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
Create Global Scope
Let’s make a scope called ActiveScope.php.
php artisan make:scope ActiveScope
<?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.
<?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.
Md Obydullah
Software Engineer | Ethical Hacker & Cybersecurity...
Md Obydullah is a software engineer and full stack developer specialist at Laravel, Django, Vue.js, Node.js, Android, Linux Server, and Ethichal Hacking.