在我的sale.rb模型中,我想检查表单是否为“价格”列提交了一个值。如果“price”为零(如果没有通过表单提交任何内容应该是这样),它应该从另一个表中获取值。但每当我尝试提交表单时,我都会收到NoMethodError in SalesController#create
错误,并突出显示此行:
write_attribute(:price,price * quantity.to_f)除非被销毁?
这是我的代码:
class Sale < ActiveRecord::Base
before_create :price
def price
if price = nil
mrr = Warehouse.where(:product => self.product).pluck(:mrr).shift.strip.sub(',', '.').to_f
write_attribute(:price, mrr * quantity.to_f) unless destroyed?
else
write_attribute(:price, price * quantity.to_f) unless destroyed?
end
end
end
提前致谢!
答案 0 :(得分:2)
您的支票price
为零是错误的。
你应该使用
if price == nil
或
if price.nil?
答案 1 :(得分:1)
一些随机提示:
1.避免零检查。 Rails ActiveSupport库使用整齐的present?
方法修补对象,它提供了更有意义的方法来确保您的对象在该术语的广义含义中不是空白的。例如,HTML表单没有任何特殊的空引用表示(nil
),并且可能会提交空字符串''
。
花一些时间学习基本(非Rails)Ruby。你应该理解“读者”和“作家”之间的区别。
mrr = Warehouse.where(:product => self.product).pluck(:mrr).shift.strip.sub(',', '.').to_f
- 您或其他任何开发人员浪费多少秒来试图找出这里到底发生了什么?什么是mrr
?你为什么要shift.strip.sub
呢?我觉得你的db模式可能在这里出错了。如果是商品费用,请将其存储在decimal
列中。这导致了我的下一步......
永远不会将价格作为浮动存储。浮点数会受到舍入误差的影响,因为某些分数可能需要无限数量的数字来表示而不会舍入,并且计算机自然也不能很好地处理无数个任何数字。基于二进制的计算机中的十进制浮点数可能更加棘手。现在,小的舍入误差往往会累积。百分之一百分钟最终成为一分钱,美分累积到美元,而在大规模生产应用程序中超过一年,这可能相当于一些不可忽视的金额,而且当您的报告到时,您公司的会计部门将使您的生活变得悲惨贵国的税务机关。
def price=(value)
value = mrr_from_warehouse if value.blank?
# mrr_from_warehouse is your long query extracted to separate instance method
super(value * quantity.to_f) # I doubt destroyed? method makes sense here
end