3
votes

I need to paginate the results and sort them using sortBy(), without losing the pagination links. I also need to use a resource to return the results.

$sorted = Model::paginate(10)->sortBy('name');

$results = \App\Http\Resources\MyResource::collection($sorted);

Doing this breaks the pagination links (I get only the data part).

$paginated = Model::paginate(10);

$results = \App\Http\Resources\MyResource::collection($paginated);

return $results->sortBy('name');

This also doesn't work. Any ideas?

3

3 Answers

3
votes

I've solved the problem with this solution:

$sorted = Model::get()
    ->sortBy('example_function')  //appended attribute
    ->pluck('id')
    ->toArray();

$orderedIds = implode(',', $sorted);

$result = DB::table('model')
    ->orderByRaw(\DB::raw("FIELD(id, ".$orderedIds." )"))
    ->paginate(10);

I've appended example_function attribute to the model, to be used by sortBy. With this solution I was able to use orderBy to order by an appended attribute of the model. And also I was able to use pagination.

2
votes

I think you can sort the results first, and then paginate

$sorted = Model::orderBy('name')->paginate(10);
2
votes

Using the getCollection() and setCollection() method in the paginator class, You can update the pagination result without losing the meta data.

$result = Post::orderBy('another_key')->paginate();
$sortedResult = $result->getCollection()->sortBy('key_name')->values();
$result->setCollection($sortedResult);

return $result;