3

こちら で説明されているように、Rails Engine をオーバーライドするデコレーターをいくつか作成しています。エンジンからクラスに単純なメソッドを追加しようとしています。コードは次のとおりです。

# app/decorators/models/my_engine/user_decorator.rb

MyEngine::User.class_eval do
  def self.find_by_name_or_mis_id str
    where("CONCAT(#{table_name}.firstname, ' ', #{table_name}.surname) LIKE CONCAT('%', :s, '%') OR mis_id = :s", { s: str })
  end
end

私のアプリはメソッドを見つけることができず、レールコンソールでテストしようとしています:

# rails c
MyEngine::User.find_by_name_or_mis_id "John"
NoMethodError: undefined method `find_by_name_or_mis_id' for #<Class:0x007fcb85a45580>

コンソールで実行することで機能させることができますがrequire '/models/my_engine/user_decorator'、レールがデコレータを取得しないのはなぜですか?

4

4 に答える 4

6

かなりいろいろ調べてみたところ、自動ロードされていないように見えることがわかりました。必要だったのは (この gemに抽出する前に、 forem repoからつまんだものです):

# MyEngine
# lib/my_engine/engine.rb

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine

    config.to_prepare do
      Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
        require_dependency(c)
      end
    end
  end
end

ドキュメントにチケットを発行して、この情報を含めることができるようにします。デコレータの詳細については説明していますが、実際にそれらをロードする方法については説明していません (すべてが処理されていることを前提としています)。

更新:チケットを発行し、それに応じてガイドが更新されました。

于 2013-05-16T15:52:26.643 に答える
0

デコレーターrequire_dependency機能が組み込まれていない Rails エンジンでも機能する柔軟な代替手段として、オーバーライドするクラスのファイル パスをミラーリングし、require_dependency を使用してカスタマイズの前に元のクラスを要求することを検討してください。

この手法はデコレータを使用しません。代わりに、同じ名前のファイルでクラスを再度開きます。

# File: app/models/my_engine/user.rb

# Load the original class definition from the engine:
require_dependency "#{MyEngine::Engine.root}/app/models/my_engine/user"

# Open class to modify it:
module MyEngine
  class User
    def self.find_by_name_or_mis_id(str)
      where("CONCAT(#{table_name}.firstname, ' ', #{table_name}.surname) LIKE CONCAT('%', :s, '%') OR mis_id = :s", { s: str })
    end
  end
end
于 2016-05-18T17:09:57.903 に答える