[英]In Laravel, how to combine where() and orderBy() when orderBy() is working on relationship?
我有两个模型,一个Track
模型和一个Artist
模型,其中每个Track
模型belongsTo()
一个Artist
模型。 Track
模型有一个number
列,而Artist
模型有一个name
列。 我想检索number = 1
所有Tracks
,然后显示按其艺术家姓名排序的Tracks
。 到目前为止,我只想出了如何做一个或另一个,而不是两个都做。
我希望能够通过以下方式做到这一点:
Track::with(['artist' => function($q) {
$q->orderBy('name');
}])->where('number', 1)->get();
这将显示number = 1
所有轨道,但不会以任何特定顺序对tracks
进行排序。 如果完全删除with()
我将得到相同的结果。 相反,如果删除where()
子句,则会在数据库中获得所有轨道,并按艺术家的名称对其进行排序。 如何结合这两个功能? 结果应如下所示:
[
{
"id": 17,
"created_at": "2019-09-04 22:33:50",
"updated_at": "2019-09-04 22:33:50",
"number": 1,
"title": "Iste omnis maxime inventore rerum nam et.",
"artist_id": 2,
"album_id": 4,
"length": "06:08",
"disc_number": 1,
"artist": {
"id": 2,
"created_at": "2019-09-04 22:33:46",
"updated_at": "2019-09-04 22:33:49",
"name": "Ace",
"image_id": "4"
}
},
{
"id": 35,
"created_at": "2019-09-04 22:33:54",
"updated_at": "2019-09-04 22:33:54",
"number": 1,
"title": "Doloremque quidem voluptatibus doloribus et.",
"artist_id": 4,
"album_id": 7,
"length": "18:13",
"disc_number": 3,
"artist": {
"id": 4,
"created_at": "2019-09-04 22:33:46",
"updated_at": "2019-09-04 22:33:53",
"name": "Bar",
"image_id": "10"
}
},
{
"id": 54,
"created_at": "2019-09-04 23:00:08",
"updated_at": "2019-09-04 23:00:08",
"number": 1,
"title": "Ut placeat assumenda aut.",
"artist_id": 21,
"album_id": 17,
"length": "09:25",
"disc_number": 4,
"artist": {
"id": 21,
"created_at": "2019-09-04 23:00:08",
"updated_at": "2019-09-04 23:00:08",
"name": "Cat",
"image_id": "22"
}
},
{
"id": 71,
"created_at": "2019-09-04 23:00:11",
"updated_at": "2019-09-04 23:00:11",
"number": 1,
"title": "Omnis et dolores odio a eius.",
"artist_id": 22,
"album_id": 20,
"length": "16:48",
"disc_number": 2,
"artist": {
"id": 22,
"created_at": "2019-09-04 23:00:08",
"updated_at": "2019-09-04 23:00:10",
"name": "Dog",
"image_id": "25"
}
},
]
使用这样的东西:
Track::with('artist')->join('artist', 'artist.id', '=', 'track.artist_id')->orderBy('artist.name', 'DESC')->get()
希望你明白我的意思
您无法使用代码按艺术家的名字进行排序,因为laravel为eager load
带有曲目的艺术家,执行两个查询,您应该使用join
进行一个查询,但是我给出了另外两个选项( 我不喜欢join ):
1)您可以在结果集合上使用sortBy()
或sortByDesc()
(如果要对降序进行排序),例如:
$tracks = Track::with('artist')->where('number', 1)->get()->sortBy('artist.name');
2)您可以从Artist开始查询,但是您必须稍微更改一下视图,例如:
$artists = Artist::with(['tracks' => function($q) {
$q->where('number', 1);
}])->orderBy('name')->get();
3)您可以使用联接,请查看另一个答案。
仅供参考,如果您想调试查询,只需在->get()
位置附加->toSql()
->get()
即可获取SQL
字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.