[英]Laravel: Limit Nested Relationships
下面是我必須使用相關的threads
和posts
獲取所有Discussions
的代碼。 我試圖將帖子的數量限制為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。
您需要進行一些“調整”,因為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();
急切的結果不容易受到限制,但根據: 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;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.