What are scopes?
Eloquent scopes package reusable query constraints so you can apply them anywhere without repeating yourself. There are two kinds.Local scopes
Defining a local scope
Add the#[Scope] attribute to a protected model method that accepts a Builder instance.
The
#[Scope] attribute is in the Illuminate\Database\Eloquent\Attributes namespace. It requires PHP 8.0+.Using local scopes
Call the scope as a method on the model. You can chain multiple scopes.Passing parameters
Add extra parameters after theBuilder argument.
Combining scopes with orWhere
When you combine scopes withorWhere, use a closure to ensure correct grouping.
Global scopes
How they work
A global scope is a class that implementsIlluminate\Database\Eloquent\Scope. The interface requires a single apply method.
apply, you add constraints to the query builder.
Creating a global scope
Generate a scope class with Artisan.app/Models/Scopes/ActiveScope.php.
Applying a global scope to a model
1
Use the #[ScopedBy] attribute (recommended)
In Laravel 13, the Pass multiple scopes as an array.
#[ScopedBy] attribute is the simplest approach.2
Register in booted() manually
Override
booted and call addGlobalScope.User::all() automatically includes WHERE is_active = 1.
Anonymous closure scopes
For simple scopes that do not warrant a separate file, use a named closure.Removing global scopes
Inside the framework: SoftDeletingScope
Laravel’sSoftDeletes trait is a good example of how global scopes are used in practice.
See the withTrashed() implementation
See the withTrashed() implementation
withTrashed() simply calls withoutGlobalScope($this) — it removes the SoftDeletingScope itself so soft-deleted records are included.onlyTrashed() also removes the scope, then adds a whereNotNull('deleted_at') constraint.Practical use cases
Multi-tenancy: filtering by tenant automatically
In a SaaS application you want every query to be scoped to the current tenant’s data.Post::all() now returns only the current tenant’s posts automatically.
Published / draft filtering
Show only published content to visitors, but allow admins to see everything.Use addSelect instead of select in global scopes
Next steps
Eloquent custom casts
Learn how to implement custom casts with the CastsAttributes interface and the Castable pattern.