Grayscale profile picture

Patrique Ouimet


Sortable Models with a Trait and Laravel's Query Scope

Sat, Sep 16, 2017 5:06 PM


This post aims to provide a simple example of how to use traits with Laravel Query Scopes. The trait will sort columns based on "sort" and "direction" being found within the request, while protecting the database of unwanted sorting by adding a "sortables" property to the model. The end result looks like this with a Post model as an example:


Sortable trait

Create the trait below in the "App" namespace (or change the namespace to suit your projects convention).


namespace App;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

trait Sortable
     * Scope a query to sort results.
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Database\Eloquent\Builder
    public function scopeSort(Builder $query, Request $request)
        // Get sortable column
        $sortables = data_get($this, 'sortables', []);

        // Get the column to sort
        $sort = $request->get('sort');

        // Get the direction of which to sort
        $direction = $request->get('direction', 'desc');

        // Ensure column to sort is part of model's sortables property
        // and that the direction is a valid value
        if ($sort
            && in_array($sort, $sortables)
            && $direction
            && in_array($direction, ['asc', 'desc'])) {
            // Return ordered query
            return $query->orderBy($sort, $direction);

        // No sorting, return query
        return $query;

Model setup

The model setup requires 2 things:

  1. Add a use Sortable; statement (and import the class use App\Sortable as seen in the example below)
  2. Add a sortable public property which is an array of values that may be sorted

Example below allows sorting for the columns: id, views, published_at


namespace App;

use App\Sortable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
    use Sortable;

    public $sortables = ['id', 'views', 'published_at'];

Trait usage

Below is an example of the usage of the sortable trait (query scope).


namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostController extends Controller
    public function index()
        return Post::sort(request())->get();

NOTE: This also works with pagination Post::sort(request())->paginate()


If you want to see this in action, I've created a small Laravel application to demo it.

Sortable Demo

Demo setup steps are as follows:

  1. Clone repository git clone
  2. Composer install composer install
  3. Run migrations php artisan migrate
  4. Run seeders php artisan db:seed
  5. Run artisan serv php artisan serve
  6. Visit (or value displayed from artisan serve)


That's it! I believe it's a pretty straight forward approach and made easy by Laravel's Query Scopes. Query Scopes are something I had avoided in my early Laravel development days, but I've learnt to embrace the simplicity that Laravel brings to complex situations and it's been enlightening. I suggest to everyone who's using Laravel to dig deep into the framework, there's TONS of hidden gems in there to make your life easier. Thank you Taylor Otwell and all the contributors for making my development life easier.

Hope you liked my article, please leave comments and share if you like!




Nov 19, 2017

This is a very nice trait I must say :)