rails prepend_view_path 可安装引擎

Posted

技术标签:

【中文标题】rails prepend_view_path 可安装引擎【英文标题】:rails prepend_view_path of mountable engine 【发布时间】:2012-03-19 11:28:30 【问题描述】:

一方面,我有一个可安装的引擎,比如说前面 前面包含我的资产和几页 它与 MainApp 隔离。我不希望它触及主应用。

另一方面,我希望我的 MainApp 使用前端的布局和部分。 所以我这样设置布局:

class ApplicationController < ActionController::Base
    layout 'front/application'
end

但是前端/应用程序直接引用引擎部分,因为隔离,像这样

render 'header' # front/ prefix is not required

所以 MainApp 视图尝试加载 app/views/application/header 而不是 app/views/front/application/header

为了解决这个问题,我放了一个这样的 prepend_view_path :

class ApplicationController < ActionController::Base
    layout 'front/application'
    before_filter :prepend_front
protected
    def prepend_front
       prepend_view_path "app/views/front"
    end
end

但这不起作用,因为引擎路径指向供应商。 引擎将它自己添加到前置路径列表中:~/main_app/vendor/private_gems/front-0.0.2/app/views 我的 preprend_front 方法创建了这个:~/main_app/app/views/front

我试图强行添加正确的路径(但它看起来很脏):

prepend_view_path "#Rails.root/vendor/private_gems/front-0.0.2/app/views/front"

我不工作,只是让应用程序崩溃......

我被困在这里了。也许我的设计有问题?

【问题讨论】:

【参考方案1】:

Jack 的回答是完美的,除非您想在 Rails 引擎中执行此操作(例如,如果您的引擎本身具有需要不同加载路径的“主题”)。在这种情况下, prepend_path 和 append_path 不合适,因为您希望在引擎默认加载路径之前但在应用程序加载路径之后插入新加载路径。

对此的解决方案(仅在 Rails 3.2 中测试过)是将以下内容添加到您的引擎 /lib/my_engine.rb 文件中:

config.after_initialize do
  my_engine_root = MyEngine::Engine.root.to_s
  paths = ActionController::Base.view_paths.collect|p| p.to_s
  paths = paths.insert(paths.index(my_engine_root + '/app/views'), my_engine_root + '/app/views/themes/my_theme')
  ActionController::Base.view_paths = paths
end

新的加载路径 my_engine_root + '/app/views/themes/my_theme' 现在将位于引擎标准加载路径 my_engine_root + '/app/views' 之前

【讨论】:

【参考方案2】:

默认情况下,Rails 在views/ 中查找文件,但是如果找不到,它会在引擎的views/ 中查找。这意味着您必须附加视图路径,以便 Rails 将在主应用程序的 views/ 中查找,然后在引擎中查看修改后的路径,最后在引擎的 views/ 中查找。这就是堆栈:

主要应用视图/ 引擎修改路径(视图/前/引擎内部) 引擎视图/

为此,请进入application_controller.rb

class ApplicationController < ActionController::Base

    before_filter :set_views_path

    def set_views_path
        append_view_path FnetIdentityRailsEngine::Engine.root.join('app', 'views', 'front')
    end
end

如果您在引擎中使用修改后的路径添加视图路径,您将无法在主应用中覆盖引擎视图。这就是你想要追加的原因。

【讨论】:

确实有很好的洞察力。谢谢;)【参考方案3】:

最后我删除了隔离属性。 我将视图上移了一个文件夹,因此从 engine_app 文件夹中移出。

唯一的最终调整是将 EngineApp::Engine.url_helper 包含到 MainApp 应用程序控制器中。

前置堆栈如下所示:

主应用程序附加路径 主要应用视图 引擎视图

所以它是基于引擎的,然后在顶部添加主应用程序的东西。

【讨论】:

以上是关于rails prepend_view_path 可安装引擎的主要内容,如果未能解决你的问题,请参考以下文章

可排序与可拖动的 jQuery 和 Rails

未检测到 Rails 预编译资产 Yarn 可执行文件

可重复使用的远程模态 Rails

Rails 5可操作的未定义方法'fetch'用于nil:NilClass

使用 Rspec 测试 Rails 3.1 可安装引擎

作为可读的 Rails 插件问题