Weave Code
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

Query Filter Laravel Package

laravie/query-filter

Laravie Query Filter adds a clean, reusable way to filter Eloquent queries from request input. Define filter classes and apply them to models to handle searching, sorting, and conditional constraints without cluttering controllers or repositories.

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation

    composer require laravie/query-filter
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Laravie\QueryFilter\QueryFilterServiceProvider"
    
  2. Basic Usage Use the Filterable trait on your Eloquent model:

    use Laravie\QueryFilter\Filterable;
    
    class User extends Model
    {
        use Filterable;
    }
    
  3. Define Filters Add a filters() method to your model:

    public function filters()
    {
        return [
            'name' => ['like', 'contains'],
            'email' => ['equals', 'not_equals'],
            'status' => ['in', 'not_in'],
        ];
    }
    
  4. Apply Filters in a Query

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

Implementation Patterns

Common Workflows

  1. Dynamic Filtering from Request

    $query = User::filter(request()->query('filters'));
    
  2. Predefined Filter Sets

    $query = User::filter(['status' => 'active', 'role' => 'admin']);
    
  3. Combining with Other Query Methods

    $query = User::where('active', true)
                 ->filter(request()->query('filters'))
                 ->orderBy('name');
    
  4. Custom Filter Logic Override applyFilters() in your model:

    protected function applyFilters($query, array $filters)
    {
        if (isset($filters['custom'])) {
            $query->where('created_at', '>', now()->subDays(7));
        }
        return parent::applyFilters($query, $filters);
    }
    
  5. API Resource Filtering

    // In a controller
    $users = User::filter(request()->query('filters'))->get();
    return new UserResource($users);
    

Integration Tips

  • Form Request Validation Validate filter inputs in a FormRequest:

    public function rules()
    {
        return [
            'filters.name' => 'sometimes|string',
            'filters.status' => 'sometimes|in:active,inactive',
        ];
    }
    
  • API Documentation Document expected filter formats in your API specs (e.g., Swagger/OpenAPI).

  • Testing Test filter logic with assertDatabaseHas or assertSoftDeleted:

    $response = $this->get('/users?filters[status]=active');
    $response->assertOk();
    

Gotchas and Tips

Common Pitfalls

  1. Case Sensitivity in like/contains Use LOWER() or ILIKE for case-insensitive searches:

    public function filters()
    {
        return [
            'name' => ['like' => 'ILIKE'],
        ];
    }
    
  2. Nested Filter Arrays Flatten nested arrays in your request:

    // Instead of:
    // filters[user][status]=active
    // Use:
    // filters[status]=active
    
  3. Performance with Large Datasets Avoid unbounded like queries. Add constraints:

    public function filters()
    {
        return [
            'name' => ['like' => ['constraint' => 'starts_with']],
        ];
    }
    
  4. Reserved Keywords Escape column names if they match SQL keywords (e.g., order):

    public function filters()
    {
        return [
            '`order`' => ['equals'],
        ];
    }
    

Debugging Tips

  • Log Filter Queries Add a toSql() debug line:

    $query = User::filter(request()->query('filters'));
    \Log::debug($query->toSql(), $query->getBindings());
    
  • Check Filter Definitions Ensure filters() returns an array of valid operations (e.g., ['equals', 'not_equals']).

  • Validate Inputs Use request()->validate() or a FormRequest to catch malformed filters early.


Extension Points

  1. Custom Filter Operations Extend the package by adding new operations in a service provider:

    QueryFilter::extend('custom', function ($query, $value) {
        return $query->where('column', '>', $value);
    });
    
  2. Global Filter Middleware Apply filters globally in a middleware:

    public function handle($request, Closure $next)
    {
        if ($request->has('filters')) {
            $model = app($request->route('model'));
            $model::filter($request->query('filters'));
        }
        return $next($request);
    }
    
  3. Filter Groups Support multi-tenancy or role-based filters:

    public function filters()
    {
        return [
            'tenant_id' => ['equals' => auth()->user()->tenant_id],
            'role' => ['in' => auth()->user()->allowed_roles],
        ];
    }
    
  4. Caching Filtered Queries Cache filtered results with tags:

    $users = Cache::tags(['users', 'status:active'])->remember(
        'filtered_users',
        now()->addHours(1),
        fn() => User::filter(['status' => 'active'])->get()
    );
    

Laravel 11 Compatibility

  • New Framework Features Leverage Laravel 11’s improved dependency injection and container features for cleaner integration:

    // Example: Using Laravel 11's new `app()` helper
    $filteredQuery = app(User::class)->filter(request()->query('filters'));
    
  • Model Binding Updates Ensure your routes and controllers are updated to use Laravel 11’s model binding syntax if applicable:

    // In routes/api.php
    Route::get('/users/{user}', function (User $user) {
        return User::filter(request()->query('filters'))->get();
    });
    
  • Testing with Laravel 11 Update your tests to use Laravel 11’s testing helpers:

    public function test_filtering_users()
    {
        $response = $this->get('/users?filters[status]=active');
        $response->assertOk();
        // Use Laravel 11's assertion methods
    }
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity