Brief Understanding Laravel Scopes

In this article, we will discuss “Brief Understanding Laravel Scopes”. I will try to explain to you, How can you use this in your Laravel application. As we know, Laravel provides lots of rich features to make development easy and simple.

You can check the official documentation here. Now, the first question is:

Why we need scopes?

Assume, you want to reuse some conditions in your Model. Then Laravel provides a simple and easiest way which is called Scopes. Scopes can be implemented as Local Scope, Global Scope, and Dynamic Scope.

Local Scope

Consider you are working with the custom blog in Laravel. And you want to fetch all the posts which are published by the user. Then we use the following statement.

$post = Post::where('published', 1)->get();

Here, I need the same condition to apply to the various places throughout the model. We can implement the Laravel Local Scope within my Model. A Scope is a just method that helps us to reuse our condition logics. Scopes are defined by using the “scope” prefix with our method, as given below.

class Post extends Model
{
    public function scopePublished($query)
    {
        return $query->where('published', 1);
    }
}

After creating the scope, we can execute it like:

$post = Post::published()->get();

Dynamic Scope

Laravel also provides the solution for the dynamic scopes. For example, you want to fetch both records like published or unpublished then you can use the dynamic scope as given below.

class Post extends Model
{
    public function scopePublished($query, $arg)
    {
        return $query->where('published', $arg);
    }
}

After creating the dynamic scope, we can execute it like:

$post = Post::published(1)->get(); // Published

$post = Post::published(0)->get(); // Unpublished

 

Global Scope

Global Scopes allow us to add the required conditions to all queries of the given model or entire application models. Currently, no artisan command is available to create the scope. So we have to create manually. But you can use the other packages, which provide the solution for creating scopes dynamically such as laravel-make-scope.

Create Global Scope

It’s much easy and simple to create a global scope. You have to define a class, which implements the “Illuminate\Database\Eloquent\Scope” interface. In this interface, we implement the “apply” method and contains the “where” constraints.

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class TestScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('test_id', 101);
    }
}

 

Register Global Scope

The scope is ready now, we have to register this in the base model class “Model.php”. Use the following example to complete registration of the global scope.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model As BaseModel;
use App\Scopes\TestScope;

class Model extends BaseModel
{

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new TestScope());
    }
}

This scope is added to each query. You can test this using the query log.

If you want to remove the scope from the given query then Laravel also provides a simple way to do this, as given below.

// Remove all global scope
Post::withoutGlobalScopes()->get();

// Remove specific global scope
Post::withoutGlobalScopes([
    TestScope
])->get();

 

Register within a Model

When we need a scope for the Model, all of the queries of a specific model can use the scope. Then we need to register our scope in the Model as given below.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use App\Scopes\TestScope;

class User extends Model
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope(new TestScope());
    }
}

If you don’t want to create a scope in a separate class then you can add your where constraint in the same place as given below.

...
    static::addGlobalScope('test', function (Builder $builder) {
        $builder->where('test', 101);
    });
...

Conclusion

In this article, we are discussing “Brief Understanding Laravel Scopes”. Hoping this article helps you to understand the Laravel Scopes. We will discuss more the same in our future posts. Please feel free to add a comment in any query. You can also share your feedbacks 😉


You may like:

Laravel Authorization with Gates – Part 1

Laravel Authorization Policies – Part 2

Brief Understanding on Laravel Observers

Laravel Scout with TNTSearch Driver

If you like our content, please consider buying us a coffee.
Thank you for your support!
Buy Me a Coffee

LaravelLaravel 5.7Laravel 5.8Laravel 6Laravel Code Snippet
Comments (0)
Add Comment