Laravel cookbook · Beginner
Reuse query logic with local scopes
The same where-clauses are copied across controllers and drift apart.
Approach
Define local scopes with the #[Scope] attribute on protected methods, then chain them. Keep scopes small and
composable, and use a global scope only for rules that apply to every query (such as tenancy).
Solution
<?php
// app/Models/Product.php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
#[Scope]
protected function active(Builder $query): void
{
$query->where('active', true)->whereNull('discontinued_at');
}
#[Scope]
protected function inCategory(Builder $query, string $slug): void
{
$query->whereRelation('category', 'slug', $slug);
}
#[Scope]
protected function search(Builder $query, ?string $term): void
{
$query->when($term, fn (Builder $q) => $q->whereAny(['name', 'sku'], 'like', "%{$term}%"));
}
}
// Usage
// Product::active()->inCategory('teapots')->search(request('q'))->orderBy('name')->paginate(20);
Pitfalls
- Global scopes for convenience filters, surprising developers who forget
withoutGlobalScope. orWhereinside scopes without grouping, which breaks other constraints; wrap them in a closure.- Leading-wildcard
LIKEsearches on large tables; use full-text search.
Variations
- Custom Eloquent builders (
#[UseEloquentBuilder]) group many query methods for complex models. - Use
whereFullTextwith a full-text index for search.
Further reading: Local scopes
Reference: https://laravel.com/docs/13.x/eloquent#local-scopes
More Laravel recipes
- Authorize actions with policies
- Cache expensive data with stale-while-revalidate
- Call external APIs with timeouts, retries and fakes
- Catch N+1 queries with strict Eloquent mode
- Delete old records automatically with prunable models
- Dispatch events and listeners after the transaction commits
- Issue scoped API tokens with Sanctum
- Make queued jobs reliable with retries, backoff and uniqueness