【问题标题】:linked attributes between classes (ruby on rails)类之间的链接属性(ruby on rails)
【发布时间】:2013-08-25 08:36:34
【问题描述】:

早上好,我在我的 rails 应用程序中尝试在两个类之间链接属性时遇到问题。让我解释得更好:

我有一个Systemclass,其中belongs_to我的Area class(一个区域has_many系统)。它们都有一个名为price 的属性。一个区域的价格必须是它拥有的所有系统价格的总和。

有没有什么方法可以建立这种关系,而不必每次我更改其中一个系统的价格时都更新该地区的价格? (我会做类似@system.area.price = @system.area.price + @system.price 的事情)

【问题讨论】:

  • 希望area.price自动更新吗?
  • @dax 不,恰恰相反。这正是我想要的

标签: ruby-on-rails ruby class sum attr


【解决方案1】:

如果您可以在数据库中处理此问题,sum 计算将为您完成:http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html

class Area < ActiveRecord::Base
  has_many :systems
  def price
    systems.sum('price')
  end
end

您可以完全删除该区域的价格字段。

【讨论】:

  • 这取决于你是否想在列表中显示这个,因为当显示多个区域记录时,这将导致N个查询而不是1个。
  • 你打赌,有能力的开发人员会注意的。 :)
【解决方案2】:

除非您想走在数据库中引入触发器的黑暗、危险的道路上,否则简短的回答并不是真的。

长答案是您需要after_save 处理程序来为您进行此调整。始终确保您应用它的方式是 increment 而不是 reset 否则您将遇到竞争条件。

在您的简短示例中,不清楚您要的是什么。除非 Area 有 base_price,否则您将无限期地继续添加系统价格。您需要在此处计算出确切的逻辑,但您的要求示例如下:

class System < ActiveRecord::Base
  belongs_to :area
  after_save :update_area_price

protected
  def update_area_price
    self.area and self.area.increment!(:price, self.price)
  end
end

【讨论】:

  • base_price 是什么意思?我想要的是在area.price 与其system 价格之间建立关系(其中area.price 等于其系统价格的总和。
  • 那么您需要一种协调方法。将 area.price 设置为 SUM(systems.price) 并具有正确的范围:self.price = self.systems.sum(:price),也许?
  • 它使用sum 工作,非常感谢@tadman!理解了这个概念后,我制作了一个效果更好的循环(使用each)!
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多