rails prepend_view_path可安装引擎

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

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

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" 

我不工作,只是崩溃的应用程序…

我被困在这里。 也许我的设计错了?

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'

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

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

为此,请进入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 

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

最后我删除了isolate属性。 我将视图移动了一个文件夹,因此不在engine_app文件夹中。

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

前置堆栈看起来像这样:

  • 主应用程序前置路径
  • 主要应用视图
  • 引擎视图

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