Rails将成功返回一个对象,但如果我尝试访问它的属性,则会抱怨该对象为NIL

时间:2010-02-23 03:38:51

标签: ruby-on-rails object nested attributes

我正在尝试填充嵌套字段product_name,它是一个Item。

在我的物品模型中:

 class Item < ActiveRecord::Base
   attr_writer :product_name
   belongs_to :order
   belongs_to :product
   def product_name

     #Product.find_by_id(self.product_id) #=> returns the product object
     #self.product #=> returns the product object

     #Product.find_by_id(self.product_id).name #=> complains that 'name' is being called on nil
     #self.product.name #=> complains that 'name' is being called on nil
     #"foooobar" #=> returns "foooobar"

   end     
 end

这些注释行中的每一行都如所描述的那样。 我没有得到的是,如何成功地返回一个对象,但是当你访问它的一个属性时,它会抱怨该对象是nil?

以下是整个错误:

 NoMethodError in Orders#edit

Showing app/views/orders/_form.haml where line #18 raised:

undefined method `name' for nil:NilClass

Extracted source (around line #18):

17:       = item.hidden_field :product_id
18:       = item.text_field :product_name, :class => 'auto_complete_input'
19:       = item.text_field :quantity, :size => 2

由于

3 个答案:

答案 0 :(得分:1)

您可能需要查看http://github.com/raganwald/andand处的插件。

基本上,它所做的是处理尝试在另一个可能 nil 的方法上调用方法时可能产生的错误。

完全基于您的示例:

Product.find_by_id(self.product_id).name #=> complains that 'name' is being called on nil

的实现如下:

Product.find(self.product_id).andand.name 

即使第一个语句Product.find(self.product_id)返回 nil ,它也不再在nil错误上触发未定义的方法。

PS:

同样,仅基于您的代码,我可以看到您正在复制使用:belongs_to关联生成的功能。从本质上讲,它意味着您可以使用:

self.product

of insead of:

Product.find_by_id(self.product_id)

答案 1 :(得分:0)

听起来你问的是一个非常普遍的问题。如果你问的是一个与我听到的完全不同的问题,请忽略它。 :)

是的,Ruby成功返回一个对象,对象是nil。在Ruby中,方法可以返回任何值,nil只是方法可以返回的另一个值。这些语句可能正在执行不返回任何结果的查询,因此该方法返回nil而不是您期望的对象。

答案越长,Product.find_by_id(x)会为id字段调用生成的find_by_属性方法,这与调用Product.find(:first, :conditions => ["id = ?", x])相同。如果你看the documentation for .find,你会发现它说的是

  

首先查找 - 这将返回[等等黑色...]如果没有匹配的记录,则返回nil。

答案 2 :(得分:0)

您是否在产品型号和产品型号中建立了适当的关系,我认为给予适当的关联可以解决您的错误。