扩展 ActiveRecord::Base 的正确方法

发布于 2024-10-09 06:35:30 字数 1842 浏览 2 评论 0原文

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

  • 我在 lib 下创建了一个目录,我们现在调用它 foo
  • 编写了模块提供了额外的方法has_many_bidirection,以在
  • lib/foo/active_record.rbActiveRecord::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 now foo
  • wrote the module which provides the extra method has_many_bidirectional to have bidirectional has_many relationships in ActiveRecord::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 the config/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 the config.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花之痕靓丽 2024-10-16 06:35:30

正如我所发现的,最好的方法是使用生成器创建一个插件:

./script/generate plugin has_many_bidirectional

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

我以前的所有代码都可以轻松地采用这种方式。

As I digged it out, the best way is to create a plugin with the generator:

./script/generate plugin has_many_bidirectional

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文