Bill Garrison
Bill Garrison

Reputation: 2237

Laravel 5.2 - filtering on a custom attribute and then paginating

So I know how to paginate using paginate() and I know how to filter based on an Accessor (a where() on the collection). However, paginate takes in a query builder and where() on a collection returns a collection.

So if I want to get a bunch of items / filter by a custom attribute and then paginate the result set....how do i do that??

Accessor:

public function getRequiredToReportAttribute()
{
  // return boolean based off of complicated business logic
}

index method:

public function index()
{
    //what im doing (redacted)
    $employers = (new App\Employers')->paginate($this->perPage);

    // what I would like to be doing
    $employers = (new App\Employers)->where('required_to_report', '=', true)->paginate($this->perPage);


    return $this->sendResponse($employers);
}

Upvotes: 3

Views: 3650

Answers (2)

mfink
mfink

Reputation: 1380

Based off of Jose Rojas answer and this post I built a LengthAwarePaginator for a collection filtering on an attribute accessor. Here's an example of how to do it:

$collection = Model::all();

//Filter your collection
$filteredItems = $collection->filter(function($col) {
    return $col->require_to_report === true;
});

// Setup necessary information for LengthAwarePaginator
$currentPage = LengthAwarePaginator::resolveCurrentPage();
$pageLimit = 20;

// slice the current page items       
$currentItems = $filteredItems->slice(pageLimit * ($currentPage - 1), pageLimit)->values();

// you may not need the $path here but might be helpful..
$path = "/api/v1/employers";

// Build the new paginator
$paginator = new LengthAwarePaginator($currentItems, count($filteredItems), $pageLimit, $currentPage, ['path' => $path]);

return $paginator;

Upvotes: 1

Jose Rojas
Jose Rojas

Reputation: 3520

In the case that you want to work with accesors, you could by iterating the collection after you get your query, something like this:

 $result = Model::get()->filter(function($item) {
    return $item->require_to_report === true;
 });

Here you have all records of your model and then you could create a manual paginator:

 $paginator = new Illuminate\Pagination\Paginator($result, 10);

you have with this approach a weakness when you have too many records, the performance could be affected.

Upvotes: 4

Related Questions