PHP
Implement Reusable Query Logic with Eloquent Local Scopes
Create elegant and reusable query constraints by defining local scopes in your Laravel Eloquent models, promoting cleaner, more maintainable code.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Product extends Model
{
/**
* Scope a query to only include active products.
*/
public function scopeActive(Builder $query): void
{
$query->where('is_active', true);
}
/**
* Scope a query to only include products within a given price range.
*/
public function scopePriceRange(Builder $query, float $minPrice, float $maxPrice = null): void
{
$query->where('price', '>=', $minPrice);
if ($maxPrice !== null) {
$query->where('price', '<=', $maxPrice);
}
}
}
// Usage examples:
$activeProducts = Product::active()->get();
$expensiveProducts = Product::priceRange(100)->get();
$midRangeProducts = Product::priceRange(50, 150)->active()->get();
$specificActiveProduct = Product::active()->where('name', 'Laptop')->first();
How it works: Eloquent local scopes allow you to define common sets of query constraints that you can easily reuse throughout your application. To define a scope, prefix a method name in your model with `scope` (e.g., `scopeActive`). This method will receive the `Illuminate\Database\Eloquent\Builder` instance as its first argument. You can then call these scopes directly on the model or relationship query builder (e.g., `Product::active()`). Scopes can also accept arguments, as shown with `scopePriceRange`, making them highly flexible. This pattern keeps your controller or service logic cleaner and promotes the DRY (Don't Repeat Yourself) principle.