PHP

Applying Application-Wide Query Constraints with Eloquent Global Scopes

Implement Eloquent global scopes to automatically apply query constraints to all queries for a specific model, useful for multi-tenancy, soft deletes, or general data filtering.

<?php
// 1. Define a Global Scope Class (e.g., 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 an Eloquent Model (e.g., app/Models/User.php)
namespace App\Models;

use App\Scopes\ActiveUserScope; // Import the scope
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'email', 'is_active'];

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope(new ActiveUserScope);
        // You can also define an anonymous global scope
        // static::addGlobalScope('age', function (Builder $builder) {
        //     $builder->where('age', '>', 18);
        // });
    }
}

// Example Usage in a controller or route
use App\Models\User;

// This query will automatically include `WHERE is_active = 1`
$activeUsers = User::all();
// SELECT * FROM users WHERE is_active = 1

// This query will also include `WHERE is_active = 1`
$someActiveUser = User::where('name', 'John Doe')->first();
// SELECT * FROM users WHERE name = 'John Doe' AND is_active = 1 LIMIT 1

// To remove a global scope for a specific query
$allUsersIncludingInactive = User::withoutGlobalScope(ActiveUserScope::class)->get();
// SELECT * FROM users

// To remove all global scopes
$allUsersNoScopes = User::withoutGlobalScopes()->get();
// SELECT * FROM users
How it works: Global scopes provide a way to apply common constraints to all queries for a given Eloquent model. Unlike local scopes which are explicitly called, global scopes are automatically applied, ensuring consistency across your application. This snippet shows how to define a global scope class (e.g., `ActiveUserScope` to only fetch active users) and how to register it within a model's `booted` method. It also demonstrates how to temporarily remove global scopes using `withoutGlobalScope()` or `withoutGlobalScopes()` when you need to fetch records that would normally be filtered out. This is particularly useful for features like multi-tenancy or a default "published" status.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs