如何按 Laravel 中的预加载结果排序?

How to sort by eager loading results in Laravel?

我对预加载非常陌生,运行 遇到了我认为是我只是不理解的简单问题。我查看了一些 the materials here 并环顾四周,但似乎无法找到我所问内容的正确术语。

目前我的装备模型有如下关系:

public function registrationsExpireLatest()
{
       return $this->hasOne(EquipmentLicense::class,'equipmentID','id')
    ->orderByDesc('expirationDate');
}

这非常有效,但是假设我想将它放在 @foreach 下的索引 blade 上,我得到了我需要的一切,包括使用以下代码的到期日期:

        @foreach ($equipments as $equipment)

             <tr>
                 <td><a href="/origins/{{$equipment['id']}}">{{$equipment['unit_id']}}</a></td>
                 <td>{{\Crypt::decryptString($equipment->licensePlate)}}</td>
                 <td>@if (count($equipment->registrationsExpireLatest))
                     {{$equipment->registrationsExpireLatest->expirationDate}}
                    @endif</td>
            </tr>

        @endforeach

来自这个控制器代码:

    $equipments = Equipment::with(['registrationsExpireLatest' => function ($query) {
                                    $query->orderBy('expirationDate', 'asc');
                                }])
                                ->where([
                                    ['unit_type','<',3],
                                    ['active','=',1]
                                    ])
                                ->limit(10)
                                ->get();

所有输出都是这样的:

11      086-YRR     2015-05-31
26      062-XWE     2018-11-30
33      880-HNV     2018-04-30
39      820-YYT     2018-01-31
203     279-WWU     2013-12-31
31      BMR 199     2018-04-30
UNK3    997-WLH     2011-09-30
1       957-VDN     2018-05-31
1096    187-MFF     2015-01-31
2105    154-CLU     2018-01-31 

正如您在我的控制器上看到的那样,我已经尝试按照我认为正确的方式进行排序:https://laravel.com/docs/5.3/eloquent-relationships#constraining-eager-loads

但是正如您从我的结果中看到的那样table,它们根据到期日期是乱序的。

我希望它按日期提前(如 2011 年)和晚些(如 2018 年)。有办法吗?

您当前正在对相关集合进行排序,即如果 registrationsExpireLatest 是一个 one-to-many 关系,则相关模型将按其 expirationDate 升序排序你们每个 Equipments。据我从你的模型可以看出,你已经加入了最新的实体。

要对关系上的 Equipments 进行排序通常并不难,您只需加入相关的 table。但是在您的情况下,如果每个 Equipment 的相关 table 中有多个元素,连接会稍微复杂一些。我认为类似以下的方法可行:

Equipment::where([
        ['unit_type','<',3],
        ['active','=',1]
    ])
    ->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) AS tmp'), 'equipment.id', '=', 'tmp.equipmentID')
    ->orderBy('tmp.latest')
    ->select('equipment.*', 'tmp.latest')
    ->limit(10)
    ->get();

(基于

JOIN 需要一个别名:

Equipment::where([
        ['unit_type','<',3],
        ['active','=',1]
    ])
    ->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) as license'), 'equipment.id', '=', 'license.equipmentID')
    ->orderBy('license.latest')
    ->limit(10)
    ->get();