Pedro
Pedro

Reputation: 1178

Laravel order data by relation property

I have two related models 'Yards' & 'Inspections'. A yard can have multiple inspections.

I want to be able to order the Yard list based on the inspection property 'reinspect_at'. I have a Model method that returns the Latest Inspection for the yard based on the inspection date.

I have tried the following:

$yards = Yard::orderBy('quarantined', 'DESC')
        ->with(['latestInspection' => function($query){
            $query->orderBy('reinspect_at', 'asc');
        }])
        ->get();

But this doesn't order the yard based on the reinspect_at date, it is only ordering the latest inspection for each yard.

I want to be able to always return the latest inspection for the yard, but need to be able to reorder the yard list based on the reinspect_at date for the latest inspection for each yard. Cheers

Screenshot of yard list display below. As you can see the Inspection due date is how I want to be able to order the result.

enter image description here

** Update ** Looks like what I want is possible in the frontend template using:

@foreach( $yards->sortBy('latestInspection.reinspect_at') as $yard )

It would be preferable to do be able to do this from the controller though, so I can have other options for ordering by.

Upvotes: 3

Views: 1335

Answers (3)

Pedro
Pedro

Reputation: 1178

Looks like I can do the following:

$yards = Yard::orderBy('quarantined', 'DESC')
        ->orderBy('archived', 'ASC')
        ->orderBy('name', 'ASC')
        ->get();
$yards = $yards->sortByDesc('latestInspection.reinspect_at');

Upvotes: 1

user1669496
user1669496

Reputation: 33118

You could use some of the methods of the returned collection. Generally you want to handle this all on the database end but I think this way is worth it because it greatly simplifies the process.

$yards = Yard::with(['inspections'])->get()->sortBy(function($yard) {
    return $yard->inspections->max('reinspect_at');
});

I removed your ordering by quarantine. Not sure how you want to handle that if you are also sorting by the reinspect_date.

Upvotes: 0

Illia Yaremchuk
Illia Yaremchuk

Reputation: 2025

For example:

function latestInspection() {
   return $this->hasOne('App\Yard')->orderBy('reinspect_at', 'asc');
}

And

$yards = Yard::with('latestInspection')->orderBy('quarantined', 'DESC')->get();

Upvotes: 0

Related Questions