简体   繁体   English

Rails模型中的属性不是零时

[英]Attribute in Rails model appears to be nil when it's not

I have a very annoying and hard to figure out bug in my rails project. 我在Rails项目中有一个非常烦人并且很难弄清错误的地方。

After having created a bunch of models and their relations, I want to list them. 创建了一堆模型及其关系之后,我想列出它们。

But I keep getting an Error "can't dup NilClass". 但是我一直收到错误消息“无法复制NilClass”。 That is, until I restart the server. 也就是说,直到我重新启动服务器。 Then I can list them just fine. 然后我可以列出它们。

Debugging this issue, it turns out that the Error gets raised in a method in one of the models when I try to return the value of one of its attributes. 调试此问题后,事实证明,当我尝试返回其属性之一的值时,在其中一个模型的方法中引发了Error。 I have a breakpoint in the method, and this is what I get in the debugger: 我在方法中有一个断点,这是我在调试器中得到的:

(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

I doesn't matter if I reload the page. 我重新加载页面没关系。 I get the same error until I restart the server. 在重新启动服务器之前,我得到相同的错误。

My model basically looks like this (the error occurs in method baz): 我的模型基本上是这样的(错误发生在方法baz中):

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

My schema looks like this: 我的架构如下所示:

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

Update: 更新:

Before I get any more answers pointing out that :foo and "foo" are not the same: I'm aware that they are not equal, but that is not the issue here. 在我得到更多答案之前,指出:foo和“ foo”不相同:我知道它们不相等,但这不是这里的问题。

And, I just confirmed that read_attribute("foo") does return the same as read_attribute(:foo). 而且,我刚刚确认read_attribute(“ foo”)的返回结果与read_attribute(:foo)相同。 And so does self[:foo] and self["foo"]. self [:foo]和self [“ foo”]也是如此。 None of these return nil. 这些都不返回零。 They do however all return the id of foo, instead of foo itself. 但是,它们都返回foo的ID,而不是foo本身。

:foo is not equal to 'foo' . :foo不等于'foo' It is equal to 'foo'.to_sym or 'foo'.intern . 它等于'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

Finally solved it! 终于解决了!

Although I'm not exactly sure why, the problem goes away if I add "unloadable" to the model definition: 尽管我不确定为什么,但是如果在模型定义中添加“ unloadable”,问题就消失了:

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 is where I found the solution. 这个网站是我找到解决方案的地方。 I totally do not understand it, but it works :-) 我完全不明白,但是它有效:-)

The difference is that you have a different key. 区别在于您具有不同的密钥。 In Ruby, :foo is not the same thing as "foo" (:foo is a symbol, while "foo" is a String). 在Ruby中,:foo与“ foo”是不同的东西(:foo是符号,而“ foo”是String)。

You can try it out by putting :foo.to_s which will transform the symbol to a String if I'm not mistaken. 您可以通过放入:foo.to_s进行尝试,如果我没记错的话,它将把符号转换成字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM