WAIT: Support international addresses with country-driven state field#1855
WAIT: Support international addresses with country-driven state field#1855maebeale wants to merge 1 commit into
Conversation
AWBW now serves people and orgs outside the US, but every address forced a US-state dropdown and required a US state, so international addresses couldn't be entered or registered. Drive the state field off the country instead: - Address forms swap the validated US-state dropdown for a required free-text region input whenever the country isn't the United States (new address-region Stimulus controller; country is a real dropdown via the countries gem). - Address validates state is a recognized US abbreviation only for US addresses (case-insensitive); international addresses just require a value. - Public registration persists the submitted country and keeps the state field free-text so non-US registrants can enter their region; the same model rules reject an invalid US state. - Address#name drops a blank/again-optional region without a stray separator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| # US addresses must use a recognized state abbreviation; international addresses | ||
| # store a free-form region, so they only need a value (presence above). The check | ||
| # is case-insensitive to tolerate legacy lowercase abbreviations (e.g. "tx"). | ||
| validate :state_is_a_us_state, if: :united_states? |
There was a problem hiding this comment.
🤖 From Claude: The US-state check only runs when united_states? (blank/US country). International addresses just need a value, so a region like "Ontario" passes. The check itself is case-insensitive (see state_is_a_us_state) to tolerate legacy lowercase abbreviations the dashboard already normalizes.
| def create_mailing_address(person) | ||
| new_city = field_value("mailing_city")&.strip | ||
| new_state = field_value("mailing_state")&.strip | ||
| new_country = field_value("mailing_country")&.strip.presence |
There was a problem hiding this comment.
🤖 From Claude: The form already collected mailing_country but the service never saved it. That gap is load-bearing now: without a country, an international address defaults to domestic and the new US-state validation would reject the region. Persisting it (also for agency_country) is what lets non-US registrations through.
| class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" %> | ||
| </div> | ||
| <div data-address-region-wrapper class="<%= "hidden" if domestic %>"> | ||
| <%= f.label :state, "State / region", for: f.field_id(:state, :region), |
There was a problem hiding this comment.
🤖 From Claude: Both state inputs bind to the same state attribute, so the inactive one is disabled (not just hidden) — disabled fields do not submit, so exactly one value posts. Initial visibility is server-rendered from the stored country so there is no flash before the Stimulus controller connects.
|
This pull request has been inactive for 30 days. Please update it or let us know if it is still relevant. |
What is the goal of this PR and why is this important?
How did you approach the change?
countryis now a real dropdown (via thecountriesgem, defaulting to United States). A newaddress-regionStimulus controller shows a validated US-state dropdown when the country is the US, and swaps to a required free-text region input otherwise. Only the active input is enabled, so exactly one value submits.Addressrequires a state, but only enforces a recognized US abbreviation (case-insensitive, to tolerate legacy lowercase) when the country is the US; international addresses just need a value.Address#namedrops a blank region without leaving a stray separator.UsStatemodule used by both the dropdown and the validation, so options and accepted values can't drift.mailing_country/agency_country, and the public state field is free-text (US states offered as datalist suggestions) so non-US registrants can enter their region. The same model rules reject an invalid US state.UI Testing Checklist
Anything else to add?
EventDashboard) is unchanged: it still buckets recognized US abbreviations into the States map, leaving international regions for the Countries map.address-regioncontroller is scoped per address block, so cocoon-added addresses work too.🤖 Generated with Claude Code