如何在两个相互依赖的属性上运行回调函数?

时间:2014-01-26 18:06:23

标签: ruby-on-rails ruby activerecord

在我的Rails应用中,我的Invoice模型的属性为datedue_date

为简单起见,我不希望用户手动输入due_date,而只需输入应添加到date天数

这就是我设置虚拟属性days_allowed的原因。

class Invoice < ActiveRecord::Base

  belongs_to :user

  before_save :save_date

  attr_accessor :days_allowed

  def days_allowed # attribute reader (I need that too!)
    (due_date - date).to_i
  end

  def save_date
    self.due_date = date + days_allowed.days
  end

end

但是,当用户在表单中选择日期并输入若干天时,例如10,我得错了结果,因为save_date回调是指days_allowed方法,而不是同名属性。

关键问题似乎是我在两个相互依赖的不同属性上使用回调(datedays_allowed)。

有谁能告诉我如何解决这个难题?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这种方法如何(不需要before_save):

class Invoice < ActiveRecord::Base

  belongs_to :user

  def days_allowed
    (due_date - date).to_i
  end

  def days_allowed=(days)
    self.due_date = date + days
  end
end

编辑除非date始终排在第一位,否则当days_alloweddate都存在时,不应该使用批量作业。

答案 1 :(得分:0)

我认为您需要存储所有三个字段,只是不提供任何表单属性来编辑计算的字段。

虽然你的用例似乎是违反了“不要重复自己”,但我认为这是巧合重复的一个例子。让我解释一下:

考虑你的下一个问题 - 你将在周末,假期等开始到期日。正是出于这个原因,我写了business_time gem:

https://github.com/bokmann/business_time

因此,在您添加10天的解决方案中,您现在可以添加10个工作日。确切的截止日期现在可以在周末,假日等3天周末等情况下波动。如果你必须应对雪天,就像美国东海岸大部分地区最近一样,你可以加入tham作为一个假期,并重新计算。营业日数仍为10天,但截止日期已发生变化。工作日的数量是要保存的关键数据,而不是要计算的数据。需要保存到期数据,因为它是在您要保存以进行查询而不是每次都尝试重新计算的上下文中计算的一条信息。