Laravel Eloquent - find order - php

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

Related

Laravel Eloquent Collection returned as object

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]

Laravel whereIn issue

Good day,
I wanted to do something like this:
$ids = [1, 2, 3];
$posts = $user->posts()->whereIn('id', $ids)->get();
but I get an Internal Server Error. Is there a different way to do this?
For the sake of this example, assume ID is not the primary key and that multiple posts can have the same ID. So this:
$ids = [1, 2, 3];
$posts = Post::whereIn('id', $ids)->get();
wouldn't return the desired results.
The reason you are having the error is mysql is unable to what table you are referring with id column. Use tableName in whereIn() clouse
$posts = $user->posts()->whereIn('posts.id', $ids)->get();
N.B: I assume your Post table name is posts
please use like
$items = DB::table('items')->whereIn('id', [1, 2, 3])->get();
link : Laravel ->where('id', ARRAY). multiple where conditions laravel 4
And
User::select('id','name','email','phone','created_at')->whereIN('id',[1,2,3,4,5,6,7,8,9,9,10,11])->where('is_guest',NULL)->where('user_type','1')->orderBy('id','desc')->take(20)->get();
also work with laravel 5.4

"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();

Sort collection by custom order in Eloquent [duplicate]

This question already has answers here:
Sorting Laravel Collection via Array of ID's
(3 answers)
Closed last year.
I have an array of ID's as follows:
$ids = [5,6,0,1]
Using Eloquent I am able to search for these Id's using the ->whereIn('id', $ids) function. This as expected will return the results in the ascending order by Id, is there a way I can return the results on the order the array is in? alternatively whats the easiest way to convert the collection in the order of the $ids array?
If there's a specific order you'd like the records in, you'd have to use the Collection Methods:
To get your ID's in the very specific order you've specified, you can make use of the sortBy method as follows, where collection is your collection of models:
$ids = [ 5, 6, 0, 1];
$sorted = $collection->sortBy(function($model) use ($ids) {
return array_search($model->getKey(), $ids);
});
// [ 5, 6, 0, 1] // (desired order)
To randomize your collection you can make use of the shuffle method.
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] // (generated randomly)
See the Laravel Docs on shuffle and/or sortBy for more specific requirements.
If you don't really have a specific order in mind, you can use ->inRandomOrder() in version 5.2 and up, older versions would require the raw query using ->orderBy(DB::raw('RAND()')).
See answer to MySQL order by field in Eloquent. It is possible to order the data in your SQL query. Other answers here are suggesting you sort the data after you've already fetched it in "wrong" order.
Your code should look like this:
$ids = [5,6,0,1];
$collection = YourModel::whereIn('id', $ids)
->orderByRaw('FIELD (id, ' . implode(', ', $ids) . ') ASC')
->get();
You can pass a function into the sortBy method to perform complex sorting:
$ids = [5,6,0,1];
$collection = YourModel::whereIn('id', $ids)->sortBy(function($model) use ($ids) {
// Access your array order here and modify the sorting here
});

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