You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel关联模型排序问题:如何按Type名称排序Date记录?

按Type名称排序Date记录的Eloquent实现方案

我来帮你搞定这个问题!因为Date和Type之间是通过Tour间接关联的(Date → Tour ↔ Type),咱们需要通过关联查询来实现按Type名称排序Date记录,这里有两种实用的方案:

方案一:使用JOIN语句直接关联排序

这种方式性能较好,适合数据量较大的场景,直接通过SQL JOIN关联中间表和Type表,然后排序:

$dates = Date::select('dates.*')
    ->join('tours', 'dates.tour_id', '=', 'tours.id')
    ->join('tour_type', 'tours.id', '=', 'tour_type.tour_id')
    ->join('types', 'tour_type.type_id', '=', 'types.id')
    ->orderBy('types.name', 'asc') // 这里按Type名称升序,改成desc就是降序
    ->get();

注意:如果你的多对多中间表不是默认的tour_type(比如自定义了表名),记得替换成实际的表名;另外如果存在一个Tour对应多个Type的情况,这条查询可能会返回重复的Date记录,你可以加上->distinct()去重:

$dates = Date::select('dates.*')
    ->join('tours', 'dates.tour_id', '=', 'tours.id')
    ->join('tour_type', 'tours.id', '=', 'tour_type.tour_id')
    ->join('types', 'tour_type.type_id', '=', 'types.id')
    ->orderBy('types.name', 'asc')
    ->distinct()
    ->get();

方案二:使用Eloquent关联加载+排序

如果你更倾向于用Eloquent的关联语法,也可以通过预加载关联,然后利用集合的排序方法,不过这种方式是在内存中排序,适合数据量较小的场景:

$dates = Date::with(['Tour.Types' => function ($query) {
    $query->orderBy('name', 'asc');
}])->get()->sortBy(function ($date) {
    // 这里取第一个Type的名称来排序,如果Tour有多个Type,你可以根据需求调整,比如取第一个或者拼接所有名称
    return $date->Tour->Types->first()->name ?? '';
});

提示:如果你的Tour可能没有关联的Type,记得加上?? ''避免报错,或者在查询时过滤掉没有Type的Tour:

$dates = Date::whereHas('Tour.Types')
    ->with(['Tour.Types' => function ($query) {
        $query->orderBy('name', 'asc');
    }])->get()->sortBy(function ($date) {
        return $date->Tour->Types->first()->name;
    });

额外优化:添加全局作用域(可选)

如果你的项目中经常需要按Type名称排序Date记录,可以给Date模型添加一个全局作用域,这样每次查询Date时都会自动按Type名称排序:

在Date模型中添加:

protected static function booted()
{
    static::addGlobalScope('sortByTypeName', function ($query) {
        $query->select('dates.*')
            ->join('tours', 'dates.tour_id', '=', 'tours.id')
            ->join('tour_type', 'tours.id', '=', 'tour_type.tour_id')
            ->join('types', 'tour_type.type_id', '=', 'types.id')
            ->orderBy('types.name', 'asc')
            ->distinct();
    });
}

这样之后,直接Date::get()就会自动按Type名称排序了。

内容的提问来源于stack exchange,提问作者FarbodKain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:43:39