扩展 ActiveRecord::Base 的正确方法
我通过以下方式扩展了 ActiveRecord::Base
类:
- 我在
lib
下创建了一个目录,我们现在调用它foo
- 编写了模块提供了额外的方法
has_many_bidirection
,以在 lib/foo/active_record.rb
的ActiveRecord::Base
类中 建立双向has_many关系>:
模块 Foo 活动记录模块 自动加载:关联,'active_record/associations' 自动加载:基础,'active_record/base' 结尾 结尾
在
lib/foo/active_record/base.rb
中:模块 Foo 活动记录模块 模块底座 def self.included(基础) base.class_eval 做 包括协会 结尾 结尾 结尾 结尾 结尾
当然还有
lib/foo/active_record/associations.rb<中的真实代码< /代码>:
模块 Foo 活动记录模块 模块关联 def self.included(基础) base.extend(类方法) 结尾 模块类方法 def has_many_bi Direction(...) # ... 结尾 结尾 结尾 结尾 结尾
扩展了
ActiveRecord::Base
类在配置文件末尾包含以下代码的config/environment.rb
:ActiveRecord::Base.class_eval 做 包括 Foo::ActiveRecord::Base 结尾
通过这种方式,Rails 正确地包含在我的模块中,我可以毫无问题地使用它
- 直到我想要观察< /strong> 扩展类,因为在
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 而不是模块吗code> 目录有这个功能吗?
谢谢!
I have extended the ActiveRecord::Base
class in the following way:
- I made a directory under the
lib
, let's call it nowfoo
- wrote the module which provides the extra method
has_many_bidirectional
to have bidirectional has_many relationships inActiveRecord::Base
classes in the
lib/foo/active_record.rb
:module Foo module ActiveRecord autoload :Associations, 'active_record/associations' autoload :Base, 'active_record/base' end end
in the
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
and of course the real code in
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
extended the
ActiveRecord::Base
class in theconfig/environment.rb
with the following code at the end of the configuration file:ActiveRecord::Base.class_eval do include Foo::ActiveRecord::Base end
with this way Rails was properly included my module, and I could use it without any problem
- until I wanted to observe an extended class, because in the
config/environment.rb
theconfig.active_record.observers
part is before the extending part, and the observable class does not know anything about the new method at that point.
The following error produced:
/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
My question is, which is the correct way to extend the ActiveRecord::Base
class? (I don't want to use callback methods in my User
class.)
Do I really have to create a gem instead of a module under the lib
directory to have this functionality?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如我所发现的,最好的方法是使用生成器创建一个插件:
通过这种方式,Rails 会将其包含在观察者部分之前。可以在此处找到一个很好的教程。
我以前的所有代码都可以轻松地采用这种方式。
As I digged it out, the best way is to create a plugin with the generator:
And with this way Rails will include it before the observer part. A good tutorial can be found here.
All of my previous code can be easily adopted to this way.