Dominic
Dominic

Reputation: 510

Laravel: OrderBy nested object in collection

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

Answers (2)

Dominic
Dominic

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

Brighton Balfrey
Brighton Balfrey

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

Related Questions