我有一个可靠的User hasOne Position
,我正在获取用户,但我想先按Position->name
排序,然后按User->name
排序。我尝试了以下
<?php
$sorted = Position::where('groupId', $this->groupId)
->whereIn('id', $positions)
->with(['user' => function($query) {
$query->orderBy('user.name'); // internal sort
}])
->orderBy('position.name') // external sort
->get();
这样,结果只按外部排序,或者按位置->名称进行排序。具有相同位置->名称的不同用户未排序列出。如果我删除外部排序,只保留sortBy User->name,它会起作用,但只适用于名称,而位置是随机的。
我尝试了不同的方法
- 在
Position->user
关系中设置顺序不起作用 - 在
User->position
关系中设置顺序不起作用 - 只定义一个外部
orderBy('position.name, user.name')
,崩溃,表示用户表不在查询中
我也试着回答类似的问题,比如
关于关系的Laravel orderBy但他们似乎并没有试图根据父项和关系对结果进行排序。我唯一的解决方案似乎是在PHP中遍历结果并对其进行排序,而不是从DB中进行排序,但这听起来很愚蠢。
请给我建议,谢谢。
如果要根据关系User
对父Position
进行排序,则需要使用join()
:
$sorted = Position::where(...)
->whereIn(...)
->with('user')
->join('users', 'users.id', '=', 'positions.user_id') // Or whatever the join logic is
->orderBy('users.name')
->orderBy('positions.name')
->get();
注意:with()
中user
关系上的orderBy()
似乎没有必要,因为按照惯例,一个单独命名的关系应该只返回1个记录,对单个记录进行排序是没有意义的。
这将返回一个Position
型号的Collection
,以及一个附加的User
型号,按用户名排序,然后按职位名称排序。您可能需要添加一个select('positions.*')
来避免任何歧义问题,但这应该会让您有大致的想法。