繁体   English   中英

装饰 Rails 引擎的助手以包含来自主应用程序的关注

[英]Decorate a Rails engine's helper to include a concern from the main app

我想通过装饰引擎的帮助程序模块之一,在引擎中包含来自应用程序的 ActiveSupport::Concern。 这是来自引擎的 Helper:

module MyEngine
  module MyHelper
  end
end

这是主应用程序的关注点:

module MyConcern
  extend ActiveSupport::Concern

  def do_this
  end

  def do_that
  end
end

下面是需要包含关注点的装饰引擎助手(用于引擎视图) - 它在主应用程序中声明,使用Rails 指南中描述的装饰器模式:

module MyEngine
  module MyHelper
    include MyConcern

    def do_stuff
    end
  end
end

修饰的帮助器由引擎正确加载,但引擎视图只能调用“do_stuff”。 MyConcern 的方法不可用,我很难弄清楚原因。 我还尝试通过将其嵌入 MyEngine::MyHelper.module_eval 调用来包含该问题,但这也不起作用。

有没有人遇到过这种问题? 我是否以错误的方式看待这个问题?

我将 MyHelper 从模块替换为类

module MyConcern
  extend ActiveSupport::Concern

  def do_this
    "do this"
  end

  def do_that
    "do that"
  end
end

module MyEngine
  class MyHelper
    include ::MyConcern

    def do_stuff
      "do stuff"
    end
  end
end

打电话时:

MyEngine::MyHelper.new.do_stuff
MyEngine::MyHelper.new.do_this
MyEngine::MyHelper.new.do_that

结果将是:

做东西

做这个

去做

我想你可能在反推这个。

如果您的引擎提供:

module MyEngine
  module MyHelper
    def foo
    end
  end
end

您可以在主应用程序中扩展该方法(您可以将其称为装饰,但我不确定这在技术上是否是装饰器模式):

module MainApp
  module MyHelper
    extend ::MyEngine::MyHelper
    def foo
      super
      do_something_else
    end
  end
end

当使用模块混合模式(这是 ActiveSupport::Concern 所做的)时,您可以使用模块扩展模块并将模块包含在类中。

如果您的引擎和主应用程序“共享部分” - 它应该只是放置在引擎中,因为 Rails 将在应用程序的 app/views 目录中渲染时首先查找视图,然后再查找已安装的引擎。

因此,主应用程序可以始终覆盖引擎提供的功能,而反之则不然。

如果您想让引擎提供的方法可配置,更好的主意是使用 Rails 配置设置(或单独的模块配置)或仅使用方法参数,而不是一些疯狂的循环依赖马戏团。

所以我终于找到了一种以“干净”的方式做到这一点的方法,如以下评论中所述: https : //groups.google.com/g/rubyonrails-core/c/PaABJDXnxyo/m/k-QUJEi9a9wJ

这个想法是在引擎中添加一个空的占位符助手,例如:

module MyEngine
  module ExtendableHelper
  end
end

然后在主应用程序中覆盖它,通过添加方法或包含关注点、其他 gem 的助手等...

module MyEngine
  module ExtendableHelper
    extend OtherGemFromMainApp::UsefulHelper
    include MainAppConcern
    
    def other_useful_method
      ...
    end
  end
end

因此引擎使用的助手是应用程序提供的助手,可以在引擎视图中调用UsefulHelper方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM