如何按照Laravel的急切加载结果进行排序?

时间:2018-03-29 18:08:30

标签: php laravel laravel-5 eloquent laravel-eloquent

我非常擅长加载,并且遇到了我认为只是不理解它的简单问题。我查看了the materials here的一些内容并且环顾四周,但似乎无法为我所要求的内容提供正确的术语。

在我的设备型号中,我有以下关系:

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

这很有效,但是我想把它放在@foreach下的索引刀片上,我得到了我需要的一切,包括使用下面代码的截止日期:

        @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

但是从结果表中可以看出,根据到期日期,它们会出现故障。

我希望按日期提前(如2011年)到之后(如2018年)。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

您目前正在做的是对相关集合进行排序,即如果registrationsExpireLatest是一对多关系,则相关模型将按其expirationDate的升序排序。你的Equipments。据我所知,你已经加入了最新的实体。

要对关系Equipments进行排序通常不是那么难,您只需加入相关表即可。但在您的情况下,每个Equipment在相关表中有多个元素,连接会更复杂一些。我认为以下内容可能有效:

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

答案 1 :(得分:1)

(基于JSFiddle-Demo

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