I am creating a stream which contains two types of objects, BluePerson and RedPerson. To create the stream, I fetch all of both objects, then merge them into one collection. After doing so, I need to paginate them, however paginate is for eloquent models and DB queries, and not collections, it seems. I have seen a lot about manually creating a paginator, but the documentation, especially in the API is sparse (I can't even seem to find the arguments the Paginator class accepts.)
How can I paginate the results of merging my collections?
public function index()
{
$bluePerson = BluePerson::all();
$redPerson = RedPerson::all();
$people = $bluePerson->merge($redPerson)->sortByDesc('created_at');
return view('stream.index')->with('people', $people);
}
Try following.
I had to deal with something like that in a project i was working on, where in one of the pages i had to display two type of publication paginated and sorted by the created_at field. In my case it was a Post model and an Event Model (hereinafter referred to as publications).
The only difference is i didn't want to get all the publications from database then merge and sort the results, as you can imagine it would rise a performance issue if we have hundreds of publications.
So i figure out that it would be more convenient to paginate each model and only then, merge and sort them.
So here is what i did (based on answers and comments posted earlier)
First of all let me show you a simplified version of "my solution", then i will try to explain the code as much as i could.
As you can guess it by now, the facade Paginator is the responsible of merging and sorting my paginators (
$events
&$posts
)To make this answer a little bit more clear and complete, i will show you how to create your own Facade.
You can choose to put your own facades anywhere you like, personally, i choose to put them inside Facades folder under the app folder, just like shown in this tree.
Put this code inside
app/Facades/Paginator.php
For more info, you can see How Facades Work
Next, bind paginator to service container, open
app\Providers\AppServiceProvider.php
For more info, you can see The Boot Method
My Paginator class is under
app/Services/Pagination/
folder. Again, you can put your classes wherever you like.Definitely there is room for improvements, so please if you see something that needs to be changed, leave a comment here or reach me on twitter.
best way for paginate collection:
1- add this to boot function in \app\Providers\AppServiceProvider
2-From hereafter for all collection you can paginate like your code
You can add the following code for Collection in the Providers/AppServiceProvider.
Then, you can call paginate from a Collection, just like an Eloquent model. For example
You are right. but there is ineed a paginator function for collections. forPage
Syntax:
Example:
Rest is simple.
If you want to use a LengthAwarePaginator simply instantiate one. As mentioned in the comments of a previous answer you will have to set the path for this. You will also need to make sure you resolve the "currentPage" and set the items to be returned before you instantiate the paginator. This can all be done before/on instantiation. So a function may look something like: