Published on September 05 Aug 25
Stop Writing Repetitive Query Filters in Laravel

Stop Writing Repetitive Query Filters in Laravel — Meet YSM/Filterable
In every real-world Laravel project, there comes a time when your controllers start filling up with conditional query logic:
$query->when(request('status'), fn ($q, $status) => $q->where('status', $status));
$query->when(request('category'), fn ($q, $category) => $q->where('category', $category));
$query->when(request('published'), fn ($q) => $q->where('published', true));
It works, sure. But as your filters grow, it gets ugly, repetitive, and hard to test or maintain.
That’s where YSM/Filterable
comes in.
🎯 What is YSM/Filterable
?
YSM/Filterable
is a Laravel package that makes dynamic filtering clean, reusable, and decoupled.
Instead of writing filtering logic inside your controller or query builder, you define all your filters in a dedicated class, keeping your controller logic clean and maintainable.
Think of it as FormRequest
but for filtering.
🚀 Installation
Install it via Composer:
composer require ysm/filterable
✍️ Basic Usage Example
Let’s say we have a Post
model and we want to filter it by:
Title (partial match)
Category (exact match)
Published status (boolean)
Step 1: Add the Trait to the Model
use YSM\Filterable\Concerns\InteractWithFilterable;
class Post extends Model
{
use InteractWithFilterable;
}
Step 2: Create a Filter Class
use YSM\Filterable\Filterable;
class PostFilter extends Filterable
{
protected array $allowedFilters = ['title', 'category', 'published'];
public function title(string $value): void
{
$this->builder->where('title', 'like', "%{$value}%");
}
public function category(string $value): void
{
$this->builder->where('category', $value);
}
public function published(bool $value): void
{
$this->builder->where('published', $value);
}
}
Step 3: Use in Your Controller
public function index()
{
$posts = Post::filterable(PostFilter::class)->get();
return response()->json(['data' => $posts]);
}
Now you can hit the endpoint with:
GET /posts?title=Laravel&category=tutorial&published=1
And PostFilter
will take care of the rest. Clean and simple.
🧠 What Makes YSM/Filterable
Special?
Besides moving filter logic out of your controller, it supports:
✅ Aliases for Request Parameters
Map cat
to category
, or q
to title
.
protected array $aliases = ['cat' => 'category'];
✅ Auto-apply Filters (Even Without Request Input)
You can auto-apply filters like:
protected array $autoApplyFilters = ['published'];
This ensures published=true
is always applied unless explicitly overridden.
✅ Whitelisting / Blacklisting Filters
Prevent users from filtering on sensitive fields.
protected array $allowedFilters = ['title', 'category'];
protected array $forbiddenFilters = ['created_at'];
✅ Default Values for Filters
Apply fallback filters if no user input is provided:
protected array $defaults = [
'published' => true,
'category' => 'blog'
];
✅ Applied Filters Debugging
Want to inspect which filters were actually used?
$filter = PostFilter::make();
$posts = Post::filterable($filter)->get();
$filter->getAppliedFilters(); // ['title' => 'Laravel']
$filter->getConfiguredFilters(); // All internal rules
🧪 Bonus: Testable Filtering Logic
Because your filter logic is in a dedicated class, you can unit test it independently from the controller.
public function test_title_filter_applies_correctly()
{
Post::factory()->create(['title' => 'Laravel Tips']);
Post::factory()->create(['title' => 'Vue.js Guide']);
$filter = PostFilter::make()->withInput(['title' => 'Laravel']);
$results = Post::filterable($filter)->get();
$this->assertCount(1, $results);
$this->assertEquals('Laravel Tips', $results->first()->title);
}
Clean architecture. Clean tests.
🧰 When Should You Use This?
If your app supports search, filtering, or query customization, this package is a must.
Some perfect use cases:
Admin dashboards
REST APIs with multiple filters
Multi-field search in public websites
Paginated endpoints with sort/filter logic
📦 Ready to Try It?
The package is open-source and actively maintained.
🔗 GitHub: https://github.com/DevYSM/filterable
📄 MIT License
⚙️ PHP 8.0+ | Laravel 8.x+
💬 Final Thoughts
I created YSM/Filterable
to scratch a real itch — filtering was getting messy, repetitive, and hard to maintain. If you feel the same, I invite you to give it a try, and contribute your thoughts or improvements!
Let me know what you think, and feel free to open issues or PRs ❤️
—
Thanks for reading!
If this helped you, consider giving the repo a ⭐ on GitHub and sharing the package with fellow Laravel developers.