Laravel Eloquent:如何排序相关模型的结果?

Posted

技术标签:

【中文标题】Laravel Eloquent:如何排序相关模型的结果?【英文标题】:Laravel Eloquent: How to order results of related models? 【发布时间】:2014-10-31 06:31:46 【问题描述】:

我有一个名为School的模型,它有很多学生

这是我模型中的代码:

public function students()

    return $this->hasMany('Student');

我正在让所有学生在我的控制器中使用此代码:

$school = School::find($schoolId);

在视图中:

@foreach ($school->students as $student)

现在我想按students 表中的某个字段对Students 进行排序。我该怎么做?

【问题讨论】:

【参考方案1】:

您有几种方法可以做到这一点:

// when eager loading
$school = School::with(['students' => function ($q) 
  $q->orderBy('whateverField', 'asc/desc');
])->find($schoolId);

// when lazy loading
$school = School::find($schoolId);
$school->load(['students' => function ($q) 
  $q->orderBy('whateverField', 'asc/desc');
]);

// or on the collection
$school = School::find($schoolId);
// asc
$school->students->sortBy('whateverProperty');
// desc
$school->students->sortByDesc('whateverProperty');


// or querying students directly
$students = Student::whereHas('school', function ($q) use ($schoolId) 
  $q->where('id', $schoolId);
)->orderBy('whateverField')->get();

【讨论】:

如何按模型的多个属性对集合进行排序?例如,我想按班级排序,然后按他们的名字排序。 $school->students->sortBy('whateverProperty')->sortBy('anotherProperty'); 不起作用。它仅按“anotherProperty”对集合进行排序。 这是一个可行的解决方案。它使用闭包。 ***.com/a/25451441/225790 是的,Mark Ba​​ker 的链接解决方案很简洁。另一种解决方案是usort @SajeebAhamed xToOne 对相关模型进行排序没有意义,那么您的问题究竟是什么? sortBy 对我来说是完美的,仍然不需要使用 join...我唯一担心的是我在 foreach 的视图中执行 sortBy【参考方案2】:

您可以将 orderBy 添加到您的关系中,因此您唯一需要更改的是

public function students()

    return $this->hasMany('Student');

public function students()

    return $this->hasMany('Student')->orderBy('id', 'desc');

【讨论】:

这是错误的。如果我想在学生中订购 2 件东西怎么办,需要改变关系。【参考方案3】:

要回答原来的问题,students 动态属性也可以作为关系方法来访问。

所以你有这个来获取所有学生:

$students = $school->students;

现在作为关系方法,这是等价的:

$students = $school->students()->get();

鉴于此,您现在可以添加一些排序:

$students = $school->students()->orderBy('students.last_name')->get();

由于 eloquent 将执行连接,因此请确保在引用要排序的列时包含表名。

如果您想设置$school->students 将始终返回的默认顺序,您也可以将其添加到您的students 方法中。查看hasMany() 的文档以了解其工作原理。

【讨论】:

【参考方案4】:

对于多对一关系,我找到了一个答案:

https://laracasts.com/discuss/channels/eloquent/order-by-on-relationship

$order = 'desc';
$users = User::join('roles', 'users.role_id', '=', 'roles.id')
  ->orderBy('roles.label', $order)
  ->select('users.*')
  ->paginate(10);

这可以节省任何人的时间......

【讨论】:

【参考方案5】:

你可以这样使用:

$students = $school->students()->orderBy('id', 'desc');

你也可以使用

$students = $school->students()->orderBy('id', 'desc')->paginate(10);

【讨论】:

以上是关于Laravel Eloquent:如何排序相关模型的结果?的主要内容,如果未能解决你的问题,请参考以下文章

列表模型如何按 DOWN-VOTES 的数量排序到相关模型 - laravel,雄辩

如何在 Laravel Eloquent 上过滤相关模型

Laravel 4:如何使用 Eloquent ORM“排序”[重复]

在 Laravel 中通过多对多关系模型对 eloquent 模型进行排序

Laravel Eloquent 模型按局部列和关系模型列值排序

Laravel Eloquent - 通过用户模型上的方法对用户关系进行排序