我有一个CommercialDocument
模型,它有一个discount_amount
属性和一个discount_amount_with_tax
虚拟属性。
这是我在我的模型中如何定义这一点:
def discount_amount_with_tax
discount_amount * (1 + tax.rate / 100)
end
def discount_amount_with_tax=(amount)
self.discount_amount = amount.to_f / (1 + tax.rate / 100)
end
在我的表单中,用户可以填写discount_amount
和discount_amount_tax
:
= f.label :discount_amount
= f.text_field :discount_amount
= f.text_field :discount_amount_with_tax
我想优先考虑discount_amount_with_tax
字段,这意味着除非另一个字段为空,否则不得考虑discount_amount
。
我的问题是,如果我在discount_amount_with_tax
字段中什么都不放,假设 10 在 discount_amount
中,那么discount_amount
将等于 0,这显然不是我想要的。
我该如何解决这个问题?
任何帮助将不胜感激。
"".to_i
# => 0
空白字符串转换为零整数。因此:
def discount_amount_with_tax=(amount)
self.discount_amount = amount.to_f / (1 + tax.rate / 100)
end
# same as...
def discount_amount_with_tax=(0)
self.discount_amount = 0 / (...)
end
# 0 / anything except zero = 0
# self.discount_amount = 0 no matter what
在质量分配期间,调用discount_amount_with_tax=
。空白表单输入作为空字符串传递,然后 Active Record 将其转换为整数(零)。 discount_amount_with_tax=
将discount_amount
设置为零,而不管discount_amount
之前的数值如何。
解决此问题的简单方法是使用条件:
def discount_amount_with_tax=(amount)
self.discount_amount = (amount.to_f / (1 + tax.rate / 100)) if amount > 0
end
请注意,这是简单的方法,而不是理想的方法。更好的解决方案是在控制器中编写自定义 setter 逻辑来代替质量分配;基本上是在控制器中手动设置这些属性。
我认为您可以在此处使用before_validation回调来设置discount_amount字段。
before_validation :calculate_discount_amount
def discount_amount_with_tax
@discount_amount_with_tax ||= discount_amount * (1 + tax.rate / 100.0)
end
def discount_amount_with_tax=(amt)
@discount_amount_with_tax = amt
end
def calculate_discount_amount
self.discount_amount = discount_amount_with_tax / (1 + tax.rate / 100.0)
end
只是提醒一下,您需要使用 100.0 而不是 100,以便您将除以浮点数而不是整数。