在has_many关系的父级中维护聚合值的最佳实践是什么?

时间:2011-11-28 03:20:49

标签: ruby-on-rails-3 activerecord

一个非常常见的模式是在关联的父模型中具有属性来自子项的某些摘要/聚合值,例如,总计或平均值或某些此类事物。典型的:

class Order < ActiveRecord::Base
  has_many :items
  # total_cost
end

class Item < ActiveRecord::Base
  belongs_to :order
  # cost
end

每次添加或删除Item时,都希望更新父级total_cost。当然,也可能Item的费用可能会发生变化,在这种情况下,total_cost也需要更新。

我无法找到一个非常好的最佳实践指南,我已经看到它做了很多不同的方式。

我想,基本问题是谁应该负责保持total_cost价值?在我看来,它确实需要是Item(除非Items一旦与父母联系在一起,它们就是不可变的。)

最好的方法是after_save上的after_destroyItem回调调用Order中更新其total_cost的方法吗? / p>

1 个答案:

答案 0 :(得分:0)

是的,如果您必须在数据库中保存total_cost并将其更新,那么最好的方法是在项目上进行after_saveafter_destroy回调,这将更新订单的total_cost。

顺便说一下,你也可以通过在Order模型中定义一个方法来计算total_cost而不将其保存在Database.Like以下

class Order < ActiveRecord::Base
  has_many :items

 def total_cost
    return self.items.sum(:cost)
 end
end

通过这种方式,您不需要任何回调。您可以将其作为订单模型中的字段进行访问。此外,您无需担心项目更新删除或添加新项目。您也不必将其保存在数据库表中。