From 544c848f04b3a989a01086911f1a5456a8a56987 Mon Sep 17 00:00:00 2001 From: Morgan Roderick Date: Sun, 1 Feb 2026 18:04:24 +0100 Subject: [PATCH] Fix empty coaches list in workshop feedback form (Issue #2367) Resolves issue where no coaches appeared in the feedback dropdown when students tried to submit workshop feedback. Root cause: The feedback controller was filtering for coaches where attended=true, but attendance is only marked after organizers manually verify it. When feedback emails are sent (the day after workshop), coaches have attending=true but attended=nil. Changes: - Updated set_coaches to use accepted_or_attended scope instead of attended - Added ORDER BY with NULLS LAST to prioritize verified coaches first - Added test for coaches who RSVPd but haven't been verified yet - Added test for verified coaches appearing before unverified coaches This allows students to submit feedback immediately after workshops, even before organizers verify attendance, while still prioritizing verified coaches when that data is available. Fixes #2367 --- app/controllers/feedback_controller.rb | 4 ++- spec/features/member_feedback_spec.rb | 45 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/controllers/feedback_controller.rb b/app/controllers/feedback_controller.rb index 3b2602df3..88305479f 100644 --- a/app/controllers/feedback_controller.rb +++ b/app/controllers/feedback_controller.rb @@ -38,6 +38,8 @@ def feedback_params end def set_coaches(workshop) - @coaches = workshop.invitations.to_coaches.attended.map(&:member) + @coaches = workshop.invitations.to_coaches.accepted_or_attended + .order(Arel.sql('attended DESC NULLS LAST')) + .map(&:member) end end diff --git a/spec/features/member_feedback_spec.rb b/spec/features/member_feedback_spec.rb index a9dbbdf96..396df814a 100644 --- a/spec/features/member_feedback_spec.rb +++ b/spec/features/member_feedback_spec.rb @@ -38,6 +38,51 @@ expect(page).to have_select('feedback_tutorial_id', with_options: [@tutorial.title]) end + + scenario 'I can see coaches who RSVPd but have not yet been marked as attended (Issue #2367)' do + # This reproduces the real-world scenario where: + # 1. Coach RSVPs to workshop (attending = true) + # 2. Feedback is sent the next day + # 3. Organizer hasn't yet marked attendance (attended = nil) + coach_not_yet_verified = Fabricate(:coach) + Fabricate(:attending_workshop_invitation, + workshop: feedback_request.workshop, + member: coach_not_yet_verified, + role: 'Coach', + attended: nil) + + visit feedback_path(valid_token) + + # Coach should appear in the list even though attended is nil + expect(page).to have_select('feedback_coach_id', with_options: [coach_not_yet_verified.full_name]) + end + + scenario 'verified coaches appear before unverified coaches in the list' do + # Create two coaches: one verified (attended=true), one not yet (attended=nil) + verified_coach = Fabricate(:coach, name: 'Alice', surname: 'Verified') + unverified_coach = Fabricate(:coach, name: 'Bob', surname: 'Unverified') + + Fabricate(:attended_workshop_invitation, + workshop: feedback_request.workshop, + member: verified_coach, + role: 'Coach') + + Fabricate(:attending_workshop_invitation, + workshop: feedback_request.workshop, + member: unverified_coach, + role: 'Coach', + attended: nil) + + visit feedback_path(valid_token) + + # Get all coach options in order + select_options = page.find('#feedback_coach_id').all('option').map(&:text).reject(&:blank?) + verified_index = select_options.index(verified_coach.full_name) + unverified_index = select_options.index(unverified_coach.full_name) + + # Verified coach should appear before unverified coach + expect(verified_index).to be < unverified_index + end end context 'I get redirected to the main page' do