feat(scopable): delegate filters to declared model scopes - #13
Merged
Conversation
- Filterable::ValueNormalization mirrors AttributeNormalization: one shared home for coercing raw params values, so upcoming filters can reuse it instead of reaching into Equatable
- `scopable :cheaper_than` hands the normalized `filters[<name>]` value to the scope; `togglable :priced` applies a no-argument scope on a strict true value (true/1/'1'/'true') — checkbox semantics, deliberately stricter than ActiveModel::Type::Boolean where any unrecognized string casts to true - the scope name is fixed at declaration time, never derived from the params or from respond_to?; a missing scope or a scope not returning a relation narrows nothing, per the never-raise contract - aliasing and subclass inheritance as in the other DSLs; both filters report through applied_filters; Railtie includes the two concerns - declarations validator gains scope-backed kinds: a declared name whose scope does not exist is reported as an error
📊 Code Quality Report
🔍 16 new reek smells introduced — review below. 🔍 16 new reek smells introduced by this PR
✅ 2 reek smells resolved by this PRThe exact list isn't shown — these smells are gone, that's what matters. 🔍 All 40 reek smells on this PR
📊 Flog complexity breakdown📊 Flay duplication breakdown |
🛡️ Coverage Report: 100.0% (0.0%)
✅ All changes are tested. |
🛡️ RuboCop: 0 offenses (0)
✅ No RuboCop offenses. |
🛡️ Documentation Quality: 100.0% (+0.5%)
✅ Documentation quality above threshold. |
- `?filters[priced]` and `filters[priced]=` now switch the toggle on,
so a hand-written URL does not need an explicit value
- explicit false values ('false', '0' — what Rails' check_box hidden
field submits) and arbitrary strings still narrow nothing, keeping
form-submitted checkboxes correct
- summary and @api tag were missing since #10; yardstick flags it on every PR touching the file, zero measurements fail with the project config now
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Next item from the gem-landscape backlog: expose existing model scopes as filters, in two explicit forms — no arity detection, no
respond_to?-derived whitelist (the anti-patterns the gem review flagged in toschas/active_filterable/filterameter).Changes
scopable :cheaper_than: hands the normalizedfilters[cheaper_than]value to the scope (.cheaper_than(250)); blank or non-scalar values narrow nothing (sharesValueNormalizationwithequatable, extracted here as a sibling ofAttributeNormalization)togglable :priced: a bare key (?filters[priced],filters[priced]=) or a strict true value (true/'true'/1/'1') applies the no-argument scope; explicit false values ('false','0'— what Rails'check_boxhidden field submits) and arbitrary strings narrow nothing. Stricter thanActiveModel::Type::Boolean, where any unrecognized string casts to true — specs lock both the bare-key toggle and this divergencescopable: 'x' maps to unknown scope 'y'scopable max_price: :cheaper_than) and subclass inheritance as in the other DSLs; both filters report throughapplied_filters; Railtie includes the two concerns; README documents everythingHow to Test
bundle exec rakeMovementDetail.filterable(filters: { cheaper_than: 250 })→.cheaper_than(250);filters: { priced: '' }(clé nue) →.priced;filters: { priced: '0' }→ relation intacte