k_day
k_day

Reputation: 1379

Rails calculate average across belongs_to

I have a Purchase model, which belongs to both a product and a model. I am trying to keep an average price of all the purchases a user makes, and update this average whenever a new purchase is saved.

I know that I could just calculate a rolling average, but I am trying to do this using the average method provided by ActiveRecord. One other caveat is that in this contrived example, it is valid for price to be nil for a Product. Will average just ignore all instances of nil when calculating the average?

My main hang up is with the after_save block in Purchases.

class Product < ActiveRecord::Base
    #price   :float

    has_many :purchases
end

class User < ActiveRecord::Base
    #average_purchase_price  :float

    has_many :purchases
end

class Purchase < ActiveRecord::Base
    belongs_to :user
    belongs_to :product

    after_save do
       #Cant quite nail down the syntax here.
       user.update_attributes average_purchase_price: user.purchases.average(#todo average purchase prices)
    end
end

Upvotes: 0

Views: 930

Answers (2)

Harish Shetty
Harish Shetty

Reputation: 64363

Try this:

user.update_attribute(:average_purchase_price, 
  user.purchases.average("products.price", :joins => :product)

Upvotes: 0

Wahaj Ali
Wahaj Ali

Reputation: 4103

The query that is generated is SELECT AVG(average_purchase_price) FROM purchases... (refer to this: http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000293).

If you look up mysql's documentation on group functions (http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html) it states that null values are ignored unless explicitly specified. So yes, nil values will be ignored.

Upvotes: 1

Related Questions