2012-03-19 130 views
3

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

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

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

但前/应用程序是指发动机的部分直接,因为隔离的,这样

render 'header' # front/ prefix is not required 

所以MainApp观点尝试加载应用程序/意见/应用/报头,而不是应用程序/视图/前/应用/报头

要FIXE此我把像这样的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 

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

我tryed以武力前面加上正确的路径(但它看起来这么脏):

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

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

而且我卡在这里。也许我的设计错了?

回答

0

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

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

的前置栈是这样的:

  • 主要的应用程序前置的路径
  • 主要应用浏览次数
  • 引擎意见

所以它是基于发动机,再加入主要的应用程序的东西在顶端。

1

默认情况下,Rails在视图/文件中查找,但是当它没有找到它时,它会查看引擎的视图/。这意味着你必须追加视图路径,这样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 

如果您在引擎中预先修改了您的视图路径并修改了路径,那么您将无法获得ab能够覆盖主应用程序中的引擎视图。这就是为什么你想追加。

+0

确实很好洞察。谢谢 ;) – ProxyGear 2014-01-24 19:07:56

2

杰克的答案是完美的,除非你想在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'