Context
Original #370 Phase 2 proposed a generic cascading sub-format facet under any selected Type. Live data audit shows that's not actually warranted: 3 of the 4 Types are effectively monolithic.
| Type |
Sub-format diversity |
| 45s (14,710) |
Real — 4 meaningful sub-types (Singles / Promo / EP / Gold Standard) |
| LPs (4,536) |
95% in LPs: 10/12-inch; rest is mis-classified 12" Singles (handled by #376 reclassify) |
| Picture Sleeves (1,007) |
99.5% in Picture Sleeves; one straggler |
| 78s (123) |
98% in Singles: 78 rpm; two stragglers |
Conclusion: the only Type where a sub-facet pays for its UI cost is 45s. For the others, the sub-facet would render with one usable checkbox — pure noise.
Proposal
Replace the generic cascading sub-facet with a scoped sub-facet that appears only when 45s is the only active type pill. After #376 cleanup, the meaningful 45s sub-formats are:
| Sub-format |
Count |
| Singles: 7-inch |
13,221 |
| Promotional Singles |
1,147 |
| EPs: 7-inch |
~280 (after merging the "45 rpm" typo) |
| Gold Standard Singles ('447' + 'GB') |
46 |
| Picture Disc Singles |
15 |
A row of 5 sub-pills under the 45s pill, identical pill style to the existing Type/Confidence rows.
Sketch
TYPE [ ✓ 45s 14,710 ] [LPs 4,536] [Picture Sleeves 1,007] [78s 123]
SUB-TYPE [ All ] [Singles 13,221] [Promo 1,147] [EPs 280] [Gold Std 46] [Picture Disc 15]
The sub-pill row is hidden unless record_type_id_in == [45s_id] (single type, == 45s). Multi-select within the row uses a new param like record_format_id_in[].
If user adds another type to the selection (e.g. clicks LPs while 45s is active), the sub-pill row collapses (becomes ambiguous which type it scopes).
For LPs / Picture Sleeves / 78s
Don't surface anything in UI. Use the existing search box for granular queries (promotional, picture disc, etc.). Adding a 1-checkbox cascade is worse than no cascade.
Implementation notes
- New param:
record_format_id_in[] (Ransack array, matches public/admin patterns)
- Controller:
records.where(record_format_id: format_ids) when set
- Sub-pill visibility logic: server-side conditional in
_filter_bar.html.erb, no JS needed
- Counts on the sub-pills should be live (after applying other filters) for usefulness — same query pattern as the Type pills
- Apply on both
/records (public) and /admin/records (admin) — shared component if practical
Gating
Blocked on #376 (data cleanup). Without cleanup, the sub-pills row would still show typo dups (EPs: 7-inch and EPs: 7-inch 45 rpm as separate options) — defeats the purpose.
Out of scope
- Cascading sub-facets for other Types (intentionally not built; see analysis above)
- Search-as-you-type for sub-formats (orthogonal idea, not blocked by this)
- Schema changes (sub-format relationship is already correct)
Context
Original #370 Phase 2 proposed a generic cascading sub-format facet under any selected Type. Live data audit shows that's not actually warranted: 3 of the 4 Types are effectively monolithic.
LPs: 10/12-inch; rest is mis-classified 12" Singles (handled by #376 reclassify)Picture Sleeves; one stragglerSingles: 78 rpm; two stragglersConclusion: the only Type where a sub-facet pays for its UI cost is 45s. For the others, the sub-facet would render with one usable checkbox — pure noise.
Proposal
Replace the generic cascading sub-facet with a scoped sub-facet that appears only when 45s is the only active type pill. After #376 cleanup, the meaningful 45s sub-formats are:
A row of 5 sub-pills under the 45s pill, identical pill style to the existing Type/Confidence rows.
Sketch
The sub-pill row is hidden unless
record_type_id_in == [45s_id](single type, == 45s). Multi-select within the row uses a new param likerecord_format_id_in[].If user adds another type to the selection (e.g. clicks LPs while 45s is active), the sub-pill row collapses (becomes ambiguous which type it scopes).
For LPs / Picture Sleeves / 78s
Don't surface anything in UI. Use the existing search box for granular queries (
promotional,picture disc, etc.). Adding a 1-checkbox cascade is worse than no cascade.Implementation notes
record_format_id_in[](Ransack array, matches public/admin patterns)records.where(record_format_id: format_ids)when set_filter_bar.html.erb, no JS needed/records(public) and/admin/records(admin) — shared component if practicalGating
Blocked on #376 (data cleanup). Without cleanup, the sub-pills row would still show typo dups (
EPs: 7-inchandEPs: 7-inch 45 rpmas separate options) — defeats the purpose.Out of scope