Laravel Eloquent Collection returned as object - php

Why is my laravel eloquent query returning me an object? Shouldnt the returned data be in the form of an eloquent collection? Which should allow me to use the splice method.
Can someone please explain to me why the data in $location tier 1 is being seen as an object? if anything shouldnt it be an array containing objects? [ object, object] and i am trying to insert an object into this array by index
The data contained within $location tier 1 is
[{"id":1,"name":"school","lat":0,"lng":0,"enable_audit":0,"x_axis":0,"y_axis":0,"z_axis":0,"service_provider_id":0,"client_id":313,"description":"school","order":1,"created_at":"-0001-11-30 00:00:00","updated_at":"-0001-11-30 00:00:00","location_id":1,"parent_id":0},{"id":4,"name":"school","lat":0,"lng":0,"enable_audit":0,"x_axis":0,"y_axis":0,"z_axis":0,"service_provider_id":0,"client_id":313,"description":"school","order":2,"created_at":"-0001-11-30 00:00:00","updated_at":"-0001-11-30 00:00:00","location_id":1,"parent_id":0}]
$location_tier_1 = LocationTier1::where('location_id','=',$location_id)->orderby('id')->get();
array_splice($location_tier_1,$i+1,0,$value);

You can use Laravel collection methods
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2);
// [3, 4, 5]
$collection->all();
// [1, 2]

Related

Laravel unique method, log for every collection match found

I'm filtering out non-unique arrays from my collection based only on a combination of if the "first_name" and "last_name" matches any others, but I want to drop a console.log for every match found. I've thought about using a foreach in a foreach to check element against one another, but that method seems far from elegant.
Is it possible to do this while using the Laravel Unique() method without using nested forEach's?
Example of what I'm currently doing:
$collection->unique(function ($item) {
return $item['first_name'].$item['last_name'];
})->each(function ($item, $key) use ($id) {
// Do stuff..
});
First store duplicates:
$collection = collect([1, 2, 3, 3, 4, 4, 4, 5]);
$duplicates = $collection->duplicates();
Then make your collection unique and store:
$collection = $collection->unique();
Output:
References:
https://laravel.com/docs/9.x/collections#method-duplicates
https://laravel.com/docs/9.x/collections#method-unique

Return new collection without modifying original collection

I have a Laravel collection and I want to modify one of its property value to negative integer. For this I am using the collection map method but it also modifying the original collection.
My code:
$modified_revenue_data = $revenue_data->map(function ($item) {
if ($item->is_claw_back == 1 && $item->claw_back_date != null) {
return $item->revenue = $item->revenue * -1;
}
return $item;
});
I want to store the new collection into $modified_revenue_data but $revenue_data is also modified.
What would be the correct way of doing it without modifying the original collection?
It doesn't update the original collection:
$original = collect([1, 2, 3, 4, 5]);
$modified = $original->map(function ($el) {
return $el * 2;
});
dd($modified);
=> Illuminate\Support\Collection {#3726
all: [
2,
4,
6,
8,
10,
],
}
dd($original);
=> Illuminate\Support\Collection {#3743
all: [
1,
2,
3,
4,
5,
],
}
This behaviour is also stated in the documentation:
map()
...
Like most other collection methods, map returns a new collection
instance; it does not modify the collection it is called on. If
you want to transform the original collection, use the transform()
method.

"Skip" method in a Laravel Collection

In the Query Builder (\Illuminate\Database\Query\Builder), it is possible to use both the skip($n) and take($n) methods.
In a Collection (\Illuminate\Support\Collection), it's possible to use the take($n) function, but there is no skip($n) function.
Why is that and is there an alternative?
The skip($n) method is indeed not included in the Collection class, but there is a function that does the same: slice($n).
QueryBuilder (taken from the documentation):
$users = DB::table('users')->skip(10)->take(5)->get();
Alternatively, you may use the limit and offset methods:
$users = DB::table('users')
->offset(10)
->limit(5)
->get();
Collection:
collect([1, 2, 3, 4])->slice(2)->all(); //[3, 4]
Many of the methods in the QueryBuilder class are not available in the Collection class, and vice-versa. But both of them have similar functions, like QueryBuilder's where function, you'd use Collection's filter function to achieve similar results.
The forPage method returns a new collection containing the items that would be present on a given page number. The method accepts the page number as its first argument and the number of items to show per page as its second argument:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();

Laravel Eloquent - find order

I am getting 3 records from my database
return \App\Work::find([12, 2, 3]);
The annoying thing is they are reordered by when I pass them the to the view.
Is there a way to retain the order they are 'found'?
MySQL allows you to specify an order for a given field using this syntax:
SELECT * FROM work ORDER BY FIELD(id, 12, 2, 3);
Combine that with Eloquent's orderByRaw() method (https://laravel.com/api/5.5/Illuminate/Database/Query/Builder.html#method_orderByRaw) and you should be able to do something like this:
return \App\Work::whereIn('id', [12, 2, 3])->orderByRaw('FIELD (id, 12, 2, 3)')->get();
The find() method won't work with this because it returns the object immediately, so we need to use a WHERE IN clause for the ID instead. Obviously it will need a bit of refactoring as currently the ID's are duplicated, but this should achieve what you want.
Try sortBy like this
return \App\Work::find([12, 2, 3])->sortBy(function($el){
return array_search($el->getKey(), [12, 2, 3]);
}
About getKey

User Laravel model to query using an array

I've got a Laravel model, but i'd like to search the table according to an array passed in.
i.e. "Return all rows whose id matches one of the array's contents"
I can see with Laravel's query builder i can search via an input array:
$users = DB::table('teams')->whereIn('id', array(1, 2, 3))->get();
But can't seem to find anywhere how to do the same using a model.
Any ideas? Cheers!
Replace DB::table('teams')-> with a static call to the model.
$users = <model name>::whereIn('id', array(1, 2, 3))->get();
You can try this.
<?php
use App\Models\Team;
$users = Team::whereIn('id', array(1, 2, 3))->get();

Categories