How to Register Eloquent Global Scope in Laravel

Published on December 18, 2020 1 min read

Global scopes allow you to add constraints to all queries for a given model. Laravel’s own soft delete functionality utilizes global scopes to only retrieve “non-deleted” models from the database.

In this article, we’ll create our own global scope. Let’s get started:

Table of Contents

  1. Create Global Scope
  2. Register Scope in Model
  3. Anonymous Global Scope
  4. Remove Scope From Query

Create Global Scope

We have to create scope in app\Scopes folder. Let’s make a scope called ActiveScope.php.

ActiveScope.php
<?php

namespace App\Scopes;

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

class ActiveScope 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('is_active', 1);
    }
}

Register Scope in Model

In this step, we’ll define ActiveScope in User model.

User.php
<?php

namespace App;

use App\Scopes\ActiveScope;
use Illuminate\Database\Eloquent\Model;
  
class User extends Model
{
    protected $fillable = [
        'name','email','password','is_active',
    ];
  
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope(new ActiveScope);
    }
}

If we run select query User::all(), it will execute the following SQL query:

select * from `users` where `is_active` = 1

Anonymous Global Scope

Eloquent also allows you to define global scopes using closures, which is particularly useful for simple scopes that do not warrant a separate class of their own.

<?php

namespace App\Models;

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

class User extends Model
{
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope('ancient', function (Builder $builder) {
            $builder->where('created_at', '<', now()->subDays(20));
        });
    }
}

Remove Scope From Query

To remove a global scope for a given query, we can use the withoutGlobalScope method:

User::withoutGlobalScope(AncientScope::class)->get();

And if we want to removed the global scope using closure (anonymous), we need to write code like:

User::withoutGlobalScope('ancient')->get();

To remove all of the global scopes:

User::withoutGlobalScopes()->get();

To remove some of the global scopes:

User::withoutGlobalScopes([
    FirstScope::class, SecondScope::class
])->get();
That’s all, artisans. Thanks for reading. 🙂

Monthly Newsletter

One email a month, packed with the latest tutorials, delivered straight to your inbox.
We'll never send any spam or promotional emails.
Author

Hey, I'm Md Obydullah. I build open-source projects and write on Laravel, Linux server, modern JavaScript and more on web development.

Follow