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

Filterable Laravel Package

kettasoft/filterable

Filterable brings clean, request-driven filtering to Laravel Eloquent models. Define reusable filter classes, apply them to any query with a simple trait, and support search, sorting, and custom filters without bloating your controllers. Lightweight and easy to extend.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require kettasoft/filterable and publish the config (php artisan vendor:publish --tag=filterable-config) so the engine choice, mode, and allowed fields are visible in config/filterable.php.
  • Add the package trait to the models you want to filter, then define the whitelist of filterable fields and permitted operators there. Treat that list as the contract with your front end.
  • Look first at: the config file (engine + strict/permissive mode), the trait on your model (field/operator whitelist), and the Tree payload schema in the docs. Those three determine almost all day-to-day behavior.
  • First use case: a controller that accepts a Tree payload from a query-builder UI, hands it to the model's filter scope, and returns a paginated result set. Validate and whitelist in a FormRequest before the payload ever reaches the engine.

Implementation Patterns

  • Pick the engine per endpoint. Use the linear style for cheap, predictable filters (?filter[status]=active&filter[created_at][gte]=...) and the Tree engine only where the UI actually exposes nested groups. Don't pay Tree's complexity for a status dropdown.
  • Mirror UI nesting 1:1. Since v3.0.1, each group's own and/or boolean governs only its direct children, and nested groups keep their boundaries during recursive construction. This means a saved query-builder state can be serialized straight into a Tree payload without flattening or re-writing booleans — the mapping is now faithful.
  • Validate, then filter. In a FormRequest: assert group nodes have a boolean key, leaf nodes have field/operator/value, and field/operator are in the model's whitelist. Reject unknown keys rather than letting them be silently ignored.
  • Choose mode deliberately. Strict mode for internal/admin APIs — malformed leaves fail loudly and you catch client bugs early. Permissive mode for public search endpoints, where v3.0.1 now drops rejected leaves while keeping valid conditions in the same group, so one bad clause doesn't nuke the whole request.
  • Saved views / presets. Store the Tree payload as JSON per user and replay it. Because group semantics are now stable, a stored payload behaves the same after upgrade — good candidate for a regression fixture.
  • Keep filtering separate from sorting/pagination. Filter payload in the body (or a dedicated query param), sort and page as normal params. Mixing them makes caching and payload validation messy.
  • Test at the payload level, not just the SQL level. Feature tests with factories plus a nested-group fixture (AND parent containing an OR child, and the inverse) catch semantic regressions far better than asserting a toSql() string.

Gotchas and Tips

  • Remove any pre-3.0.1 workarounds. If you were duplicating conditions, flattening nested groups, or manually injecting the intended boolean because groups weren't honoring their declared operator, delete that code and re-verify. Leaving it in will now double-apply logic.
  • Two different booleans. The operator joining a group to its parent is not the same as the group's own and/or for its children. Most confusion around Tree payloads comes from conflating these; v3.0.1 makes the distinction real, so name your payload keys clearly.
  • Empty groups. An empty AND group is vacuously true; an empty OR group is false. Test both — they're the classic source of "filter returns everything" and "filter returns nothing" reports.
  • Permissive mode fails quietly. Rejected leaves simply vanish, which looks like a broken filter to the user. Log or surface dropped leaves (at debug level at minimum) so client-side schema drift is visible.
  • Whitelist is a security boundary. Field names and operators flow into query construction; never interpolate raw request values into column names.
  • Debugging: dump the underlying builder (toSql() + getBindings()) at the point the filter is applied, and cross-check binding order against your group nesting. Turning on the query log for a single request is usually faster than reasoning about the tree.
  • Config cache. After changing engine or mode, run php artisan config:cache (or config:clear locally) — mode changes appear to "not apply" otherwise.
  • Cap nesting depth. Deeply nested groups produce large recursive queries; enforce a max depth in validation.
  • Upgrade is safe. v3.0.1 adds no public APIs and no breaking changes; composer update kettasoft/filterable plus a re-run of your nested-group tests is sufficient. The only behavioral risk is code that depended on the old, incorrect group-join semantics.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager