Rails has_many: nil:NilClass 的未定义方法“*”
Rails has_many: undefined method `*' for nil:NilClass
我定义了一个关系,其中一个订单有很多订单项:
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
*' for nil:NilClass):`
是从视图中调用,以显示订单的总价。
实际上,如果我在此方法中添加一些行以尝试访问任何订单项属性,比如 order_items[0].price
我会立即收到错误消息。
我不明白为什么会这样。
我定义的关系与 ShoppingCart
和 ShoppingCartItems
完全相同,但没有遇到这个问题。
此外,我正在开发的订单和订单项目 类 与我之前使用 Rails 3.2.9 所做的项目非常相似,并且运行良好。
我能做什么?
您的 OrderItem
没有 price
或 amount
值。
要验证哪些 OrderItem
条目没有价格,请执行 OrderItem.where(price: nil)
;对于金额做 OrderItem.where(amount: nil)
要将这些 nil
prices/amounts 视为 0,请将您的代码更改为以下内容:
def total
order_items.map{ |oi| (oi.price || 0) * (oi.amount || 0) }.sum
end
错误来自这个花絮:
n.price * n.amount
Ruby 试图在 n.price
上调用 *
方法,但 n.price
正在返回 nil
,而 nil
没有上面定义了一个 *
方法,所以它会爆炸 "undefined method `*' for nil:NilClass"
简而言之,它不能乘以 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 }
我定义了一个关系,其中一个订单有很多订单项:
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
*' for nil:NilClass):`
是从视图中调用,以显示订单的总价。
实际上,如果我在此方法中添加一些行以尝试访问任何订单项属性,比如 order_items[0].price
我会立即收到错误消息。
我不明白为什么会这样。
我定义的关系与 ShoppingCart
和 ShoppingCartItems
完全相同,但没有遇到这个问题。
此外,我正在开发的订单和订单项目 类 与我之前使用 Rails 3.2.9 所做的项目非常相似,并且运行良好。
我能做什么?
您的 OrderItem
没有 price
或 amount
值。
要验证哪些 OrderItem
条目没有价格,请执行 OrderItem.where(price: nil)
;对于金额做 OrderItem.where(amount: nil)
要将这些 nil
prices/amounts 视为 0,请将您的代码更改为以下内容:
def total
order_items.map{ |oi| (oi.price || 0) * (oi.amount || 0) }.sum
end
错误来自这个花絮:
n.price * n.amount
Ruby 试图在 n.price
上调用 *
方法,但 n.price
正在返回 nil
,而 nil
没有上面定义了一个 *
方法,所以它会爆炸 "undefined method `*' for nil:NilClass"
简而言之,它不能乘以 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 }