PHP

Implementing Global Scopes for Application-Wide Eloquent Filtering

Apply consistent query constraints across multiple models automatically using Laravel Eloquent global scopes, ensuring data integrity and simplifying common query patterns.

// app/Scopes/PublishedScope.php
namespace App\Scopes;

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

class PublishedScope 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_published', true);
    }
}

// app/Models/Post.php
namespace App\Models;

use App\Scopes\PublishedScope;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = ['title', 'content', 'is_published'];

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope(new PublishedScope);
    }
}

// app/Models/Page.php
namespace App\Models;

use App\Scopes\PublishedScope;
use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    protected $fillable = ['title', 'body', 'is_published'];

    protected static function booted()
    {
        static::addGlobalScope(new PublishedScope);
    }
}

// Usage example (e.g., in a controller)
// Only published posts will be retrieved by default
$publishedPosts = Post::all();

// You can temporarily remove a global scope
$allPostsIncludingUnpublished = Post::withoutGlobalScope(PublishedScope::class)->get();

// Or remove all global scopes
$allPostsIncludingUnpublishedAndMore = Post::withoutGlobalScopes()->get();

// Query on published items
$latestPublishedPost = Post::orderBy('created_at', 'desc')->first();
How it works: Global scopes allow you to add constraints to all queries for a given model. They are ideal for "soft deletes," multi-tenancy, or ensuring only "published" content is retrieved by default. To define one, create a class that implements `Illuminate\Database\Eloquent\Scope` and implement its `apply` method, adding your desired `where` clauses. Then, register the scope within the model's `booted()` method using `static::addGlobalScope()`. You can temporarily remove global scopes for specific queries using `withoutGlobalScope()` or `withoutGlobalScopes()`.

Need help integrating this into your project?

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

Hire DigitalCodeLabs