在STI类上覆盖`inherited`会引发NoMethodError

时间:2014-10-15 17:32:09

标签: ruby-on-rails inheritance rails-activerecord single-table-inheritance

我在rails 4 app中有以下课程:

class ReceiptDocument < ActiveRecord::Base
  @foo

  self.inheritance_column = :document_type
  has_and_belongs_to_many :donations

  protected

    def self.inherited(subklass)
      subklass.inherit_attributes(@foo)
    end

    def self.inherit_attributes(foo)
      @foo = foo
    end
end

class ReceiptRequest < ReceiptDocument; end
class ReceiptResult < ReceiptDocument; end

类实例变量@foo在类定义中设置一次,并且在所有子类中应该具有相同的值。我添加了inherited覆盖,以便可以从ReceiptRequestReceiptResult访问该值。

但是,现在当我致电ReceiptRequest.new时,我得到:

pry(main)> DonationReceiptRequest.new
NoMethodError: undefined method `[]' for nil:NilClass
from /gems/activerecord-4.1.5/lib/active_record/relation/delegation.rb:9:in `relation_delegate_class'

如果我注释掉覆盖,事情就会恢复正常。但是,我无法再在ReceiptDocument的所有子类中共享该值。

非常感谢任何见解。

1 个答案:

答案 0 :(得分:2)

最后得到了这个。

这个错误似乎指向了ActiveRecord正在做的一些幕后工作,所以我进一步挖了一下。

似乎设置self.inheritance_column很可能会覆盖inherited方法。老实说,我不确定我的覆盖是在踩踏什么工作。但是如下重新定义该方法可以解决问题:

def self.inherited(subklass)
  super # <--
  subklass.inherit_attributes(@foo)
end