在Laravel Eloquent中,内部orderBy被外部orderBy覆盖



我有一个可靠的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
  • 用Laravel/Eloquent排序相关模型
  • 但他们似乎并没有试图根据父项和关系对结果进行排序。我唯一的解决方案似乎是在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.*')来避免任何歧义问题,但这应该会让您有大致的想法。

    最新更新