問題描述
有關(guān)于舊的 L3 預(yù)加載分頁的問題,而不是使用 eloquent.但我想使用 eloquent 來獲得與分頁的急切加載關(guān)系.
There was question about old L3 eager loaded paginations, not using eloquent. But i want to use eloquent to get eager loaded relationship with pagination.
主模型:與帖子有一對(duì)多關(guān)系的主題,這樣一個(gè)主題就有很多帖子.我使用此功能獲取所有數(shù)據(jù):
Main model: Topic that has one to many relationship with Posts, So that one Topic has many Posts. I get all data with this function:
public function findById($id)
{
return $this->topic->with('posts', 'posts.user', 'posts.user.profile')
->find($id);
}
然后我循環(huán)顯示所有結(jié)果,但它們沒有分頁:
And later I make loop to display all results, but they are not paginated:
@foreach($topic->posts as $post)
... unpaginated content ...
@endforeach
因此,我可以采取一種解決方法并分別選擇所有具有主題 $id 的帖子并使用 ->paginate() 而不是 ->get() 并且會(huì)得到分頁 $pots,
So, i could make a workaround and select separately all posts that has $id of topic and use ->paginate() instead of ->get() and would got paginated $pots,
- 但是是否有可能使用分頁的急切加載關(guān)系帖子?怎么做?
推薦答案
澄清一些事情:對(duì)急切加載的關(guān)系進(jìn)行分頁是一種誤解.急切加載的要點(diǎn)是在盡可能少的查詢中檢索所有關(guān)系.如果要檢索 10 個(gè)主題,所有主題都有 35 個(gè)帖子,則只需要兩個(gè)查詢.甜!
To clarify something: paginating eager-loaded relationships is somewhat of a misconception. The point of eager loading is to retrieve all relationships in as few queries as you can. If you want to retrieve 10 topics, all of which have 35 posts, you will only need two queries. Sweet!
也就是說,對(duì)急切加載的關(guān)系進(jìn)行分頁是行不通的.考慮發(fā)生急切加載時(shí)的兩種情況:
That said, paginating an eager-loaded relationship is not going to work. Consider two scenarios when eager loading happens:
您想要檢索和列出主題,并且可能列出每個(gè)主題的前五個(gè)帖子.偉大的!急切加載是完美的.現(xiàn)在,您不希望在這樣的頁面上對(duì)急切加載的帖子進(jìn)行分頁,所以沒關(guān)系.
You want to retrieve and list topics, and maybe list the first five posts for each topic. Great! Eager loading is perfect. Now, you wouldn't want to paginate the eager-loaded posts on a page like this, so it doesn't matter.
您加載了一個(gè)主題,并且想要為該主題的帖子分頁.偉大的!比較容易做到.但是,如果您已經(jīng)預(yù)先加載了屬于該主題的所有 帖子,那么您可能只是檢索了許多您不需要的額外資源.因此,急切加載實(shí)際上傷害你.
You load a single topic, and you want to paginate the posts for that topic. Great! Relatively easy to do. However, if you've already eager-loaded all posts belonging to this topic, you've just potentially retrieved a lot of extra resources that you don't need. Therefore eager loading is actually hurting you.
也就是說,有兩種可能的解決方案:
That said, there are two potential solutions:
選項(xiàng) 1:創(chuàng)建一個(gè)自定義訪問器來對(duì) Eloquent 關(guān)系進(jìn)行分頁.
Option 1: Create a custom accessor that paginates the Eloquent relationship.
/**
* Paginated posts accessor. Access via $topic->posts_paginated
*
* @return IlluminatePaginationPaginator
*/
public function getPostsPaginatedAttribute()
{
return $this->posts()->paginate(10);
}
優(yōu)點(diǎn):非常容易分頁;不干擾正常的帖子關(guān)系.
缺點(diǎn):急切加載帖子不會(huì)影響此訪問器;運(yùn)行它將在預(yù)先加載的查詢之上創(chuàng)建兩個(gè)額外的查詢.
Pros: Paginates very easily; does not interfere with normal posts relationship.
Cons: Eager loading posts will not affect this accessor; running it will create two additional queries on top of the eager loaded query.
選項(xiàng) 2:對(duì)急切加載關(guān)系返回的帖子集合進(jìn)行分頁.
Option 2: Paginate the posts Collection returned by the eager-loaded relationship.
/**
* Paginated posts accessor. Access via $topic->posts_paginated
*
* @return IlluminatePaginationPaginator
*/
public function getPostsPaginatedAttribute()
{
$posts = $this->posts;
// Note that you will need to slice the correct array elements yourself.
// The paginator class will not do that for you.
return Paginator::make($posts, $posts->count(), 10);
}
優(yōu)點(diǎn):使用急切加載關(guān)系;不創(chuàng)建額外的查詢.
缺點(diǎn):無論當(dāng)前頁面如何,都必須檢索所有元素(慢);必須手動(dòng)構(gòu)建當(dāng)前頁面元素.
Pros: Uses the eager-loaded relationship; creates no additional queries.
Cons: Must retrieve ALL elements regardless of current page (slow); have to build the current-page elements manually.
這篇關(guān)于Laravel 4.1:如何對(duì)雄辯的渴望關(guān)系進(jìn)行分頁?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!