一方面,我有一个可安装的引擎让我们说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"
我不工作,只是让应用程序崩溃......
我被困在这里。也许我的设计错了?
答案 0 :(得分:2)
杰克的答案是完美的,除非您想在Rails引擎中执行此操作(例如,如果您的引擎本身具有需要不同加载路径的主题&#39;)。在这种情况下,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'
答案 1 :(得分:1)
默认情况下,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
如果您在引擎中使用修改后的路径添加了视图路径,则无法在主应用程序中覆盖引擎视图。这就是你想要追加的原因。
答案 2 :(得分:0)
最后我删除了isolate属性。 我将视图移动了一个文件夹,因此不在engine_app文件夹中。
唯一的最终结果是将EngineApp :: Engine.url_helper包含在MainApp应用程序控制器中。
前置堆栈如下所示:
所以它基于引擎,然后在顶部添加主应用程序。