Calculate sum of price on distant relation I have a booking with a method total which calculates the total price of the booking from the sum of all the prices of activities that belong to appointments. A booking has many appointments and the following seems to give the right answer, but it seems horrid.  How can I improve this?

  def total 
    # TODO  shouldn't this be a db query?
    total = 0
    self.appointments.each do |appointment|
        unless appointment.activity.price.nil? 
            total += appointment.activity.price.to_f
        end
    end     
    total
  end
You can do this:

def total
  self.appointments.joins(:activity).sum(:price)
end


You could perhaps simplify it a little, by making an explicit 2nd order has_many on your booking model:

has_many :appointments
has_many :activities, :through =&gt; :appointments


Then you can just do:

def total
  self.activities.sum(:price)
end


In either case, it'll end up as a single DB-query.