Skip to content

Instantly share code, notes, and snippets.

@DesolatorMagno
Last active June 18, 2024 18:37
Show Gist options
  • Save DesolatorMagno/1ae3f7ff992da1d4c45712ef37cdd8b7 to your computer and use it in GitHub Desktop.
Save DesolatorMagno/1ae3f7ff992da1d4c45712ef37cdd8b7 to your computer and use it in GitHub Desktop.
Laravel - Generic Sort

Taking into considetarion the value for $fields in the controller is:

$fields = ['id', 'name', 'email', 'age', 'created_at'];


localhost/api/users?limit=20&sort=-name

  • limit = 20
  • sort = name
  • order = desc

localhost/api/users?sort=age

  • limit = 15 // Default value.
  • sort = age
  • order = asc

localhost/api/users?limit=15&sort=country

  • limit = 15
  • sort = created_at // (country is not in the fields array so it will go back to the default)
  • order = desc // default order is desc.
<?php
namespace App\Http\Requests;
class GenericIndexRequest extends Request
{
public function rules(): array
{
return [
'limit' => 'bail|nullable|integer|min:5|max:100',
'sort' => 'bail|nullable|string',
];
}
//TODO: sort can be a array (string using | as separator)
public function getSort(array $fields): array
{
$sort = $this->validated()['sort'] ?? '-created_at';
$order = $sort[0] === '-' ? 'desc' : 'asc';
if ($order === 'desc') {
$sort = substr($sort, 1);
}
if (!in_array($sort, $fields)) {
$sort = '-created_at';
}
return compact('sort', 'order');
}
}
<?php
namespace App\Http\Controllers\V2\User;
use App\Http\Controllers\Controller;
use App\Http\Requests\GenericIndexRequest;
use App\Http\Models\User;
use App\Http\Models\Company;
use App\Http\Resources\UsersResource;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class UserController extends Controller
{
use AuthorizesRequests;
public function index(GenericIndexRequest $request, Company $company)
{
$this->authorize('view', [User::class, $company]);
$fields = ['id', 'name', 'email', 'age', 'created_at'];
$sort = $request->getSort($fields);
return UsersResource::collection(User::where('company_id', $company->id)
->select($fields)
->orderBy($sort['sort'], $sort['order'])
->paginate(request()->input('limit', 15)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment