Laravel查询:按嵌套关联Position的order字段排序Users并返回Unit
解决Laravel中按关联模型字段排序关联数据的问题
你当前的代码只是对每个用户关联的Position模型本身进行了排序,但并没有实现用户按所属职位的order字段排序的核心需求——因为你只是调整了每个user下position的顺序,而user集合本身的排序逻辑根本没碰。
方案一:关联查询时通过Join直接排序
通过在用户的查询中关联职位表,直接按职位的order字段排序用户列表:
return Unit::query() ->ordered() ->with(['users' => function($query) { // 关联职位表,按职位的order字段排序用户 $query->join('positions', 'users.position_id', '=', 'positions.id') ->orderBy('positions.order') ->select('users.*'); // 必须指定选择用户表字段,避免与职位表字段冲突 }]) ->get();
方案二:集合层面排序(适合数据量不大的场景)
先预加载所有关联数据,再在Eloquent集合层面完成排序:
// 先加载所有单元、用户及对应的职位 $units = Unit::query() ->ordered() ->with('users.position') ->get(); // 遍历每个单元,对用户按职位的order字段排序 $units->each(function ($unit) { $unit->users = $unit->users->sortBy(function ($user) { // 处理没有关联职位的用户,默认放到最后 return $user->position?->order ?? PHP_INT_MAX; }); }); return $units;
方案三:在关联定义中固化排序逻辑
如果需要每次调用users关联都自动按职位排序,可以直接在Unit模型的关联方法中定义排序:
在Unit模型里修改users关联:
public function users() { return $this->hasMany(User::class) ->join('positions', 'users.position_id', '=', 'positions.id') ->orderBy('positions.order') ->select('users.*'); }
之后调用时只需正常预加载即可:
return Unit::query()->ordered()->with('users.position')->get();
内容的提问来源于stack exchange,提问作者Jon Erickson
相关产品推荐
相关产品推荐

