filtering a paginated eloquent collection

Expanding on mininoz's answer with your specific case:

//Start with creating your object, which will be used to query the database

$queryUser = User::query();

//Add sorting

$queryUser->orderBy('first_name','asc');

//Add Conditions

if(!is_null($filters['type'])) {
    $queryUser->where('type','=',$filters['type']);
}

if(!is_null($filters['state_id'])) {
    $queryUser->whereHas('profile',function($q) use ($filters){
        return $q->where('state_id','=',$filters['state_id']);
    });
}

if(!is_null($filters['city_id'])) {
    $queryUser->whereHas('profile',function($q) use ($filters){
        return $q->where('city_id','=',$filters['city_id']);
    });
}

//Fetch list of results

$result = $queryUser->paginate(20);

By applying the proper conditions to your SQL query, you are limiting the amount of information that comes back to your PHP script, and hence speeding up the process.

Source: http://laravel.com/docs/4.2/eloquent#querying-relations


None of the answers provide an answer to the actual question, which is possible in Laravel 5.2+:

How to filter the underlying collection of a Paginator without losing the Paginator object

The Paginator is built on an underlying collection, but indeed when you use any of the inherited Collection methods they return the underlying collection and not the full Paginator object: collection methods return collections for chaining together collection calls.

But you can eject, modify and inject the collection as follows:

$someFilter = 5;
$collection = $paginator->getCollection();
$filteredCollection = $collection->filter(function($model) use ($someFilter) {
  return $model->id == $someFilter;
});
$paginator->setCollection($filteredCollection);