Framework: [Request] Paginate a laravel Collection

Created on 5 Feb 2014  路  10Comments  路  Source: laravel/framework

It would be cool, if we could paginate collections.

Why we need this: If you make up a custom collection or need sorting/filtering items, that can not simple be done directly via the database.

EG: My user has _clients_ which have _projects_ which have _times_. To get all times I have about the following code:

$clients = Auth::user()->clients();
$single_times = array();
foreach($clients as $client){
    foreach($client->projects as $project){
        foreach($project->times as $time){
            $single_times[] = $time;
        }
    }
}

$times = new Illuminate\Database\Eloquent\Collection($single_times);
$total = $times->count();
$pp = 5;
$times = Paginator::make($times->toArray(), $total, $pp);

However $times is now an array and contains all times (not only 5).

Suggestion: make a Collection paginatable like: $some_times = $times->paginate(5);

Most helpful comment

I wrote a gist for a way to do this using a Collection macro. Hope it helps in those situations when a model isn't the right solution

All 10 comments

Why don't you get just the time model with inverse relationships?

What are inverse relationships? I could not find anything about it? Do you maybe have an example?

I suppose that your client has many projects (hasMany method), so a project belongs to a client (belongsTo method). You can always retrieve all projects (or the time) with clients just calling Project::with('clients')->get(). To get the times you could call Time::with('projects.clients')->get().

Ah ok, got it. The clients are user specific, so I only want a subset of clients. (I added the line with the definition of $clients in my initial comment). So I think that would not work here.

I think this kinda defeats the purpose of pagination - to reduce the number of rows retrieved. If you're going to fetch all the rows anyway then you haven't really gained anything.

@gabrielkoerich: Well, I now got all the project_ids and paginated the Times with Times::whereIn('project_id',$project_ids)->paginate(10); Thanks for that hint.

@anlutro: Good point. I just wanted to paginate the results due their space. But what if I have to sort them before in a way, that the database does not provide? (So I can not just query a subset).

Don't think we have any plans to implement this currently. Though you could pretty easily extend Collections to do this, using the newCollection method on the model.

I wrote a gist for a way to do this using a Collection macro. Hope it helps in those situations when a model isn't the right solution

It would be easy for soring based on sorting based on external data like google map distance matrix API result

Thanks @simonhamp, your gist saved my day!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iivanov2 picture iivanov2  路  3Comments

gabriellimo picture gabriellimo  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

JamborJan picture JamborJan  路  3Comments

YannPl picture YannPl  路  3Comments