patternphplaravelTip
Eloquent Query Scopes for Reusable Constraints
Viewed 0 times
query scopelocal scopeglobal scopescopeActivewithoutGlobalScopereusable queries
Problem
Repeating the same where() clauses across multiple controller methods leads to code duplication and makes it hard to change business logic in one place.
Solution
Define local scopes as methods prefixed with 'scope' on the model. They receive a Builder instance and return it. Call them without the prefix in queries. Define global scopes in a separate class and register in the model's booted() method for constraints that must always apply.
Why
Scopes encapsulate query logic inside the model layer where it belongs. Local scopes are opt-in. Global scopes are automatic and ensure invariants like soft-delete filtering or tenant isolation are never forgotten.
Gotchas
- Local scope methods must be prefixed with 'scope' but called without it
- Global scopes apply to every query including relationships—test carefully
- To bypass a global scope use withoutGlobalScope(ScopeName::class)
- Scopes can accept parameters: scopeOfType($query, $type)
Code Snippets
Local and global scopes
// Model
class Post extends Model
{
public function scopePublished(Builder $query): Builder
{
return $query->where('status', 'published');
}
public function scopeByAuthor(Builder $query, int $authorId): Builder
{
return $query->where('author_id', $authorId);
}
}
// Usage
$posts = Post::published()->byAuthor(1)->get();Revisions (0)
No revisions yet.