Laravel remove index element from get collection - laravel

I pull in data from the database via ->get(); and want to remove a certain element based on a condition in a foreach loop so i would need something like
foreach($datas as $data) {
$data->forget(this);
}
or i count the index or whatever, but I need to find a way to remove it because the ->forget() does only work on collection instances (not on eloquent collections as it seems) , any idea?
here is the format of my log:
[{"id":14,...},{"id":15,...}...]
so i get objects in an array.
and here is the dd();
Collection {#274 ▼
#items: array:4 [▼
0 => Data {#275 ▶}
1 => Data {#276 ▶}
2 => Data {#277 ▶}
3 => Data {#278 ▶}
]
}
edit: i know its better to select only needed elements in the first place but thats not possible or rather not wished for because I am putting the results through a long carbon related check and wish to do something depending on different scenarios.
edit 2:
I can remove with forget(1..2 and 3) but not with 0, it tells me undefined offset?

Maybe map is what your are looking for if you want to remove a specific property in the item:
$datas = $datas->map(function ($data) {
// modify $data here, unset unset($data->property);
return $data;
});
See documentation here
Or filter to remove the whole item:
$datas = $datas->filter(function ($data) {
return ($data->property == 'bar') ? true : false;
});
See documentation here

Related

How to get data using foreach eloquent

I have a problem to get data using forach eloquent in laravel 6.
To get value which I want to use in foreach
$array_suspect_idBLE = Transaction::
select('id_ble')
->where('id_user',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->pluck('id_ble');
The output
Illuminate\Support\Collection {#281
#items: array:5 [
0 => 18
1 => 6
2 => 12
3 => 16
4 => 10
]
}
and the foreach
foreach($array_suspect_idBLE as $arr){
$suspect_list = Transaction::
select('id_transaction','id_user','id_ble')
->where('id_user','<>',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->where('id_ble', $arr->array_suspect_idBLE)
->get();
}
And the error is
message: Trying to get property 'array_suspect_idBLE' of non-object
The expected result are all id_transaction, id_user, id_ble that connect to array_suspect_idBLE 18,6,12,16,10
Any help would be appreciated.
Thank you
The problem is that the pluck() method returns an array of values. You are treating it as if it returns a collection of objects.
The solution would be to change it into this:
foreach($array_suspect_idBLE as $value) {
$suspect_list = Transaction::
select('id_transaction','id_user','id_ble')
->where('id_user','<>',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->where('id_ble', $value)
->get();
}

Cannot using where in eloquent

I'm using Eloquent ORM in Laravel. There is 2 model, User and Trans. User hasMany Trans, and Trans belongsTo User. The problem is when I'm using query where, it doesn't work.
I tried using ->get() in the last code, it still doesn't work. I tried using ->all() in the last code it still doesn't work. I tried whereIn, it still doesn't work.
User Model
public function trans()
{
return $this->hasMany('App\Trans', 'user_id');
}
Trans Model
public function user ()
{
return $this->belongsTo('App\User','user_id');
}
Controller
$trans = Auth::user()->trans->where('date', $date);
I want the output is based on query where the date is based on user input, when I delete ->where , it works and the output like this.
Collection {#797 ▼
#items: array:13 [▼
0 => Trans {#783 ▶}
1 => Trans {#784 ▶}
2 => Trans {#785 ▶}
3 => Trans {#786 ▶}
]
}
try to change like that
Auth::user()->trans->where('date', $date);
to
Auth::user()->trans()->where('date', $date)->get();
note : if you want to get only property then u get property without
pointer but if you want to used another method then must used(add)
pointer(->).

Laravel: Check if Models have same relation

I have models: Partido and Coalicion related in a many to many relationship.
I need to know when two or more Coalicion has the same Partido related.
Hope I have explained myself.
Edit 1:
Model:
class Coalicion extends Model
{
public function partidos()
{
return $this->belongsToMany(Partido::class);
}
}
Let's say users selected some elements from a select input and I grabbed them in an array and send them to the controller.
...
public function example(Request $request)
{
$coaliciones = $request->coaliciones;
foreach ($coaliciones as $c) {
$coalicion = Coalicion::find($c);
# Here we have a list of Coalicion model in a loop
# Let's say the first iteration I can see the relationship
dump($c->partidos);
}
}
This for example give me the following answer at the browser:
Collection {#1 ▼
#items: array:2 [▼
0 => Partido {#271 ▶} #This is Partido with id 1
1 => Partido {#268 ▶}
]
}
Collection {#2 ▼
#items: array:3 [▼
0 => Partido {#279 ▶}
1 => Partido {#280 ▶}
2 => Partido {#283 ▶} #This is Partido with id 1
]
}
I need to know when the item 0 of the first Collection and the item 2 of the second Collection are the same.
I kinda found a way but I don't know if it's the correct or best approach.
In Coalicion model I add the following function:
public function partidosId()
{
return $this->partidos->pluck('id');
}
With this I can get only the id's from the relations, then in the controller I created an empty array() and fill it with all my ids with a foreach loop, then, finishing up I evaluated if the id's in the now filled array are unique, if the unique values are less than the length of the array then some models have the same relation (I don't know which but It's a start), e.g.:
public function example(Request $request)
{
$coaliciones = $request->coaliciones;
$allItems = [];
foreach ($coaliciones as $c) {
$coalicion = Coalicion::find($c);
$allItems = array_merge($allItems, $coalicion->partidosId()->toArray());
}
if (count(array_unique($allItems))<count($allItems)) {
dd("Duplicates");
}else{
dd("Uniques");
}
}
If anyone find a better way or a way to know which are the ones with the duplicate relation please let me know

Laravel 5: Build dynamic query for Eloquent Model and pass to view

I have just started to learn Laravel 5, so I hope my question is not too stupid. I am trying to achieve the following. I have 3 tables
adverts
categories
advert_category
In my categories table I have main and subcategories. So parent categories have got parent_id NULL otherwise they show the id of the parent. When I save a new advert, I have the advert_id and the category_id saved in the pivot table advert_category. All that works fine. I am now trying the following. I want a Navigation with Maincategories and Subcategories shown. When I click on a Subcategory then I can read out easily the advert_id's from the advert_category table, because I am only looking for only 1 category_id, but I now plan to be able to click on the Maincategory and now show all the Adverts which belong to all the Subcategories from this Maincategory. So my approach is the following:
// Look up if passed id is found under parent_id column
$cat = Category::where('parent_id', $id)->get();
// The choosen category is a maincategory,
// therefore build dynamic where to look for all the id's
if (count($cat) > 0)
{
$query = Category::select();
foreach($cat as $value)
{
$query->orWhere('id', '=', $value->id);
}
$advertList = $query->get();
}
else{
$advertList = Category::findOrFail($id);
}
return view ('publicpage.adverts.showall',['advertList' => $advertList->adverts]);
Unfortunately, when I go on the Maincategory, I get below error. When I go on the Subcategory, I get the adverts shown.
Undefined property: Illuminate\Database\Eloquent\Collection::$adverts
A dd($advertlist) brings the following result:
Clicked on Maincategory:
Collection {#203 ▼
#items: array:2 [▼
0 => Category {#204 ▶}
1 => Category {#205 ▶}
] }
So it shows Collection.
Clicked on Subcategory
Category {#201 ▼
#table: "Categories"
#connection: null
I can see that there is obviously a difference, but I have got no idea, how to fix that or what the best approach would be. I hope I explained it well enough to understand my task and look forward to any advice. Thanks in advance !
UPDATE
After the below comment, I tried it out:
// Look up if passed id is found under parent_id column
$cat = Category::where('parent_id', $id)->get();
if (count($cat) > 0)
{
$query = Category::select();
foreach($cat as $value)
{
$query->orWhere('id', '=', $value->id);
}
$advertList = $query->get();
return view ('frontend.adverts.showall',['advertList' => $advertList[0]->adverts]);
}
else{
// 1 Category,
$advertList = Category::findOrFail($id);
return view ('frontend.adverts.showall',['advertList' => $advertList->adverts]);
}
This way I get the adverts for the first category, but how would I manage to hand over the adverts for all the categories or how can I handle this? I just don't seem to to be able to fix this problem. Or would the change be in the view? I tried it with another foreach in the view aswell to run through the adervertList, but again no success. Any advice? Thank you very much in advance!
tl;dr
The problem is here, that you are using $advertList->adverts and $advertList might be in some cases collection (you can think it as it was some kind of array).
So you cannot simply write $array->adverts but you should do something like this $array[0]->adverts in case you want to get adverts for 1st element only.

Laravel Paginator always returning full list on every page

I couldn't use the paginate()-method anymore cause I needed to add an extra attribute to every element in my collection.
The result is that I get the right pagination when rendering but it's always showing all elements on every page.
public function allPaginate($perPage)
{
$initialCollection = $this->model->orderBy('created_at', 'desc')->get();
// adding slug to my collection for every item
$initialCollection->each(function ($item) {
if(! isset($item->slug))
{
$slug = Str::slug($item->title);
$item->slug = $slug;
}
});
$result = new Paginator($initialCollection, count($initialCollection), $perPage);
$result->setPath(Request::url());
return $result;
}
Before i just used this:
$paginator = $this->model->orderBy('created_at', 'desc')->paginate($perPage);
I have 3 elements in my database and I want to show 2 per page. Here are the dumps of the two versions.
As it should be (with the ->paginate()) with 2 items in the collection
LengthAwarePaginator {#362 ▼
#total: 3
#lastPage: 2
#items: Collection {#364 ▼
#items: array:2 [▼
0 => News {#365 ▶}
1 => News {#366 ▶}
]
}
#perPage: 2
#currentPage: 1
#path: "http://jv.app/nl/nieuws/"
#query: []
#fragment: null
#pageName: "page"
}
As it is now (with new Paginator::make()) with 3 items in the collection
LengthAwarePaginator {#358 ▼
#total: 3
#lastPage: 2
#items: Collection {#368 ▼
#items: array:3 [▼
0 => News {#369 ▶}
1 => News {#370 ▶}
2 => News {#371 ▶}
]
}
#perPage: 2
#currentPage: 1
#path: "http://jv.app/nl/nieuws"
#query: []
#fragment: null
#pageName: "page"
}
What is the issue here?
Laravels Paginator class expects to be passed the records for the current page.
Firstly you will need to get the value for the current page. Then you will need to alter your query to only get the records for the current page:
// Get current page number
$page = 'Get this from the query string';
// Calculate the offset for current page
$offset = $perPage * ($page - 1);
// Get the records for the current page
$initialCollection = $this->model->orderBy('created_at', 'desc')->
skip($offset)->
take($perPage)->
get();
// Get total number of records in table
$totalRecords = $this->model->count();
// Paginate
$result = new Paginator($initialCollection, $totalRecords, $perPage);

Resources