以下是我必须使用关联的Discussions
和threads
获取所有posts
的代码。我试图将帖子的数量限制为1.当我这样做时,我希望每个帖子中只有1个帖子,但是9个帖子中没有帖子,1个帖子中有1个帖子。
App\Discussion::with([
'threads' => function ($query) => {
// Correctly limits the number of threads to 10.
$query->latest()->take(10);
},
'threads.posts' => function ($query) {
// Limits all posts to 1, not each post to 1 for each thread.
$query->take(1);
}
])->where(['slug' => 'something'])->firstOrFail();
上面的代码在数据库中运行以下SQL查询。
select * from `discussions` where (`slug` = ?) and `discussions`.`deleted_at` is null limit 1
select * from `threads` where `threads`.`discussion_id` in (?) and `threads`.`deleted_at` is null order by `created_at` desc limit 10
select * from `posts` where `posts`.`thread_id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) and `posts`.`deleted_at` is null order by `created_at` desc limit 1
我可以看到第三个查询导致问题,因为它将所有帖子限制为1。
我希望看到以下内容;一个讨论,在该主题中有10个主题和1个帖子。
{
"id": 1,
"title": "Discussion Title",
...
"threads": [
{
"id": 1,
"title": "Thread Title",
...
"posts": [
{
"id": 1,
"title": "Post Title",
...
}
]
}
...
]
}
有没有办法在Laravel框架内执行此操作,还是必须运行原始查询?我宁愿尽可能坚持使用雄辩的ORM。
答案 0 :(得分:3)
你需要做一些“调整”,因为Eloquent没有查询方法来限制关系中的数字结果。
首先在Thread模型上创建此函数。
public function one_post()
{
//OrderBy is optional
return $this->hasOne(Post::class)->orderBy('id', 'asc');
}
现在你有一个只返回一个帖子的关系。您可以这样查询:
App\Discussion::with([
'threads' => function ($query) {
// Correctly limits the number of threads to 10.
$query
->latest()
->take(10)
->with('one_post');
}
])->where(['slug' => 'something'])->firstOrFail();
答案 1 :(得分:1)
急切的结果不容易受到限制,但根据:https://laracasts.com/discuss/channels/eloquent/laravel-51-eloquent-relationship-hasmany-limit-records可以使用模型关系进行映射....换句话说,您的代码可能看起来像:
App\Discussion::with([
'threads' => function ($query) => {
// Correctly limits the number of threads to 10.
$query->latest()->take(10);
}])->where(['slug' => 'something'])->firstOrFail()
->map(function ($thread) {
$thread->setRelation('posts', $thread->posts->take(1));
return $thread;
});