Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Model Filter Laravel Package

laraditz/model-filter

Flexible Eloquent model filtering for Laravel with operator support (eq, gte, etc.), AND/OR grouping, and relationship filters via dot notation. Add a Filterable trait and allowlist fields, optionally create filter classes for custom logic, and filter using request params under filters[].

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laraditz/model-filter
    
  2. Apply Trait to Model: Add Filterable trait to your Eloquent model and define $filterable array with allowed fields (including dot-notation for relationships):

    use Laraditz\ModelFilter\Filterable;
    
    class User extends Model
    {
        use Filterable;
    
        protected array $filterable = [
            'name',
            'email',
            'age',
            'role.name', // Relationship field
        ];
    
  3. First Use Case: Filter a query via HTTP request (e.g., API or form submission):

    $users = User::filter(request()->all())->get();
    

    Ensure request payload includes filters[] (e.g., {"filters[email]": "[email protected]"}).


Where to Look First

  • Artisan Command: Generate a filter class for complex logic:
    php artisan make:filter UserFilter
    
  • Filterable Trait: Review $filterable allowlist and relationship definitions.
  • Request Handling: Check how filters[] is structured in incoming requests.

Implementation Patterns

Core Workflows

  1. Basic Filtering:

    // In Controller/Service
    $query = User::filter(request()->input('filters', []));
    $results = $query->get();
    
  2. Custom Filter Logic: Extend generated filter class (app/Filters/UserFilter.php):

    namespace App\Filters;
    
    use Laraditz\ModelFilter\Filter;
    
    class UserFilter extends Filter
    {
        public function isAdmin(): void
        {
            $this->builder->where('role.name', 'admin');
        }
    
        public function activeOnly(): void
        {
            $this->builder->where('is_active', true);
        }
    }
    

    Apply in query:

    $query = User::filter(request()->input('filters', []))
                 ->when(request()->has('admin'), fn($q) => $q->isAdmin())
                 ->when(request()->has('active'), fn($q) => $q->activeOnly());
    
  3. Relationship Filtering: Use dot-notation in $filterable (e.g., role.name) and pass filters like:

    {
        "filters[role.name]": "admin"
    }
    
  4. Operator Support: Append operators to filter keys (e.g., filters[age][gt] for age > 25):

    {
        "filters[age][gt]": 25
    }
    

    Supported operators: =, !=, >, <, >=, <=, like, ilike.


Integration Tips

  • API Requests: Use request()->input('filters', []) to capture filter parameters.
  • Form Requests: Validate filters[] in a FormRequest class:
    public function rules(): array
    {
        return [
            'filters.name' => 'sometimes|string',
            'filters.email' => 'sometimes|email',
        ];
    }
    
  • Pagination: Combine with Laravel’s pagination:
    $users = User::filter(request()->input('filters', []))
                 ->paginate(10);
    
  • API Resources: Filter data before serialization:
    return new UserResource(User::filter(request()->input('filters', []))->get());
    

Gotchas and Tips

Pitfalls

  1. Namespace Change (v2):

  2. Strict Allowlist:

    • Only fields listed in $filterable are allowed. Omitting a field silently ignores it (no error).
    • Debug tip: Log request()->input('filters', []) to verify payload structure.
  3. Relationship Pitfalls:

    • Ensure relationship methods (e.g., role()) are defined in the model.
    • Dot-notation (e.g., role.name) requires the relationship (role) and field (name) to exist.
  4. Operator Conflicts:

    • Avoid ambiguous keys like filters[age][gt] and filters[age][lt] in the same request if not handled by the package (may require custom logic).

Debugging

  1. Query Inspection: Use toSql() and getBindings() to debug generated queries:

    $query = User::filter(request()->input('filters', []));
    dd($query->toSql(), $query->getBindings());
    
  2. Filter Validation: Temporarily log filter inputs:

    \Log::info('Raw filters:', request()->input('filters', []));
    
  3. Custom Filter Issues: Ensure custom filter methods in UserFilter are public and follow the void return type convention.


Extension Points

  1. Custom Operators: Extend the package by publishing and modifying the operator logic (check vendor/laraditz/model-filter/src/Operators/).

  2. Filter Events: Listen for filter application via events (if the package emits them; check source for hooks).

  3. Dynamic Allowlists: Override $filterable dynamically (e.g., based on user roles):

    protected array $filterable = [];
    public function boot()
    {
        $this->filterable = auth()->user()->can('admin') ? ['*'] : ['name', 'email'];
    }
    
  4. Caching Filters: Cache filtered query results if filters are static (e.g., dashboard widgets):

    $cacheKey = 'users_filtered_' . md5(serialize(request()->input('filters', [])));
    return Cache::remember($cacheKey, now()->addHours(1), function() {
        return User::filter(request()->input('filters', []))->get();
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc