3
votes

I cant create a proper pagination system using laravel 4. I have the following models and function that return collections:

Model Restaurant:

public function fooditem()
{
    return $this->hasMany('Fooditem','rest_id');
}
public function get_rest_foods($id){
    return Restaurant::find($id)->fooditem->toArray();
}

The second function returns all food items for a certain restaurant as an array. I also use this in an API call.

in my controller i have this:

 $food = $food->get_rest_foods($id);
 $paginator = Paginator::make($food, 10, 5);

I pass the paginator to the view and it shows the links ok but also shows all my item from the food array.

I tried using

public function get_rest_foods($id){
        return Restaurant::find($id)->fooditem->paginate(5);
    }

but i get an error:

FatalErrorException: Error: Call to undefined method Illuminate\Database\Eloquent\Collection::paginate()

I searched this and many other sites but cant understant how to paginate a collection.

Thanks for your help

3

3 Answers

5
votes

The paginator must get the items that it would normally get from a database query with an offset/limit statement. So when you have a collection with all items, you should do the offset/limit yourself.

    $food = $food->get_rest_foods($id);

    $page = 1;
    if( !empty(Input::get['page']) ) {
        $page = Input::get['page'];
    }

    $perPage = 15;
    $offset = (($page - 1) * $perPage);

    $food = Paginator::make($food->slice($offset,$perPage, true)->all(), $food->count(), $perPage);
4
votes

I created a subclass of Collection and implemented my own paginate method

public function paginate($perPage) {
    $pagination = App::make('paginator');
    $count = $this->count();
    $page = $pagination->getCurrentPage($count);
    $items = $this->slice(($page - 1) * $perPage, $perPage)->all();
    $pagination = $pagination->make($items, $count, $perPage);
    return $pagination;
}
3
votes

The Laravel paginator does not do any of the splicing for you. Typically the paginator should be used hand in hand with Eloquent/Fluent. In your second example you should be doing it like this.

return Restaurant::find($id)->fooditem()->paginate(5);

Without calling the actual method you'll just be getting a collection of results and not the query builder instance.

If you want to use the paginator manually you need to pass in the spliced array (the correct items for the current page). This usually involves determining the current page, the total results and total pages. That's why, where possibly, it's best to use it with Eloquent or Fluent.