PHP

Dynamic Filtering with Eloquent Local Scopes

Implement flexible and reusable query filters in Laravel Eloquent using local scopes, allowing dynamic search criteria for models based on various inputs.

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

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    // Define a local scope for category filtering
    public function scopeCategory(Builder $query, string $categorySlug): void
    {
        $query->whereHas('category', function ($q) use ($categorySlug) {
            $q->where('slug', $categorySlug);
        });
    }

    // Define a local scope for price range filtering
    public function scopePriceRange(Builder $query, float $minPrice, float $maxPrice): void
    {
        $query->whereBetween('price', [$minPrice, $maxPrice]);
    }

    // Define a local scope for search term
    public function scopeSearch(Builder $query, string $searchTerm): void
    {
        $query->where('name', 'like', '%' . $searchTerm . '%')
              ->orWhere('description', 'like', '%' . $searchTerm . '%');
    }
}

// app/Http/Controllers/ProductController.php
namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index(Request $request)
    {
        $products = Product::query();

        if ($request->has('category')) {
            $products->category($request->input('category'));
        }

        if ($request->has(['min_price', 'max_price'])) {
            $products->priceRange($request->input('min_price'), $request->input('max_price'));
        }

        if ($request->has('search')) {
            $products->search($request->input('search'));
        }

        // Add ordering, pagination, etc.
        $products = $products->orderBy('created_at', 'desc')->paginate(10);

        return view('products.index', compact('products'));
    }
}
How it works: This snippet demonstrates how to use Eloquent local scopes to implement dynamic, reusable filtering logic. Local scopes are methods prefixed with `scope` in your model, accepting the `Builder` instance as their first argument. You can then chain these scopes in your controller based on request parameters. This approach keeps your controller clean and makes query logic reusable across your application, improving maintainability and readability for complex filtering scenarios.

Need help integrating this into your project?

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

Hire DigitalCodeLabs