Installation
Run composer require jedrzej/sortable:0.0.12 in your Laravel project root.
Apply Trait
Add SortableTrait to your Eloquent model:
use Jedrzej\Sortable\SortableTrait;
class Post extends Model
{
use SortableTrait;
public $sortable = ['title', 'created_at', 'updated_at'];
}
First Use Case
Pass a sort query parameter in your API or web request (e.g., ?sort=title,-created_at).
The package automatically applies sorting to your query results.
Define Sortable Fields
Use either $sortable property or getSortableAttributes() method to specify allowed sort fields.
Example:
public function getSortableAttributes()
{
return ['name', 'price', 'published_at'];
}
Request Handling
The package reads the sort parameter from the request (e.g., ?sort=price,-published_at).
field1,field2,-field3 (ascending/descending).sort is missing.Integration with Queries Use the trait in controllers or repositories:
$posts = Post::sortable()->get(); // Applies sorting from request
Or chain with other query methods:
$posts = Post::where('status', 'published')->sortable()->paginate(10);
API/Resource Layer
Document the sort parameter in your API specs (e.g., Swagger/OpenAPI):
parameters:
- in: query
name: sort
schema:
type: string
example: "title,-created_at"
Frontend Integration
sort parameter (e.g., with URLSearchParams).
Example:
const sortBy = (field) => {
const params = new URLSearchParams(window.location.search);
params.set('sort', field.startsWith('-') ? field : field);
window.location.search = params.toString();
};
Invalid Sort Fields
?sort=non_existent) throws an exception.try-catch or validate the sort parameter in middleware:
if (!$model->isSortable($request->sort)) {
abort(400, 'Invalid sort field');
}
Case Sensitivity
name) may behave unexpectedly.orderByRaw:
public function getSortableAttributes()
{
return ['name' => 'LOWER(name)']; // Custom sorting logic
}
Performance
body) is slow for large datasets.Default Order Overrides
sort parameter overrides the model’s default setDefaultOrder().Log Sort Queries Enable Laravel query logging to verify sorting:
DB::enableQueryLog();
$posts = Post::sortable()->get();
dd(DB::getQueryLog());
Check Request Parsing
Debug the sort parameter parsing:
$sortable = new \Jedrzej\Sortable\Sortable($model, $request->sort);
dd($sortable->getSorts());
Custom Sort Logic
Override the applySort method in your model:
public function applySort($query, $sorts)
{
foreach ($sorts as $field => $direction) {
if ($field === 'custom') {
$query->orderByRaw('LENGTH(body) ' . $direction);
} else {
$query->orderBy($field, $direction);
}
}
}
Dynamic Sortable Fields Fetch sortable fields from a database table or config:
public function getSortableAttributes()
{
return Config::get('app.sortable_fields.' . $this->type);
}
Integration with Pimpable
Combine with Pimpable for unified filtering/sorting/eager-loading:
use Jedrzej\Pimpable\PimpableTrait;
class Post extends Model
{
use PimpableTrait;
protected $pimpable = [
'sortable' => ['title', 'created_at'],
'searchable' => ['title', 'body'],
'withable' => ['author', 'comments']
];
}
API Versioning Use middleware to restrict sortable fields per API version:
public function handle($request, Closure $next)
{
$model = new Post();
$allowedFields = config("api.v1.sortable_fields");
$model->setSortable($allowedFields);
return $next($request);
}
How can I help you explore Laravel packages today?