PHP
Applying Default Filters with Eloquent Global Scopes
Learn how to use Laravel Eloquent global scopes to automatically apply common query constraints to all queries of a specific model, ensuring consistent filtering.
// --- 1. Define the Global Scope Class ---
// app/Scopes/ActiveUserScope.php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class ActiveUserScope 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', true);
}
}
// --- 2. Apply the Global Scope to a Model ---
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Scopes\ActiveUserScope;
class User extends Model
{
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ActiveUserScope);
// You can also add anonymous global scopes:
// static::addGlobalScope('is_verified', function (Builder $builder) {
// $builder->where('email_verified_at', '!=', null);
// });
}
}
// --- 3. Querying with and without the Global Scope ---
// This will automatically include 'where is_active = 1'
$activeUsers = User::all();
// To remove a named global scope for a particular query
$allUsersIncludingInactive = User::withoutGlobalScope(ActiveUserScope::class)->get();
// To remove all global scopes for a particular query
$allUsersIgnoringScopes = User::withoutGlobalScopes()->get();
// If using an anonymous global scope, remove by its given name
// $allUsersNotVerified = User::withoutGlobalScope('is_verified')->get();
How it works: Global scopes allow you to apply a default set of constraints to all queries executed for a given model. This is useful for enforcing application-wide "soft deletes" (though Laravel has built-in soft deletes, this concept applies to other filters like `is_active`). You define a class that implements the `Scope` interface and its `apply` method, then add it to your model's `boot` method. For specific queries, you can temporarily remove global scopes using `withoutGlobalScope()` or `withoutGlobalScopes()`.