Ruby on rails Rails装饰程序,重写Rails引擎

Ruby on rails Rails装饰程序,重写Rails引擎,ruby-on-rails,rails-engines,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

我正在编写一些装饰程序来覆盖所描述的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
我的应用程序找不到该方法,我尝试在rails控制台中对其进行测试:

# rails c
MyEngine::User.find_by_name_or_mis_id "John"
NoMethodError: undefined method `find_by_name_or_mis_id' for #<Class:0x007fcb85a45580>
#rails c
MyEngine::User.find_by_name_或_mis_id“John”
NoMethodError:未定义的方法“按名称查找”或“按id查找”#

我可以通过在控制台上执行
require'/models/my_engine/user_decorator'
来让它工作,为什么rails不接收我的decorators?

经过一番反复研究后,它似乎没有自动加载。所需的是(在他们将其提取到中之前,从中捏出):

#MyEngine
#lib/my_engine/engine.rb
MyEngine模块
类引擎<::Rails::引擎
分离出MyEngine
config.to_准备做什么
目录glob(Rails.root+“app/decorators/***.\u decorator*.rb”)。每个都做|
需要依赖项(c)
结束
结束
结束
结束
我将在文档上提出一个问题,以便它们可以包含此信息,因为它们会详细介绍装饰器,但不会解释如何实际加载它们(假设这些都是为您处理的)


更新:我确实提出了一个问题,指南也相应地更新了。

很抱歉打断了一个老问题。我对装饰宝石有一些问题。另一种选择是.< /p> < p>对于一个灵活的替代品,它也适用于Rails引擎,而不需要装饰器>代码>要求依赖性<代码>功能内置,请考虑镜像您要重写的类的文件路径,并在您的自定义之前使用ReavyRelax来要求原始类。

这种技术不使用装饰器。而是在同名文件中重新打开类:

# 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

嗨,迈克。谢谢你,真的很有帮助!你确定指南已经更新了吗?我只是偶然发现了同样的问题,但没有发现这里提到过:顺便问一下,我认为这段代码在引擎中运行是正确的吗?这不是有点奇怪吗?我的意思是引擎不需要知道这一点,是吗?这样就不会硬编码路径中的斜杠:
Rails.root.join('app','decorators','**','*.\u decorator*.rb')
config.to_prepare do
  # Load application's model / class decorators
  Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
    Rails.configuration.cache_classes ? require(c) : load(c)
  end
end
# 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