22
33module BetterTogether
44 # CRUD for BetterTogether::Event
5- class EventsController < FriendlyResourceController
5+ class EventsController < FriendlyResourceController # rubocop:todo Metrics/ClassLength
66 before_action if : -> { Rails . env . development? } do
77 # Make sure that all subclasses are loaded in dev to generate type selector
88 Rails . application . eager_load!
@@ -17,6 +17,14 @@ def index
1717 end
1818
1919 def show
20+ # Handle AJAX requests for card format - only our specific hover card requests
21+ card_request = request . headers [ 'X-Card-Request' ] == 'true' || request . headers [ 'HTTP_X_CARD_REQUEST' ] == 'true'
22+
23+ if request . xhr? && card_request
24+ render partial : 'better_together/events/event' , locals : { event : @event } , layout : false
25+ return
26+ end
27+
2028 super
2129 end
2230
@@ -35,10 +43,21 @@ def rsvp_going
3543 rsvp_update ( 'going' )
3644 end
3745
38- def rsvp_cancel
39- @event = set_resource_instance
46+ def rsvp_cancel # rubocop:disable Metrics/MethodLength
47+ set_resource_instance
48+ return if performed? # Exit early if 404 was already rendered
49+
50+ @event = @resource
4051 authorize @event , :show?
41- attendance = BetterTogether ::EventAttendance . find_by ( event : @event , person : helpers . current_person )
52+
53+ # Ensure current_person exists
54+ current_person = helpers . current_person
55+ unless current_person
56+ redirect_to @event , alert : t ( 'better_together.events.login_required' , default : 'Please log in to manage RSVPs.' )
57+ return
58+ end
59+
60+ attendance = BetterTogether ::EventAttendance . find_by ( event : @event , person : current_person )
4261 attendance &.destroy
4362 redirect_to @event , notice : t ( 'better_together.events.rsvp_cancelled' , default : 'RSVP cancelled' )
4463 end
@@ -74,10 +93,30 @@ def resource_class
7493
7594 private
7695
77- def rsvp_update ( status )
78- @event = set_resource_instance
96+ # rubocop:todo Metrics/MethodLength
97+ def rsvp_update ( status ) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
98+ set_resource_instance
99+ return if performed? # Exit early if 404 was already rendered
100+
101+ @event = @resource
79102 authorize @event , :show?
80- attendance = BetterTogether ::EventAttendance . find_or_initialize_by ( event : @event , person : helpers . current_person )
103+
104+ # Check if event allows RSVP
105+ unless @event . scheduled?
106+ redirect_to @event ,
107+ alert : t ( 'better_together.events.rsvp_not_available' ,
108+ default : 'RSVP is not available for this event.' )
109+ return
110+ end
111+
112+ # Ensure current_person exists before creating attendance
113+ current_person = helpers . current_person
114+ unless current_person
115+ redirect_to @event , alert : t ( 'better_together.events.login_required' , default : 'Please log in to RSVP.' )
116+ return
117+ end
118+
119+ attendance = BetterTogether ::EventAttendance . find_or_initialize_by ( event : @event , person : current_person )
81120 attendance . status = status
82121 authorize attendance
83122 if attendance . save
@@ -86,5 +125,54 @@ def rsvp_update(status)
86125 redirect_to @event , alert : attendance . errors . full_messages . to_sentence
87126 end
88127 end
128+ # rubocop:enable Metrics/MethodLength
129+
130+ # Override base controller method to add performance optimizations
131+ def set_resource_instance
132+ super
133+
134+ # Preload associations needed for event show page to avoid N+1 queries
135+ preload_event_associations! unless json_request?
136+ end
137+
138+ def json_request?
139+ request . format . json?
140+ end
141+
142+ # rubocop:todo Metrics/AbcSize
143+ # rubocop:todo Metrics/MethodLength
144+ def preload_event_associations! # rubocop:todo Metrics/CyclomaticComplexity, Metrics/AbcSize
145+ return unless @event
146+
147+ # Preload categories and their translations to avoid N+1 queries
148+ @event . categories . includes ( :string_translations ) . load
149+
150+ # Preload event hosts and their associated models
151+ @event . event_hosts . includes ( :host ) . load
152+
153+ # Preload event attendances to avoid count queries in view
154+ @event . event_attendances . includes ( :person ) . load
155+
156+ # Preload current person's attendance for RSVP buttons
157+ if current_person
158+ @current_attendance = @event . event_attendances . find do |a |
159+ a . person_id == current_person . id
160+ end
161+ end
162+
163+ # Preload translations for the event itself
164+ @event . string_translations . load
165+ @event . text_translations . load
166+
167+ # Preload cover image attachment to avoid attachment queries
168+ @event . cover_image_attachment &.blob &.load if @event . cover_image . attached?
169+
170+ # Preload location if present
171+ @event . location &.reload
172+
173+ self
174+ end
175+ # rubocop:enable Metrics/MethodLength
176+ # rubocop:enable Metrics/AbcSize
89177 end
90178end
0 commit comments