Reputation: 510
My LaravelController returns me an Collection with a nested object. What I need to do is to order it by a property of the nested object. The collection looks like this:
{ID:1,
subobject:{order:555}
},
{ID:2,
subobject:{order:444}
},
I want to order the objects by subobject.order (ascending) (ordered->subobject->order)
This is what the Controller currently does:
$ordered = List::with('stuff')->whereIn('ID', $foo)
->with('extrastuff')
->get();
The result of this is fine, just not in the order I need it in.
So I tried:
$ordered = List::with('stuff')->whereIn('ID', $foo)
->with('extrastuff')
->orderBy('object.order','asc')
->get();
But that gives me an error:
"Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'subobject.order' in 'order clause' (SQL: select * from `list` where `ID` in (2373, 2374, 2376, 2378, 2379, 2372) order by `subobject`.`order` asc) "
How can I order this?
Upvotes: 1
Views: 1960
Reputation: 510
Since I couldn't get it working (no sorting/ordering but also no error messages with @Brighton Ballfrey's solution) I created a workaround by recreating the collection:
Instead of starting with
$collection = List::with('stuff') [..]
I startetd with the subobject model and got the relations with the other models from there.
$collection = SubobjectModel::with('list') [..]
Like that I have the property to order by in the top level of the collection and orderBy works like a charm.
Upvotes: 0
Reputation: 51
You can sort with a closure after you retrieve your collection. This is more customizable.
$collection = $collection->sort(function ($a, $b) {
if ($a->subobject->order == $b->subobject->order) {
return 0;
}
return ($a->subobject->order < $b->subobject->order) ? -1 : 1;
});
I believe sortBy also fits your use case and the question you are asking:
$sorted = $collection->sortBy("suboject.order");
This is a simple reference https://riptutorial.com/laravel/example/11490/sorting-a-collection
Upvotes: 2