2012-02-01 261 views
0

我有一個購買模型,它既屬於產品又屬於模型。我試圖保持用戶所做的所有購買的平均價格,並在保存新購買時更新此平均價格。Rails計算平均值belongs_to

我知道我可以只計算一個滾動平均值,但我正在嘗試使用ActiveRecord提供的平均方法來做到這一點。另一個需要注意的是,在這個人爲的例子中,價格對於產品來說是無效的。在計算平均值時,平均值是否會忽略所有零的實例?

我的主要掛斷是購買中的after_save塊。

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 

回答

1

所生成的查詢是SELECT AVG(average_purchase_price)FROM購買... (參照此:http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000293)。

如果你查看關於組函數的mysql文檔(http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html),它指出null值被忽略,除非明確指定。所以是的,零值將被忽略。

+0

謝謝,這是我想通。任何關於我的after_save塊語法的建議,用於更新這個平均值? – 2012-02-01 07:48:14

+0

user.update_attribute(:average_purchase_price,user.purchases.average(:price)),即,如果您不想驗證。否則使用update_attributes。此外,如果您沒有在應用程序中的任何位置更新購買價格(即購買後已創建),則可以將after_save更改爲after_create,因爲後者只會運行一次,而前者每次更新購買時都會運行。取決於你的要求。 – 2012-02-01 07:56:37

+0

我不認爲這個語法會起作用,因爲:價格是產品的屬性,而不是購買。我基本上需要能夠做一些像user.update_attribute(:average_purchase_price,user.purchases.average(:purchase.product.price)),但我知道這也是無效的。 – 2012-02-01 08:07:39

0

試試這個:

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

這不因爲:價格是產品的屬性,而不是購買。 – 2012-02-02 07:39:05

+0

更新了答案看看。 – 2012-02-02 07:42:29