Alphabetize the Product Drive Participant drop-downs (#5593) - #5656
Open
pcbeingused333 wants to merge 1 commit into
Open
Alphabetize the Product Drive Participant drop-downs (#5593)#5656pcbeingused333 wants to merge 1 commit into
pcbeingused333 wants to merge 1 commit into
Conversation
The `alphabetized` scope ordered by `contact_name`, but every dropdown shows `business_name` and only falls back to `contact_name` when it is blank, so the lists were sorted on a column the user cannot see. Sorting on the displayed name is not enough on its own. `ORDER BY name` uses the database collation, which differs between environments: a `C.UTF-8` cluster puts every capitalised name before every lowercase one, while the `postgres:12.3` image CI runs is initialised with `en_US.utf8` and does not. Plain text ordering also puts "Store 10" before "Store 9". `NaturallySortable.natural_order` builds an ORDER BY expression that lowercases the value and zero-pads runs of digits, so the ordering is case-insensitive and natural whatever the cluster's collation is. It is an expression rather than a Postgres function or an ICU collation because the schema is maintained as `schema.rb`, which carries neither. `create.js.erb` rebuilt the dropdown without the scope at all, so the list lost its order as soon as a participant was added from the modal. It now reuses `display_name`, which is also what the donation form and the donation filter label the options with, so the sort key and the label can no longer drift apart. The donation filter previously labelled options with `business_name` alone, leaving participants who only have a contact name as blank entries. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Part of #5593 — the two drop-downs named in the issue. The survey of every other drop-down in the app is posted as a comment on the issue, per @dorner's suggestion that its results inform a separate ticket.
What was wrong
ProductDriveParticipant.alphabetizedordered bycontact_name, but every drop-down showsbusiness_nameand only falls back tocontact_namewhen it is blank — so the lists were sorted on a column the user cannot see.Sorting on the displayed name isn't enough on its own:
ORDER BY nameuses the database collation, which is not the same everywhere. AC.UTF-8cluster (whatbin/setupgave me for dev and test) puts every capitalised name before every lowercase one; thepostgres:12.3image CI runs is initialised withen_US.utf8and doesn't. Same code, different list — and a test that pins the order can pass in CI while the user sees something else.product_drive_participants/create.js.erbrebuilt the drop-down without the ordering scope at all, so the new-donation list lost its order as soon as a participant was added from the modal.The donation filter labelled its options with
business_namealone, so participants who only have a contact name showed up as blank entries.What changed
NaturallySortable.natural_orderbuilds an ORDER BY expression that lowercases the value and zero-pads runs of digits, so ordering is case-insensitive and natural regardless of the cluster's collation. It's an expression rather than a Postgres function or an ICU collation on purpose: the schema is maintained asschema.rb, which carries neither, so both would disappear ondb:schema:load.alphabetizednow sorts onCOALESCE(NULLIF(business_name, ''), contact_name)— the value the user actually reads — through that expression.create.js.erbuses the scope again, and all three places label options with the existingdisplay_namemethod, so the sort key and the label can't drift apart.Verified
bundle exec rspec spec/models/product_drive_participant_spec.rb spec/requests/donations_requests_spec.rb spec/requests/product_drive_participants_requests_spec.rb spec/system/donation_system_spec.rb spec/system/product_drive_participant_system_spec.rb, rubocop and erb_lint all pass locally.