A simple trait to make your Laravel Eloquent models sortable with ease. Designed for API usage where you can pass sort parameters directly from query strings (e.g., /users?sort=-id).
Using Composer:
composer require firevel/sortable-
Import the
Sortabletrait in your Eloquent model. -
Add a protected
$sortablearray property to your model. This array should list the fields you want to allow for sorting.
use Firevel\Sortable\Sortable;
class User extends Model {
use Sortable;
/**
* Fields allowed for sorting.
*
* @var array
*/
protected $sortable = ['id', 'name', 'email'];
/**
* Default sorting when no sort parameter is provided (optional).
*
* @var array|null
*/
protected $defaultSort = ['-id'];
}You can now easily sort your models using the sort() query scope.
To sort by name in ascending order:
User::sort(['name'])->get();To sort by id in descending order:
User::sort(['-id'])->get();The - sign before the field name indicates descending order.
You can sort by multiple columns at once. The sorting is applied in the order specified:
User::sort(['name', '-id'])->get();This will sort by name ascending, then by id descending.
This trait is particularly useful for API endpoints where you receive sort parameters from query strings:
// Example: GET /users?sort=-id
public function index(Request $request)
{
$sort = $request->input('sort');
$sortArray = $sort ? explode(',', $sort) : [];
return User::sort($sortArray)->get();
}
// Supports multiple sort parameters:
// GET /users?sort=name,-idYou can define a default sort order that will be applied when no sort parameters are provided:
class User extends Model {
use Sortable;
protected $sortable = ['id', 'name', 'email', 'created_at'];
protected $defaultSort = ['-created_at']; // Sort by newest first by default
}
// When called with no parameters, uses default sort
User::sort([])->get(); // Returns users sorted by created_at DESCYou can check if a specific field is sortable using the isSortable() method:
$user = new User();
if ($user->isSortable('name')) {
// Field is sortable
}
if ($user->isSortable('-id')) {
// Also works with descending prefix
}The package provides two ways to validate sort parameters:
class ListUsersRequest extends FormRequest
{
public function rules()
{
return [
'sort' => ['nullable', 'string', 'sort_fields:App\Models\User'],
];
}
}use Firevel\Sortable\SortField;
use App\Models\User;
class ListUsersRequest extends FormRequest
{
public function rules()
{
return [
'sort' => ['nullable', 'string', new SortField(User::class)],
];
}
}Both approaches work with string and array inputs:
// String input (e.g., from query string ?sort=name,-id)
'sort' => ['nullable', 'string', 'sort_fields:App\Models\User']
// Array input
'sort' => ['nullable', 'array', 'sort_fields:App\Models\User']Example usage in a controller:
public function index(ListUsersRequest $request)
{
$sort = $request->input('sort');
$sortArray = is_array($sort) ? $sort : explode(',', $sort);
return User::sort($sortArray)->get();
}The validation rule will automatically:
- Check if each field is in the model's
$sortablearray - Handle both ascending (
name) and descending (-name) formats - Provide clear error messages for invalid fields