DEV Community

Saurabh Mahajan
Saurabh Mahajan

Posted on

Using Scope to improve Code readability.

Laravel Query Scope is one of my favorite feature and its the one that I use extensively as it helps to keep code clean and make it more readable.

Let's suppose we have the following Code in Controller which fetches all the Posts which are active.

Post::query()
    ->where('active', 1)
    ->get();
Enter fullscreen mode Exit fullscreen mode

A very simple query with one where clause. Let's convert this where Clause to a Scope. We will go to Post Model and will create a method. We will call it scopeActive. The method name must being with scope. It will have Eloquent\Builder passed to it automatically. So we will define our method like below:

public function scopeActive( $query ) 
{
    return $query->where('active', 1);
}
Enter fullscreen mode Exit fullscreen mode

We can now use utilize this Scope and our Controller Code will become as below:

Post::query()
    ->active()
    ->get();
Enter fullscreen mode Exit fullscreen mode

We can now use our active scope anywhere in our code and Laravel will automatically convert it into query. Not a big improvement, you might say, but let's look at the following example where we need to get Active Posts which are created between 2 dates.

Post::query()
    ->where('active', 1)
    ->whereBetween('created_at', [
        $startDate . ' 00:00:00',
        $endDate .' 23:59:59'
    ])
    ->get();
Enter fullscreen mode Exit fullscreen mode

Let's create a scope for this. We will call it scopeBetween and it will accept 2 parameters, $startDate and $endDate.

public function scopeBetween($query, $startDate, $endDate)
{
    $endDate .= ' 23:59:59';
    return $query->whereBetween('created_at', [
        $startDate,
        $endDate
    ]);
}
Enter fullscreen mode Exit fullscreen mode

And now we can change our Controller Code as below:

Post::query()
    ->active()
    ->between($startDate, $endDate)
    ->get();
Enter fullscreen mode Exit fullscreen mode

If we compare this, our code is much more readable and a lot of noise has been removed. And we are starting to see the benefit of using Scopes.

Let us have another scenario where we want to retrieve active Posts created during Last Month. Our Code without Scope would look like below:

Post::query()
    ->where('active', 1)
    ->whereBetween('created_at', [
        Carbon::now()->startOfMonth()->subMonthNoOverflow(),
        Carbon::now()->subMonthNoOverflow()->endOfMonth()
    ])
    ->get();
Enter fullscreen mode Exit fullscreen mode

Now let us define a Scope as follows:

public function scopeLastMonth($query)
{
    $startDate = Carbon::now()->startOfMonth()->subMonthNoOverflow();
    $endDate = Carbon::now()->subMonthNoOverflow()->endOfMonth();

    return $query->whereBetween('created_at', [
        $startDate,
        $endDate
    ]);
}
Enter fullscreen mode Exit fullscreen mode

And our Code which uses the above scope becomes:

Post::query()
    ->active()
    ->lastMonth()
    ->get();
Enter fullscreen mode Exit fullscreen mode

As you can see, we can encapsulate our complex or repeating conditions within the scope. We can give a meaningful name to our Scopes. And then use those scopes in our code which drastically improves the readability of our code.

Discussion (0)