ruby-on-rails – 扩展ActiveRecord :: Base的正确方法

我通过以下方式扩展了ActiveRecord :: Base类:

>我在lib下创建了一个目录,让我们现在称它为foo
>编写了提供额外方法has_many_bidirectional的模块,以便在ActiveRecord :: Base类中具有双向has_many关系
>在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

>使用配置文件末尾的以下代码扩展config / environment.rb中的ActiveRecord :: Base类:

ActiveRecord::Base.class_eval do
  include Foo::ActiveRecord::Base
end

>通过这种方式Rails被正确地包含在我的模块中,我可以毫无问题地使用它
>直到我想观察一个扩展类,因为在config / environment.rb中,config.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类中使用回调方法.)

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

谢谢!

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

./script/generate plugin has_many_bidirectional

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

以前的所有代码都可以通过这种方式轻松采用.

点赞