我通过以下方式扩展了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.
以前的所有代码都可以通过这种方式轻松采用.