Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions app/models/form_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ class FormField < ApplicationRecord
# "required" flag is meaningless for them (nothing to fill in).
NON_INPUT_ANSWER_TYPES = %w[no_user_input group_header].freeze

# Multi-select "additional sectors" field identifiers. "additional_sectors" is
# the canonical name new forms are built with; the older "primary_sector" name
# (a misnomer β€” it was always the multi-select additional field) and the legacy
# "service area" name are both still accepted so existing form data keeps
# resolving.
ADDITIONAL_SECTOR_FIELD_IDENTIFIERS = %w[additional_sectors primary_sector primary_service_area].freeze

# Single-select "primary sector" field identifiers (current + legacy). Unlike
# the multi-select "additional" field, these omit the catch-all "Other" sector
# β€” a respondent's primary sector must be a concrete sector.
PRIMARY_SECTOR_FIELD_IDENTIFIERS = %w[primary_sector_single primary_service_area_single].freeze
# Multi-select "additional sectors" field identifier.
ADDITIONAL_SECTOR_FIELD_IDENTIFIERS = %w[additional_sectors].freeze

# Single-select "primary sector" field identifier. Unlike the multi-select
# "additional" field, it omits the catch-all "Other" sector β€” a respondent's
# primary sector must be a concrete sector.
PRIMARY_SECTOR_FIELD_IDENTIFIERS = %w[primary_sector].freeze

# Field identifiers whose selectable options are sourced dynamically from
# Sector records rather than the field's own stored answer options. The
Expand Down Expand Up @@ -91,7 +87,7 @@ class FormField < ApplicationRecord
# Keeps an over-long name as a friendly validation error instead of a
# database ValueTooLong exception (the column is text, this is the UX cap).
validates :name, length: { maximum: 1000 }
# A field_identifier wires a field to backend logic (Stripe, service areas,
# A field_identifier wires a field to backend logic (Stripe, sectors,
# email checks, etc.), so the same identifier must not appear twice on one form
# or that logic would target an ambiguous field. Ordinary fields carry no
# identifier, so blanks are exempt β€” any number of them may coexist.
Expand Down
4 changes: 2 additions & 2 deletions app/services/form_builder_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def call
agency_street agency_city agency_state agency_zip agency_country
],
person_background: %w[racial_ethnic_identity],
professional_info: %w[primary_sector_single additional_sectors primary_age_group additional_age_group],
professional_info: %w[primary_sector additional_sectors primary_age_group additional_age_group],
marketing: %w[referral_source training_motivation interested_in_more],
continuing_education: %w[ce_credit_interest ce_license_number],
scholarship: %w[scholarship_eligibility scholarship_contribution impact_description implementation_plan additional_comments],
Expand Down Expand Up @@ -455,7 +455,7 @@ def build_professional_info_fields(form, position)
position = add_header(form, position, "Professional Information", group: "professional")

position = add_field(form, position, "Primary sector", :single_select_dropdown,
key: "primary_sector_single", group: "professional", required: false,
key: "primary_sector", group: "professional", required: false,
subtitle: "Select the option that best represents those you primarily intend to serve through the art workshops")
position = add_field(form, position, "Additional sectors", :multi_select_checkbox,
key: "additional_sectors", group: "professional", required: false,
Expand Down
7 changes: 2 additions & 5 deletions app/services/smart_form_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,10 @@ class SmartFormFields
"records rather than from options typed into the form editor. The tags are applied to " \
"the registrant and to their linked organization.",
fields: [
[ "primary_sector_single", "Primary sector", "Tags the person and organization with one primary sector. Offers no \"Other\" β€” a primary sector must be a real sector." ],
[ "primary_sector", "Primary sector", "Tags the person and organization with one primary sector. Offers no \"Other\" β€” a primary sector must be a real sector." ],
[ "additional_sectors", "Additional sectors", "Tags the person and organization with any number of additional sectors. An \"Other\" answer goes to the Other responses review queue, where it can be promoted into a real sector." ],
[ "primary_age_group", "Primary age group(s) served", "Tags the person and organization with the primary age range served." ],
[ "additional_age_group", "Additional age group(s) served", "Tags the person and organization with additional age ranges served." ],
[ "primary_sector", "Additional sectors (legacy)", "Older name for the additional sectors question. Still honored so existing forms keep working; use additional_sectors on new forms." ],
[ "primary_service_area", "Additional sectors (legacy)", "Older name for the additional sectors question. Still honored; use additional_sectors on new forms." ],
[ "primary_service_area_single", "Primary sector (legacy)", "Older name for the primary sector question. Still honored; use primary_sector_single on new forms." ]
[ "additional_age_group", "Additional age group(s) served", "Tags the person and organization with additional age ranges served." ]
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion app/views/events/public_registrations/_form_field.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
<% end %>

<% when "single_select_dropdown" %>
<%# Dynamic fields (e.g. primary_sector_single) source options from
<%# Dynamic fields (e.g. primary_sector) source options from
Sector/Category data; everything else uses the field's own stored options. %>
<%# Dropdowns have no free-text input, so the "Other" option is omitted here.
Named specify options keep meaning as a bare choice, so they stay. %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/forms/_form_field_fields.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
class: "w-24 shrink-0 rounded border-gray-300 shadow-sm px-2 py-1 text-sm",
title: "Maximum number of characters allowed (free-form text fields only)" %>
<%# Smart field name + Remove stay pinned together so Remove never lands on its own
line. The name wires this field to backend logic (Stripe, service areas, email
line. The name wires this field to backend logic (Stripe, sectors, email
checks, etc.); most fields need none, and the linked hint explains each one. %>
<div class="flex shrink-0 items-center gap-2">
<div class="flex flex-col shrink-0">
Expand Down
2 changes: 1 addition & 1 deletion db/seeds/dev/events_management.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@

# Mirror the registration form's two sector fields: the single-select primary
# sector dropdown and the multi-select additional sectors checkboxes.
primary_field = form.form_fields.find_by(field_identifier: "primary_sector_single")
primary_field = form.form_fields.find_by(field_identifier: "primary_sector")
if primary_field && primary_sector && submission.form_answers.where(form_field: primary_field).none?
submission.form_answers.create!(form_field: primary_field,
submitted_answer: primary_sector.id.to_s,
Expand Down
96 changes: 0 additions & 96 deletions db/seeds/dev/legacy_form_identifiers.rb

This file was deleted.

6 changes: 0 additions & 6 deletions lib/tasks/dev.rake
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ namespace :db do
scholarships
membership
bulk_payments
legacy_form_identifiers
public_forms
]

Expand Down Expand Up @@ -125,11 +124,6 @@ namespace :db do
load Rails.root.join("db/seeds/dev/bulk_payments.rb")
end

desc "Seed registration forms using legacy professional-field identifiers (dev only)"
task legacy_form_identifiers: :environment do
load Rails.root.join("db/seeds/dev/legacy_form_identifiers.rb")
end

desc "Seed standalone public forms with submissions and answers (dev only)"
task public_forms: :environment do
load Rails.root.join("db/seeds/dev/public_forms.rb")
Expand Down
10 changes: 5 additions & 5 deletions spec/helpers/application_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -587,19 +587,19 @@
describe "#dynamic_form_field_options" do
let(:form) { create(:form) }

it "omits the Other sector for the primary service-area dropdown" do
it "omits the Other sector for the primary sector dropdown" do
create(:sector, :published, name: "Domestic Violence")
create(:sector, :published, name: "Other")
field = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_service_area_single")
field = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_sector")

labels = helper.dynamic_form_field_options(field).map(&:first)
expect(labels).to include("Domestic Violence")
expect(labels).not_to include("Other")
end

it "includes the Other sector for the additional service-areas field" do
it "includes the Other sector for the additional sectors field" do
create(:sector, :published, name: "Other")
field = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "primary_service_area")
field = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "additional_sectors")

labels = helper.dynamic_form_field_options(field).map(&:first)
expect(labels).to include("Other")
Expand All @@ -608,7 +608,7 @@
it "carries each sector's description as the third tuple element" do
create(:sector, :published, name: "Domestic Violence", description: "DV services")
create(:sector, :published, name: "Mental Health", description: nil)
field = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "primary_service_area")
field = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "additional_sectors")

descriptions = helper.dynamic_form_field_options(field).to_h { |name, _id, desc| [ name, desc ] }
expect(descriptions["Domestic Violence"]).to eq("DV services")
Expand Down
29 changes: 10 additions & 19 deletions spec/models/form_field_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ def selectable_field(type:, option_names:)
end

context "with dynamically-sourced options" do
it "accepts a published Sector id and rejects others for a service-area field" do
field = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_service_area_single")
it "accepts a published Sector id and rejects others for a primary sector field" do
field = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_sector")
offered = create(:sector, :published)
unpublished = create(:sector, :unpublished)

Expand All @@ -451,22 +451,13 @@ def selectable_field(type:, option_names:)
expect(field.answer_inclusion_error("999999")).to eq("has an invalid selection")
end

# The canonical identifiers, the legacy "primary_sector" additional name,
# and the legacy "service area" names must all behave identically so
# existing form data keeps resolving.
{
"sector" => %w[primary_sector_single additional_sectors],
"sector (legacy additional name)" => %w[primary_sector_single primary_sector],
"service area (legacy)" => %w[primary_service_area_single primary_service_area]
}.each do |scheme, (primary_id, additional_id)|
it "rejects the Other sector for the primary #{scheme} field but accepts it for additional" do
other = create(:sector, :published, name: "Other")
primary = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: primary_id)
additional = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: additional_id)

expect(primary.answer_inclusion_error(other.id.to_s)).to eq("has an invalid selection")
expect(additional.answer_inclusion_error([ other.id.to_s ])).to be_nil
end
it "rejects the Other sector for the primary sector field but accepts it for additional" do
other = create(:sector, :published, name: "Other")
primary = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_sector")
additional = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "additional_sectors")

expect(primary.answer_inclusion_error(other.id.to_s)).to eq("has an invalid selection")
expect(additional.answer_inclusion_error([ other.id.to_s ])).to be_nil
end

it "accepts a published Category id from the backing type for a category field" do
Expand Down Expand Up @@ -498,7 +489,7 @@ def selectable_field(type:, option_names:)
create(:sector, :published, name: "Other")
mental_health = create(:sector, :published, name: "Mental Health")
additional = create(:form_field, form: form, answer_type: :multi_select_checkbox, field_identifier: "additional_sectors")
primary = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_sector_single")
primary = create(:form_field, form: form, answer_type: :single_select_dropdown, field_identifier: "primary_sector")

# The "Other" Sector renders a free-text box on the additional checkboxes,
# which submits the folded "Other: <text>" (or a bare "Other"); both pass.
Expand Down
4 changes: 2 additions & 2 deletions spec/models/person_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,8 @@ def answer(identifier, value)
.to contain_exactly("Toddlers")
end

it "does not pull from the service area fields" do
answer("primary_service_area", "Other: Equine therapy")
it "does not pull from the sector fields" do
answer("additional_sectors", "Other: Equine therapy")

expect(person.other_workshop_setting_responses).to be_empty
end
Expand Down
Loading