indexzer0/eloquent-filtering
Filter Laravel Eloquent models using simple arrays and request data—no custom query spaghetti. Define allowed filters on your models, support complex search, and keep queries readable, maintainable, and easy to extend for APIs and dashboards.
where(), orWhere() chains) in favor of declarative model-level definitions.allowedFilters()), decoupling business rules from controllers/routes. Supports Single Responsibility Principle (SRP).FilterType enum) and JSON path queries (e.g., nested attributes), accommodating complex data structures.use Filterable; allowedFilters()) and a single filter() method call on queries.=, <, > filters).FilterType syntax (e.g., $eq, $like:start).$or conditions). Benchmarking recommended for high-traffic endpoints.options->languages.$jsonLength) require PostgreSQL/MySQL JSON extensions and may not work universally across databases.$like values)?query cache)?FilterType).where() logic in a custom Filterable trait for gradual adoption.where() calls with Filter::field() for basic operations ($eq, $gt, $like).// Before
User::where('status', 'active')->where('age', '>', 18);
// After
User::filter([
['type' => '$eq', 'target' => 'status', 'value' => 'active'],
['type' => '$gt', 'target' => 'age', 'value' => 18],
]);
allowedFilters() in models to centralize filter logic.class User extends Model implements IsFilterable {
use Filterable;
public function allowedFilters(): AllowedFilterList {
return Filter::only(
Filter::field('status', [FilterType::EQUAL]),
Filter::field('age', [FilterType::GREATER_THAN])
);
}
}
ValidatedRequest or API resources.filter() calls in unit tests.toRawSql()) to debug performance issues.where() logic, easing future changes.toRawSql() for debugging).FilterType syntax and model annotations.status, age).paginate() to avoid large result sets.cache()->remember()).$jsonLength or nested filters.| Risk | Mitigation |
|---|---|
| Invalid Filters | Use allowedFilters() to whitelist operations; validate inputs via Form Requests. |
| SQL Injection | Package sanitizes inputs, but custom filter types may introduce risks. |
| Query Timeouts | Limit complexity of nested $or/$and conditions; add query timeouts. |
| Database Incompatibility | Test on target DB early; avoid JSON path queries on SQLite. |
| Caching Issues | Avoid caching filtered queries with dynamic parameters; use cache tags. |
FilterType syntax and model annotations.FilterType::CUSTOM('between')).allowedFilters() and filter arrays.laravel-openapi.How can I help you explore Laravel packages today?