feat(attachable): add ActiveStorage pre-filtering sugar - #17
Merged
Conversation
- `attachable :document` exposes normed keys under `filters[<name>]`: `present` (strict true or bare key keeps attached records, explicit false keeps unattached ones — absence was inexpressible with the INNER JOIN paths), `type` (blob content type, = or IN), `min_size`/`max_size` (inclusive blob byte size bounds) - everything resolves through the associations has_one_attached / has_many_attached generate — Rails' documented contract — so the gem still never references ActiveStorage; a name without those associations narrows nothing and the validator reports it - presence uses where.associated / where.missing (public AR API) with DISTINCT on has_many_attached; type and sizes delegate to the existing Target machinery; applied_filters reports the accepted raw keys grouped per public name - present follows the togglable semantics: nil/'' (bare key) toggle attached, 'garbage' is a no-op
🛡️ Documentation Quality: 100.0% (0.0%)
✅ Documentation quality above threshold. Changed files
|
📊 Code Quality Report
🔍 16 new reek smells introduced — review below. 🔍 16 new reek smells introduced by this PR
🔍 All 75 reek smells on this PR
📊 Flog complexity breakdown📊 Flay duplication breakdown |
🛡️ Coverage Report: 100.0% (0.0%)
✅ All changes are tested. Changed files
|
🛡️ RuboCop: 0 offenses (0)
✅ No RuboCop offenses. |
…stry - legitimacy now comes from ActiveStorage's own public reflection API (reflect_on_attachment / attachment_reflections) instead of probing the generated association name shapes; singular/plural derives from the reflection macro - fixes a false positive: an ordinary association that happens to be called <name>_attachment no longer qualifies as an attachment — proven by a spec that failed against the name-shape probing - the generated names are still used to build the join (that is the documented contract has_one_attached publishes), but never to decide whether something is an attachment
- the blob association name came from a regex on the attachment association string; both names now derive from the attachment reflection's macro through a single attachment_reflection helper — the last name-shape logic is gone
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
The dedicated ActiveStorage options discussed after #16:
attachable :documentexposes the normed attachment filters under one public name, instead of manual association paths — and adds a capability paths cannot express: attachment absence.Changes
attachable :document(aliasattachable file: :document), eighth declaration DSL, reading nested keys underfilters[<name>]:present— strict true or bare key keeps attached records (where.associated), explicit false ('false'/'0') keeps unattached ones (where.missing); same semantics astogglable(nil/''toggle on),'garbage'is a no-optype— blob content type, scalar=or arrayINmin_size/max_size— inclusive blob byte size boundsreflect_on_attachment), looked up at runtime — an ordinary association coincidentally named<name>_attachmentdoes not qualify (spec-proven); the generated association names (<name>_attachment(s)/<name>_blob(s), the documentedhas_one_attachedcontract) are only used to build the join, with singular/plural derived from the reflection macrotype/sizes delegate to the existingTargetmachinery (joins+merge+DISTINCT)attachable: 'x' maps to unknown attachment 'y'); non-hash values dropped as usualapplied_filtersreports the accepted raw keys grouped per public name; Railtie includes the concern; README documents the DSL (167 examples, 100% coverage)How to Test
bundle exec rakeContract.filterable(filters: { document: { present: 'false' } })→ contrats sans pièce jointe ;{ document: { type: 'application/pdf', min_size: 1000 } }→ jointure blobs + bornes ;?filters[document][present](clé nue) → pièces jointes présentes