Rails 装饰器,覆盖 Rails 引擎

Mik*_*ell 3 ruby-on-rails rails-engines

我正在编写一些装饰器来覆盖此处所述的 Rails 引擎。我正在尝试向引擎中的类添加一个简单的方法,这是我的代码:

# 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
Run Code Online (Sandbox Code Playgroud)

我的应用程序找不到该方法,在 rails 控制台中我尝试对其进行测试:

# rails c
MyEngine::User.find_by_name_or_mis_id "John"
NoMethodError: undefined method `find_by_name_or_mis_id' for #<Class:0x007fcb85a45580>
Run Code Online (Sandbox Code Playgroud)

我可以通过require '/models/my_engine/user_decorator'在控制台上做来让它工作,为什么 rails 不接我的装饰器?

Mik*_*ell 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
Run Code Online (Sandbox Code Playgroud)

我将在文档上提出一张票,以便他们可以包含这些信息,看看他们详细介绍了装饰器,但不解释您实际如何加载它们(假设这些都已为您处理)。

更新:我确实提出了一张票,并相应地更新了指南。

  • 顺便说一句,我假设这段代码在引擎本身中是否正确?是不是有点奇怪?我的意思是引擎不需要知道这些,是吗? (5认同)
  • 以免在路径中硬编码斜杠:`Rails.root.join('app', 'decorators', '**', '*_decorator*.rb')` (3认同)