2012-02-01 228 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