Applying conditions to queries gives you to power to retrieve and present filtered data in every imaginable manner. Some of these conditions will be used more than others, and Laravel provides a solution for cleanly packaging these conditions into easily readable and reusable statements, known as a scope. In this tutorial I’ll show you how to easily integrate scopes into your Laravel models.

Consider a filter that only retrieves completed list tasks. You could use the following where condition to retrieve those tasks:

$completedTasks = Task::where('done', true)->get();

You might however wish to use a query such as this at multiple locations throughout an application. If so, you can DRY the code up a bit by instead using a scope. A scope is just a convenience method you can add to your model which encapsulates the syntax used to execute a query such as the above. Scopes are defined by prefixing the name of a method with scope, as demonstrated here:

class Task extends Model
{

    public function scopeDone($query)
    {
        return $query->where('done', 1);
    }

}

With the scope defined, you can execute it like so:

$completedTasks = Task::done()->get();

Creating Dynamic Scopes

If you wanted to create a scope capable of returning both completed and incomplete tasks based on a supplied argument, just define an input parameter like you would any model method:

class Task extends Model {

    public function scopeDone($query, $flag)
    {
        return $query->where('done', $flag);
    }

}

With the input parameter defined, you can use the scope like this:

// Get completed tasks
$completedTasks = Task::done(true)->get();

// Get incomplete tasks
$incompleteTasks = Task::done(false)->get();

Using Scopes with Relations

You’ll often want to use scopes in conjunction with relations. For instance, you can retrieve a list of tasks associated with a specific list:

$list = Todolist::find(34);
$completedTasks = $list->tasks()->done(true)->get();