mercredi 23 décembre 2015

Ruby on Rails remove activerecord relation result if certain criteria met

I have a rails site that allows a user to register two time slots for a course, once for themselves and once for their spouse. As courses fill up, I want to only have them displayed to the users that are registered so that they can un-register. Once the user un-registers, the course should be shown in the list again to indicate there is an open slot. I have everything working to do this, but I currently have the hiding of records being done in the view. Because of this, it is not showing the proper number of results per page as it is paginated. If there are 50 results on a page and 30 are hidden, it only shows 20 results on that page. What I wanted to do is see if I could possibly remove the Activerecord results from the list (NOT delete them) on the controller level. If there's another way to both hide the records and have the per page count be correct, I'd still be happy.

I have read up on the reject method, but don't see how it would be possible to do that in my scenario as I have to compare database values with the helper functions. There are also search functions and things of that nature which complicate by controller method. If there's an easy way to eliminate these from the Activerecord query itself, I'm just not seeing it. I'm not entirely sure that I can remove these from being visible in my scenario, other than doing so in the view like I am currently. I'm extremely close to just ditching pagination in this case, but as there are a couple hundred records to display I would rather not.

Helper Methods

def registered(course_session, user, spouse)
  course_attendee = CourseAttendee.where("user_id = ? and
   course_session_id = ? and for_spouse = ?", user.id, 
   course_session.id, spouse).first
  return course_attendee
end

def open_slots(course_session)
  course_attendees = CourseAttendee.where(:course_session_id =>
  course_session.id).count
  return course_session.attendee_limit - course_attendees
end

Current View Code

<% @course_sessions.each do |course_session| %>
    <% 
        ca = registered(course_session, current_user, false)
        cs = registered(course_session, current_user, true) 
        if ca || cs || (open_slots(course_session) > 0) %>
           ....show course session
        <% end %>
 <% end %>

What I'd like to do in Controller Index Method

def index
   if !params[:course_session_search].blank? &&
     !params[:course_session_search_end].blank?
      @course_sessions = CourseSession.joins(:room).order("starts_at").page(params[:page])
     .per_page(50).search(params[:course_session_search])   
   else
     @course_sessions = CourseSession.joins(:room).order("starts_at").
     page(params[:page]).per_page(50)
end

  # The do block is not actually there in the current code, this is my
  # attempt to weed out the unnecessary records
  @course_sessions.each do |course_session|
    ca = view_context.registered(course_session, current_user, false)
    cs = view_context.registered(course_session, current_user, true) 
    if !ca && !cs && (view_context.open_slots(course_session) <= 0)
       # Can I remove from display here if these conditions are met?
  end
end

respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @course_sessions }
end

end

Aucun commentaire:

Enregistrer un commentaire