How to Register Eloquent Global Scope in Laravel

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

Let’s make a scope called ActiveScope.php.

php artisan make:scope ActiveScope
app\Models\Scopes\ActiveScope.php
<?php
namespace App\Models\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\Models\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(ActiveScope::class)->get();

And if we want to remove 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.