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(クラスでコールバック メソッドを使用したくありません。)

この機能を実現するには、ディレクトリの下にモジュールではなく宝石を作成する必要がありますか?lib

ありがとう!

4

1 に答える 1

2

私が掘り下げたように、最良の方法は、ジェネレーターでプラグインを作成することです。

./script/generate plugin has_many_bidirectional

このようにして、Rails はオブザーバー部分の前にそれを含めます。優れたチュートリアルはこちらにあります

以前のコードはすべて、この方法で簡単に採用できます。

于 2010-12-23T12:41:45.393 に答える