Installation
composer require laravellegends/eloquent-filter
Publish the config (optional):
php artisan vendor:publish --provider="LaravelLegends\EloquentFilter\ServiceProvider"
Basic Usage Define a filterable model trait:
use LaravelLegends\EloquentFilter\Filterable;
class User extends Model
{
use Filterable;
}
First Filter Define a filter in your model:
protected $filterable = [
'name' => 'like',
'active' => 'boolean',
'role' => 'in:admin,user'
];
Apply in a controller:
$users = User::filter(request()->all())->get();
API Integration Use with Laravel API Resources:
return UserResource::collection(User::filter(request()->query())->get());
Dynamic Filtering
// In controller
$query = User::filter(request()->query())->get();
// Or with custom logic
$query = User::filter(request()->query(), ['name' => 'contains']);
Nested Relationships
protected $filterable = [
'posts.title' => 'like',
'posts.published' => 'boolean'
];
Custom Filter Logic
protected $filterable = [
'age' => ['min', 'max']
];
public function scopeAge($query, $value)
{
if (is_array($value)) {
return $query->whereBetween('age', $value);
}
return $query->where('age', $value);
}
Validation Integration
use LaravelLegends\EloquentFilter\Filterable;
class User extends Model
{
use Filterable;
protected $filterable = [
'email' => 'email',
'status' => 'in:active,pending,banned'
];
public function filter($query)
{
$this->validateFilter($query);
return parent::filter($query);
}
}
Pagination + Filtering
return User::filter(request()->query())
->paginate(15)
->withQueryString();
Document Filters Use OpenAPI/Swagger annotations to document available filters:
/**
* @OA\Parameter(
* name="name",
* in="query",
* description="Filter by name (partial match)",
* required=false,
* @OA\Schema(type="string")
* )
*/
Default Sorting
Combine with orderBy:
$users = User::filter(request()->query())
->orderBy('created_at', 'desc')
->get();
Case Sensitivity
like filters are case-sensitive by default. Use LIKE with LOWER() in custom scopes for case-insensitive searches.Boolean Handling
boolean filters expect 1/0, true/false, or '1'/'0' strings. Validate input carefully:
$request->validate(['active' => 'boolean']);
Nested Relationships
$users = User::with(['posts' => fn($q) => $q->where('published', true)])
->filter(request()->query())
->get();
Performance
// Slow for unindexed columns
$users = User::filter(['email' => 'like:%@domain.com%'])->get();
Overwriting Defaults
filter() method can be overridden, but ensure you call parent::filter():
public function filter($query)
{
$query = parent::filter($query);
// Additional logic
return $query;
}
Log Raw Queries
\DB::enableQueryLog();
User::filter(request()->query())->toSql();
dd(\DB::getQueryLog());
Validate Filter Input Use Laravel's validation to catch malformed requests early:
$validated = $request->validate([
'name' => 'sometimes|string',
'active' => 'sometimes|boolean',
]);
User::filter($validated)->get();
Custom Filter Types
Extend the Filterable trait or create a new trait:
trait CustomFilterable
{
public function scopeRange($query, $value)
{
if (is_array($value)) {
return $query->whereBetween('column', $value);
}
}
}
Global Filters Add middleware to apply filters globally:
public function handle($request, Closure $next)
{
if ($request->has('filter')) {
$request->merge(['query' => $request->filter]);
}
return $next($request);
}
Filter Groups Use array syntax for grouped filters:
$users = User::filter([
'group1' => ['name' => 'like', 'active' => true],
'group2' => ['role' => 'admin']
])->get();
Conditional Filters Dynamically add filters based on request:
$filters = ['name' => 'like'];
if ($request->has('active')) {
$filters['active'] = 'boolean';
}
User::filter($filters)->get();
Default Filter Behavior
The package uses where by default. For like filters, it appends % wildcards automatically. Disable this by overriding the like scope:
public function scopeLike($query, $value)
{
return $query->where('column', 'like', $value);
}
Empty Filter Values
Empty strings or null values are ignored by default. To include them:
protected $filterable = [
'name' => ['like', 'nullable']
];
How can I help you explore Laravel packages today?