简体   繁体   English

如何在所有模型上添加has_many关联

[英]How to add a has_many association on all models

Right now I have an initializer that does this: 现在,我有一个执行此操作的初始化程序:

ActiveRecord::Base.send :has_many, :notes, :as => :notable ActiveRecord::Base.send :accepts_nested_attributes_for, :notes ActiveRecord::Base.send :has_many, :notes, :as => :notable ActiveRecord::Base.send :accepts_nested_attributes_for, :notes

It builds the association just fine, except when I load a view that uses it, the second load gives me: can't dup NilClass from: 它建立的关联很好,除非当我加载使用它的视图时,第二次加载使我: can't dup NilClass从以下位置can't dup NilClass

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2184:in `dup'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2184:in `scoped_methods'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2188:in `current_scoped_methods'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2171:in `scoped?'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2439:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2439:in `initialize'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/reflection.rb:162:in `new'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/reflection.rb:162:in `build_association'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:423:in `build_record'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:102:in `build'
(my app)/controllers/manifests_controller.rb:21:in `show'

Any ideas? 有任何想法吗? Am I doing this the wrong way? 我做错了吗? Interestingly if I move the association onto just the model I'm working with at the moment, I don't get this error. 有趣的是,如果我仅将关联移动到当前正在使用的模型上,就不会出现此错误。 I figure I must be building the global association incorrectly. 我认为我一定建立了错误的全球协会。

You state that you have many models, all of which require this association. 您声明自己有许多模型,所有这些模型都需要此关联。 If it were me, I'd would go with the approach of creating a base model class that contains the association and then have all the other models inherit from it. 如果是我,我会采用创建包含关联的基础模型类的方法,然后让所有其他模型都从中继承。 Something like: 就像是:

class NotableModel < ActiveRecord::Base

  # Prevents ActiveRecord from looking for a database table for this class
  self.abstract_class = true

  has_many :notes, :as => :notable
  accepts_nested_attributes_for :notes  
end

class Foo < NotableModel
  ...
end

class Bar < NotableModel
  ...
end

In my opinion this approach is more self-documenting compared to using a little bit of metaprogramming hidden away in an initializer. 在我看来,与使用隐藏在初始化程序中的一些元编程相比,这种方法更具自我证明性。

看看卸载的,它可以帮助你

It's recommended to make each association in each model! 建议在每个模型中建立每个关联! It's a useless DRY way to make such things! 这是做这种事情的无用的DRY方式! At all, It's my opinion! 完全是我的意见!

Thanks to Rich Kilmer (of InfoEther), we found the elegant (and slightly opaque) way of fixing this: 多亏了InfoEther的Rich Kilmer,我们找到了解决此问题的优雅方法(略微不透明):

# config/initializers/has_many_notes.rb
module ActiveRecord
  class Base
    def self.inherited(klass)
      super
      klass.send :has_many, :notes, :as => :notable
      klass.send :accepts_nested_attributes_for, :notes
    end
  end
end

Now no inheritance changes, and it's very DRY 现在没有继承更改,而且非常干燥

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

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