我定义了一个订单有多个订单商品的关系:
class Order < ActiveRecord::Base
has_many :order_items
end
class OrderItem < ActiveRecord::Base
belongs_to :book
belongs_to :order
end
订单和订单商品会正确存储并与他们建立关系。
我正在尝试显示所有订单的记录。为此,我需要从订单商品中访问一些属性,例如金额或价格。
我定义了以下方法来计算订单的总价,并在Order
模型中定义:
def total
order_items.inject(0) { |sum, n| n.price * n.amount + sum }
end
我跟踪了错误,发现我在此方法中收到错误,这是错误:ActionView::Template::Error (undefined method
*&#39;对于nil:NilClass):`
从视图中调用,显示订单的总价格。
实际上,如果我在此方法中添加了一些我试图访问任何订单商品属性的行,请说order_items[0].price
我很中心地收到错误。
我不知道为什么会这样。
我的定义与ShoppingCart
和ShoppingCartItems
完全相同,但没有遇到此问题。
此外,我正在开发的订单和订单商品类与我之前使用Rails 3.2.9进行的项目非常相似,并且工作正常。
我该怎么办?
答案 0 :(得分:1)
您的OrderItem
没有price
或amount
值。
要验证哪些OrderItem
条目没有价格,请执行OrderItem.where(price: nil)
;并且金额为OrderItem.where(amount: nil)
要将这些nil
价格/金额视为0,请将您的代码更改为以下内容:
def total
order_items.map{ |oi| (oi.price || 0) * (oi.amount || 0) }.sum
end
答案 1 :(得分:0)
错误来自这个花絮:
n.price * n.amount
Ruby试图在*
上调用n.price
方法,但n.price
正在返回nil
,nil
没有*
在它上面定义的方法,所以它会用&#34;未定义的方法`*&#39;为零:NilClass&#34;
简而言之,它不能乘以nil,通常只能使用类似数字或字符串的值。
如果您想阻止订单商品的价格为零,您可以添加模型验证:
class OrderItem
validates_numericality_of :price, greater_than_or_equal_to: 0
或者您可以将计算方法更改为强制安全值:
order_items.inject(0) { |sum, n| (n.price || 0) * (n.amount || 1) + sum }