2009-06-09 31 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是我找到了解決辦法。我完全不明白它,但它的工作原理:-)