4

ActiveRecord::Base通过以下方式扩展了课程:

  • 我在 下做了一个目录lib,我们现在调用它foo
  • 编写了提供额外方法以在类has_many_bidirectional中具有双向 has_many 关系的模块ActiveRecord::Base
  • lib/foo/active_record.rb

    module Foo
      module ActiveRecord
        autoload :Associations, 'active_record/associations'
        autoload :Base, 'active_record/base'
      end
    end
    
  • lib/foo/active_record/base.rb

    module Foo
      module ActiveRecord
        module Base
          def self.included(base)
            base.class_eval do
              include Associations
            end
          end
        end
      end
    end
    
  • 当然还有真正的代码lib/foo/active_record/associations.rb

    module Foo
      module ActiveRecord
        module Associations
    
          def self.included(base)
            base.extend(ClassMethods)
          end
    
          module ClassMethods
            def has_many_bidirectional(...)
              # ...
            end
          end
        end
      end
    end
    
  • 在配置文件末尾使用以下代码扩展了ActiveRecord::Base类中的内容:config/environment.rb

    ActiveRecord::Base.class_eval do
      include Foo::ActiveRecord::Base
    end
    
  • 通过这种方式,Rails 被正确包含在我的模块中,我可以毫无问题地使用它

  • 直到我想观察一个扩展类,因为config/environment.rbconfig.active_record.observers部分在扩展部分之前,而可观察类此时对新方法一无所知。

产生以下错误:

/Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:1998:in `method_missing': undefined method `has_many_bidirectional' for #<Class:0x1032f2fc0> (NoMethodError)
        from .../app/models/user.rb:27

我的问题是,扩展ActiveRecord::Base课程的正确方法是什么?(我不想在User课堂上使用回调方法。)

我真的必须在目录下创建一个gem而不是一个模块lib才能拥有这个功能吗?

谢谢!

4

1 回答 1

2

当我挖掘出来时,最好的方法是使用生成器创建一个插件:

./script/generate plugin has_many_bidirectional

通过这种方式,Rails 会将它包含在观察者部分之前。一个很好的教程可以在这里找到。

我以前的所有代码都可以很容易地采用这种方式。

于 2010-12-23T12:41:45.393 回答