From 6c7115a9c9922a4abc9e65e7834c4a78d4dc2577 Mon Sep 17 00:00:00 2001 From: Travis Grathwell Date: Tue, 10 Feb 2015 20:59:25 -0800 Subject: [PATCH] Cache event role on users to reduce RSVP querying on homepage The homepage does a bunch of queries for each event to figure out which buttons to show the logged-in user based on whether they're an organizer, volunteer, etc. There is now a User#event_attendances method which gathers all of a user RSVPs into a hash like: 5 => { role: Role::STUDENT, waitlist_position: 2 } This structure is memoized on the user so if we need to ask event.organizer?(user) and event.volunteer?(user) etc multiple times in the single request it just looks up the result in yonder hash. --- app/models/event.rb | 10 +++++----- app/models/user.rb | 13 +++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/models/event.rb b/app/models/event.rb index 192d72a07..f0cdf72fc 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -208,23 +208,23 @@ def rsvp_for_user(user) end def no_rsvp?(user) - !rsvps.where(user_id: user.id).any? + user.event_role(self).blank? end def student?(user) - student_rsvps.where(user_id: user.id).any? + user.event_role(self) == Role::STUDENT end def waitlisted_student?(user) - student_waitlist_rsvps.where(user_id: user.id).any? + student?(user) && user.event_attendances[id][:waitlist_position].present? end def volunteer?(user) - volunteer_rsvps.where(user_id: user.id).any? + user.event_role(self) == Role::VOLUNTEER end def organizer?(user) - organizer_rsvps.where(user_id: user.id).any? + user.event_role(self) == Role::ORGANIZER end def checkiner?(user) diff --git a/app/models/user.rb b/app/models/user.rb index df7203c15..688b42ad8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -59,6 +59,19 @@ def meetup_id authentications.find { |a| a.provider == 'meetup' }.try(:uid) end + def event_attendances + @event_attendances ||= rsvps.each_with_object({}) do |rsvp, hsh| + hsh[rsvp.event_id] = { + role: rsvp.role, + waitlist_position: rsvp.waitlist_position + } + end + end + + def event_role(event) + event_attendances.fetch(event.id, {})[:role] + end + private def make_empty_profile