You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Alphabetize Product Drive Participant dropdown in new-donation form #5593
... do a survey of all the drop-downs of product drive participants and alphabetize them all
Why change?
Not having an alphabetized list everywhere makes more work for the user to find what they're looking for in lists
Steps to replicate
survey the codebase to locate drop down lists
identify lists that should be human alphabetical
ask Human Essential in a comment if you're unsure about which lists are in scope
Criteria for completion / testing needs
for any list that is in scope for human alphabetization - which means that 1 comes before 9 and 10 comes after 9, or A comes before B and C comes after B – update the list to be alphabetical
if tests fail, update the test fixture to represent the new alphabetical order
Hi I would love to get involved with the project and this seems like a good place for me to start. I am a new dev having completed a bootcamp based in Rails and want to contribute to open source projects that do good. Could you please assign this issue to me? I’m forking the repository now to set it up locally and dive into the code.
I'm happy to get a PR request up tomorrow regardless as I'd like to get involved at some point and seems like a good problem to get to grips with the project
Hi! I'd like to pick this one up if it's still free — looks like the bot unassigned it on Aug 4.
Two scope questions before I start, so I don't guess wrong:
The summary names the New donation and Donation filter dropdowns, and the third bullet asks for a survey of "all the drop-downs of product drive participants". Should I keep this to Product Drive Participant dropdowns specifically, or is the intent to cover every dropdown in the app that should be alphabetized?
On the definition in the completion criteria — "1 comes before 9 and 10 comes after 9" — that's a natural sort rather than a plain string sort, which would put 10 before 9. Is natural ordering wanted anywhere a list has numeric entries, or is it only relevant for particular lists you have in mind?
Happy to start with the Product Drive Participant dropdowns and expand from there if you'd rather review it in smaller pieces.
@pcbeingused333 I'd say to start by a) fixing the ones we know about and b) making a survey of the ones we don't. The results of that can inform a further ticket where we decide which of them to fix.
AFAIK we'll want everything the user sees to be natural-sorted unless the drop-down shows nothing but numbers (maybe a day of the month?).
Thanks @dorner — that's clear. PR for the Product Drive Participant drop-downs is up #5656, and here's the survey of everything else.
Method. Grepped app/views for everything that renders a <select> — f.association, f.input/input_field with a collection:, collection_select, options_from_collection_for_select, select_tag + options_for_select, and the filter_select helper — then traced each collection back to the controller or view model that builds it. Radio buttons and render partial: ..., collection: are excluded; one check-box list is listed at the end because it has the same problem.
1. Not ordered at all — the user gets database order
What the user sees
View
Where the collection is built
Manufacturer, after adding one from the modal
app/views/manufacturers/create.js.erb:5
inline current_organization.manufacturers — the alphabetized scope exists, it just isn't used
Product drive, after adding one from the modal
app/views/product_drives/create.js.erb:5
inline current_organization.product_drives
Vendor, after adding one from the modal
app/views/vendors/create.js.erb:5
inline current_organization.vendors
Events → Filter by storage location
app/views/events/index.html.erb:49
inline current_organization.storage_locations
New / Edit item → Category
app/views/items/_form.html.erb:18
items_controller#new:55, #edit:60. #index:13 and the failed-create re-render at :47 do order('name ASC'), so the same drop-down is sorted or not depending on how you reached it
New / Edit partner → Partner group
app/views/partners/_form.html.erb:28
partners_controller:89, :94
Adjustments → Filter by user
app/views/adjustments/index.html.erb:40
adjustments_controller:18
New / Edit adjustment → Storage location
app/views/storage_locations/_source.html.erb:9
adjustments_controller:36, :57 (.active, no ordering)
New audit → Storage location
app/views/audits/_form.html.erb:17, same partial
audits_controller:103
Kit allocation → Storage location
app/views/kits/allocations.html.erb:81
kits_controller:60
Purchases → Filter by storage location
app/views/purchases/index.html.erb:41
purchases_controller:27
Purchases → Filter by category
app/views/purchases/index.html.erb:53
purchases_controller:12 (pluck(:name).uniq)
Distributions → Filter by item category
app/views/distributions/index.html.erb:46
distributions_controller:56
NDBN member (account request form, organization edit)
f.association with no scope, and NdbnMember has no default order
Organization edit → custom request units (behind enable_packs)
app/views/organizations/edit.html.erb:134
inline current_organization.request_units
The first three are the same defect the PR fixes for participants: create.js.erb rebuilds the drop-down after the modal without the ordering scope, so the list loses its order as soon as you add a record. Those three are one-line fixes.
2. Sorted by primary key, which reads as random
View::Donations builds two filters on the same screen as this issue's second screenshot by calling .sort on ActiveRecord objects. ActiveRecord::Core#<=> compares to_key, so these come out ordered by id:
Donations → Filter by Storage Location — app/models/view/donations.rb:44
Donations → Filter by manufacturer — app/models/view/donations.rb:46
donation_sites, built ten lines below at :57, gets it right with sort_by { |site| site.name.downcase }.
3. Sorted by name, but case-sensitively and not naturally
Everything on an alphabetized scope — i.e. order(:name): partners, vendors, storage locations, items, item categories, base items, product drives, donation sites, manufacturers, tags, users — plus the Ruby-side sort_by(&:name) in events_controller:16, StorageLocation.items_inventoried (app/models/storage_location.rb:81) and PartnerFetchRequestableItemsService (the partner portal's item drop-down).
Two consequences:
Case.ORDER BY name uses the database collation, which is not the same everywhere. My dev and test clusters are C.UTF-8, where every capitalised name sorts before every lowercase one — "Zebra Foods" above "apple st. depot". The postgres:12.3 image CI runs is initialised with en_US.utf8, where it isn't. Same code, different list, and a test that pins the order can pass in CI and be wrong for a user. Ruby's sort_by(&:name) is always byte order, so it's capitals-first everywhere.
Numbers. None of them are natural: "Item 10" sorts before "Item 9".
Neither shows up in a list of ordinary capitalised names, which is probably why this has gone unnoticed — it appears as soon as an organisation names things "Site 9 / Site 10" or types a name in lowercase.
4. Deliberately not alphabetical — I'd leave these alone
Numbers only: client share 1..100 (served_areas/_served_area_fields.html.erb:11), the deadline-day and day-of-week selects (shared/_deadline_day_fields.html.erb).
Workflow order: distribution status, request status, request type.
Fixed domain lists where the order carries meaning: donation source, gender, race, insurance type, warehouse type, agency type, NDBN reporting category (enum order), time zones (by offset), US states (already alphabetical).
Counties (County.in_category_name_order): grouped by category, then by name. Intentional.
5. Not a drop-down, same problem
app/views/partner_groups/_form.html.erb:20 renders item categories as a check-box list from partner_groups_controller:7, :26, :67 — unordered.
Suggestion for the follow-up ticket
Sections 1 and 2 are straightforward, low-risk fixes and could be a single "beginner" ticket, or split bank-side / partner-side.
Section 3 is the one worth a decision, because it's one change applied in ~12 places. The PR adds NaturallySortable.natural_order, a SQL ORDER BY expression that lowercases and zero-pads digit runs, so the ordering is natural and identical regardless of the cluster's collation. I built it as an expression rather than a Postgres function or an ICU collation on purpose: the schema is maintained as schema.rb, which doesn't carry functions or collations, so either of those would vanish on db:schema:load. If you'd rather not have that SQL in the codebase, the alternative is structure.sql plus a natural_sort_key() function — cleaner call sites, bigger change. Happy to do either, or to leave section 3 alone if it's not worth the churn.
Hi @StephanieFarid@dorner — flagging this rather than asserting it, since I may well be misreading the scope.
#5684 natural-sorts @product_drives_alphabetical in product_drives_controller#index, which builds the Product Drive name filter (it sorts on pd.name). The two drop-downs this issue names are Product Drive Participant ones, and as far as I can tell they are unchanged on main:
app/views/donations/_donation_form.html.erb — new donation, still label_method: lambda { |x| "#{x.try(:business_name).presence || x.try(:contact_name)}" }
app/views/donations/index.html.erb — donation filter, still value: :business_name
The ordering is the part that bites: the drop-downs display business_name but alphabetized orders by contact_name, so a participant whose business name starts with "A" but whose contact starts with "Z" still lands at the bottom. Adding a participant named "Aardvark Supplies" with contact "zoe" should reproduce it.
#5656 covers those two plus the create.js.erb modal that rebuilds the list after a participant is created, ordering on the displayed name with digit runs compared by value, per @dorner's natural-sort note above. Its checks currently show an Aug 14 run because the workflows on my latest push are sitting in action_required — the brakeman failure visible there is already fixed on the branch.
Also worth knowing: #5616 is open against this issue too, so there are three PRs in flight.
Genuinely happy either way — reopen and review #5656, have me rework it, or close it if you would rather someone else take the participant drop-downs. Just did not want the remaining half to disappear quietly behind a closed issue.
Activity
meamalpb commentedon Jun 16, 2026
Can I try this?
tonleikar commentedon Jun 17, 2026
Hi I would love to get involved with the project and this seems like a good place for me to start. I am a new dev having completed a bootcamp based in Rails and want to contribute to open source projects that do good. Could you please assign this issue to me? I’m forking the repository now to set it up locally and dive into the code.
dorner commentedon Jun 19, 2026
Sorry @tonleikar - @meamalpb did ask to be assigned it before you. You can ask them if you want it instead (there's no PR up yet from either of you).
tonleikar commentedon Jun 21, 2026
I'm happy to get a PR request up tomorrow regardless as I'd like to get involved at some point and seems like a good problem to get to grips with the project
meamalpb commentedon Jun 21, 2026
Hi @tonleikar, I'm happy for you to take this issue if you'd like. I haven't started working on it yet, so feel free to put up a PR.
@dorner, could you please reassign the issue to @tonleikar when you get a chance? Thanks!
tonleikar commentedon Jun 21, 2026
Hi @meamalpb thats kind thank you!
github-actions commentedon Jul 27, 2026
This issue is marked as stale due to no activity within 30 days. If no further activity is detected within 7 days, it will be unassigned.
github-actions commentedon Aug 4, 2026
Automatically unassigned after 7 days of inactivity.
pcbeingused333 commentedon Aug 10, 2026
Hi! I'd like to pick this one up if it's still free — looks like the bot unassigned it on Aug 4.
Two scope questions before I start, so I don't guess wrong:
The summary names the New donation and Donation filter dropdowns, and the third bullet asks for a survey of "all the drop-downs of product drive participants". Should I keep this to Product Drive Participant dropdowns specifically, or is the intent to cover every dropdown in the app that should be alphabetized?
On the definition in the completion criteria — "1 comes before 9 and 10 comes after 9" — that's a natural sort rather than a plain string sort, which would put 10 before 9. Is natural ordering wanted anywhere a list has numeric entries, or is it only relevant for particular lists you have in mind?
Happy to start with the Product Drive Participant dropdowns and expand from there if you'd rather review it in smaller pieces.
dorner commentedon Aug 14, 2026
@pcbeingused333 I'd say to start by a) fixing the ones we know about and b) making a survey of the ones we don't. The results of that can inform a further ticket where we decide which of them to fix.
AFAIK we'll want everything the user sees to be natural-sorted unless the drop-down shows nothing but numbers (maybe a day of the month?).
pcbeingused333 commentedon Aug 14, 2026
Thanks @dorner — that's clear. PR for the Product Drive Participant drop-downs is up #5656, and here's the survey of everything else.
Method. Grepped
app/viewsfor everything that renders a<select>—f.association,f.input/input_fieldwith acollection:,collection_select,options_from_collection_for_select,select_tag+options_for_select, and thefilter_selecthelper — then traced each collection back to the controller or view model that builds it. Radio buttons andrender partial: ..., collection:are excluded; one check-box list is listed at the end because it has the same problem.1. Not ordered at all — the user gets database order
app/views/manufacturers/create.js.erb:5current_organization.manufacturers— thealphabetizedscope exists, it just isn't usedapp/views/product_drives/create.js.erb:5current_organization.product_drivesapp/views/vendors/create.js.erb:5current_organization.vendorsapp/views/events/index.html.erb:49current_organization.storage_locationsapp/views/items/_form.html.erb:18items_controller#new:55,#edit:60.#index:13and the failed-create re-render at:47doorder('name ASC'), so the same drop-down is sorted or not depending on how you reached itapp/views/partners/_form.html.erb:28partners_controller:89,:94app/views/adjustments/index.html.erb:40adjustments_controller:18app/views/storage_locations/_source.html.erb:9adjustments_controller:36,:57(.active, no ordering)app/views/audits/_form.html.erb:17, same partialaudits_controller:103app/views/kits/allocations.html.erb:81kits_controller:60app/views/purchases/index.html.erb:41purchases_controller:27app/views/purchases/index.html.erb:53purchases_controller:12(pluck(:name).uniq)app/views/distributions/index.html.erb:46distributions_controller:56app/views/account_requests/new.html.erb:64,app/views/organizations/edit.html.erb:67f.associationwith no scope, andNdbnMemberhas no default orderenable_packs)app/views/organizations/edit.html.erb:134current_organization.request_unitsThe first three are the same defect the PR fixes for participants:
create.js.erbrebuilds the drop-down after the modal without the ordering scope, so the list loses its order as soon as you add a record. Those three are one-line fixes.2. Sorted by primary key, which reads as random
View::Donationsbuilds two filters on the same screen as this issue's second screenshot by calling.sorton ActiveRecord objects.ActiveRecord::Core#<=>comparesto_key, so these come out ordered byid:app/models/view/donations.rb:44app/models/view/donations.rb:46donation_sites, built ten lines below at:57, gets it right withsort_by { |site| site.name.downcase }.3. Sorted by name, but case-sensitively and not naturally
Everything on an
alphabetizedscope — i.e.order(:name): partners, vendors, storage locations, items, item categories, base items, product drives, donation sites, manufacturers, tags, users — plus the Ruby-sidesort_by(&:name)inevents_controller:16,StorageLocation.items_inventoried(app/models/storage_location.rb:81) andPartnerFetchRequestableItemsService(the partner portal's item drop-down).Two consequences:
ORDER BY nameuses the database collation, which is not the same everywhere. My dev and test clusters areC.UTF-8, where every capitalised name sorts before every lowercase one — "Zebra Foods" above "apple st. depot". Thepostgres:12.3image CI runs is initialised withen_US.utf8, where it isn't. Same code, different list, and a test that pins the order can pass in CI and be wrong for a user. Ruby'ssort_by(&:name)is always byte order, so it's capitals-first everywhere.Neither shows up in a list of ordinary capitalised names, which is probably why this has gone unnoticed — it appears as soon as an organisation names things "Site 9 / Site 10" or types a name in lowercase.
4. Deliberately not alphabetical — I'd leave these alone
1..100(served_areas/_served_area_fields.html.erb:11), the deadline-day and day-of-week selects (shared/_deadline_day_fields.html.erb).County.in_category_name_order): grouped by category, then by name. Intentional.5. Not a drop-down, same problem
app/views/partner_groups/_form.html.erb:20renders item categories as a check-box list frompartner_groups_controller:7,:26,:67— unordered.Suggestion for the follow-up ticket
Sections 1 and 2 are straightforward, low-risk fixes and could be a single "beginner" ticket, or split bank-side / partner-side.
Section 3 is the one worth a decision, because it's one change applied in ~12 places. The PR adds
NaturallySortable.natural_order, a SQL ORDER BY expression that lowercases and zero-pads digit runs, so the ordering is natural and identical regardless of the cluster's collation. I built it as an expression rather than a Postgres function or an ICU collation on purpose: the schema is maintained asschema.rb, which doesn't carry functions or collations, so either of those would vanish ondb:schema:load. If you'd rather not have that SQL in the codebase, the alternative isstructure.sqlplus anatural_sort_key()function — cleaner call sites, bigger change. Happy to do either, or to leave section 3 alone if it's not worth the churn.StephanieFarid commentedon Aug 28, 2026
I got this!
pcbeingused333 commentedon Aug 29, 2026
Hi @StephanieFarid @dorner — flagging this rather than asserting it, since I may well be misreading the scope.
#5684 natural-sorts
@product_drives_alphabeticalinproduct_drives_controller#index, which builds the Product Drive name filter (it sorts onpd.name). The two drop-downs this issue names are Product Drive Participant ones, and as far as I can tell they are unchanged onmain:app/models/product_drive_participant.rb—scope :alphabetized, -> { order(:contact_name) }app/views/donations/_donation_form.html.erb— new donation, stilllabel_method: lambda { |x| "#{x.try(:business_name).presence || x.try(:contact_name)}" }app/views/donations/index.html.erb— donation filter, stillvalue: :business_nameThe ordering is the part that bites: the drop-downs display
business_namebutalphabetizedorders bycontact_name, so a participant whose business name starts with "A" but whose contact starts with "Z" still lands at the bottom. Adding a participant named "Aardvark Supplies" with contact "zoe" should reproduce it.#5656 covers those two plus the
create.js.erbmodal that rebuilds the list after a participant is created, ordering on the displayed name with digit runs compared by value, per @dorner's natural-sort note above. Its checks currently show an Aug 14 run because the workflows on my latest push are sitting inaction_required— the brakeman failure visible there is already fixed on the branch.Also worth knowing: #5616 is open against this issue too, so there are three PRs in flight.
Genuinely happy either way — reopen and review #5656, have me rework it, or close it if you would rather someone else take the participant drop-downs. Just did not want the remaining half to disappear quietly behind a closed issue.
Merge pull request #5656 from pcbeingused333/5593-alphabetize-partici…