2009-06-09 28 views
0

我有一个非常烦人,很难找出我的rails项目中的错误。Rails模型中的属性似乎是零,当它不是

在创建了一堆模型及其关系之后,我想列出它们。

但我不断收到一个错误“不能重复NilClass”。也就是说,直到我重新启动服务器。然后我可以列出他们很好。

调试此问题,事实证明,当我尝试返回其某个属性的值时,会在其中一个模型的方法中引发错误。我在方法中设置断点,这就是我得到的调试器:

 
    (rdb:5) self 
    #<Bar id: 1037, foo: 2237, created_at: "2009-06-09 19:52:11", updated_at: "2009-06-09 19:52:47"> 
    (rdb:5) foo 
    TypeError Exception: can't dup NilClass 
    (rdb:5) attributes[:foo] 
    nil 
    (rdb:5) attributes["foo"] 
    2237 

,如果我重新加载页面我无所谓。我得到相同的错误,直到我重新启动服务器。

我的模型基本上看起来像这样(在方法巴兹发生错误):

class FooBar < ActiveRecord::Base 

    belongs_to :foo, :class_name => "BarFoo", :foreign_key => "foo", :dependent => :destroy 
    belongs_to :bar, :class_name => "BarFoo", :foreign_key => "bar", :dependent => :destroy 
    validates_presence_of :foo, :on => :create 

    def baz 
     [foo, bar].compact 
    end 
end 

我的模式是这样的:

create_table "foo_bar", :force => true do |t| 
    t.integer "foo" 
    t.integer "bar" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

更新:

之前,我还有更多的答案指出:foo和“foo”是不一样的:我知道它们不是平等的,但这不是问题。

而且,我刚刚确认read_attribute(“foo”)确实返回与read_attribute(:foo)相同的结果。 self [:foo]和self [“foo”]也是如此。这些都没有返回零。但是,他们都会返回foo的id,而不是foo本身。

+0

您需要提供更多信息:模型的数据库模式,foo方法定义和设置foo的代码。 – 2009-06-09 20:54:43

回答

0

区别在于你有不同的关键。在Ruby中,:foo与“foo”不一样(:foo是一个符号,而“foo”是一个String)。

如果我没有弄错,你可以试试把:foo.to_s这个符号转换成String。

+0

我很清楚这一点。但是,它并没有真正解决这个问题。 – KaptajnKold 2009-06-09 20:32:29

1

:foo不等于'foo'。它等于'foo'.to_sym'foo'.intern

irb(main):001:0> hash = {:foo => 10, 'foo' => 'bar'} 
=> {"foo"=>"bar", :foo=>10} 
irb(main):002:0> hash[:foo] 
=> 10 
irb(main):003:0> hash['foo'] 
=> "bar" 
irb(main):004:0> hash[:foo.to_s] 
=> "bar" 
irb(main):005:0> hash['foo'.to_sym] 
=> 10 
irb(main):006:0> hash['foo'.intern] 
=> 10 
1

终于解决了!

虽然我不知道是什么原因,问题消失,如果我加上“卸”的模型定义:

class FooBar < ActiveRecord::Base 

    unloadable 

    belongs_to :foo, :class_name => "BarFoo", :foreign_key => "foo", :dependent => :destroy 
    belongs_to :bar, :class_name => "BarFoo", :foreign_key => "bar", :dependent => :destroy 
    validates_presence_of :foo, :on => :create 

    def baz 
     [foo, bar].compact 
    end 
end 

This site是我找到了解决办法。我完全不明白它,但它的工作原理:-)