1

I have a helper method in a Rails site that checks how many attendees are in a certain class. I have two different entities here, one for the class and one for attendee. The helper method takes an activerecord result as an argument and calculates how many open slots there are based on the total spots minus the total people that have registered. Is there any way that I can sort by the result of this so that courses with no open spots are put at the end of the list? Don't know if it will affect anything, but I am also using the will_paginate gem on the result set as well. I am currently ordering by the start date.

Method in math_class.helper

def open_slots(math_class)
  math_attendees = Attendee.where(:math_class_id => math_class.id).count
  return math_class.total_spots - math_attendees
end

Math Class View/Open Slots Column

<% @math_classes.each do |math_class| %>
   <!-- Other columns... -->
<% if open_slots(math_class) > 0 %>
  <td>
   <%= pluralize(open_slots(math_class), 'slot') %> of 
   <%= math_class.total_spots %> remaining
   </td>
<% else %>
   <td><span class="text-error">No Open Slots</span></td>
<% end %>

Controller Query statement

@math_classes = MathClass.joins(:room).order("starts_at").page(params[:page]).per_page(100)

2 Answers 2

1

Consider using the block form of Array#sort:

 @math_classes = MathClass.joins(:room).order("starts_at").page(params[:page]).per_page(100)
 @math_classes.to_a.sort! do |a, b|
   a_open_spots = a.total_spots - a.attendees.count
   b_open_spots = b.total_spots - b.attendees.count
   a_open_spots <=> b_open_spots
 end

The spaceship operator <=> returns -1, 0 or 1 depending on if the left hand side is less than, equal to or greater than the right side. For example:

 3 <=> 4 # => -1
 3 <=> 3 # => 0
 4 <=> 3 # => 1

Array#sort uses this to order the elements in the array.

Sign up to request clarification or add additional context in comments.

2 Comments

Seems handy, but total_spots is a column within math_classes. I get an error when I attempt this that total_spots is undefined. If you attempt a to_a conversion wouldn't that remove the activerecord column names and not allow you to reference total_spots?
The instance variable @math_classes should be something like MathClass::ActiveRecord_Relation. The to_a converts this relation into actual instances of the MathClass. From there, we should be able to sort based on attributes of this class. For example: math_classes.to_a.sort { |a, b| a.total_spots <=> b.total_spots }
-1

You're going to have to use the order_by Ruby method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.