2012-06-29 59 views
6

我正在将我的标准Rails应用程序转换为可安装引擎的过程。该应用程序可与标准博客应用程序相媲美,我希望每个模型,控制器和视图都可扩展,因此我选择了可​​安装的引擎。Rails可安装引擎并覆盖另一引擎

我使用的宝石之一是据我了解一种可安装引擎本身的设计。它可以在可安装的发动机内使用,如here所述。

我可以在我的引擎中部分使用它。一切工作正常,包括一些设计控制器我重写像这样的:

# config/routes.rb 

Bbronline::Engine.routes.draw do 
    devise_for :users, class_name: "Bbronline::User", module: :devise, 
    controllers: { registrations: "bbronline/devise_overrides/registrations"} 
    ... 

# controllers/bbronline/devise_overrides/registrations_controller.rb 
require_dependency "bbronline/application_controller" 

module Bbronline 

class DeviseOverrides::RegistrationsController < Devise::RegistrationsController 

    def new_intermediair 
    @user = User.new 
    end 
    ... 

正确的观点的意见/ bbronline/devise_overrides /注册/ new_intermediair.html.haml'也正确加载预期。

但是,我的问题是,我没有自定义控制器重写的视图没有正确加载。例如,如果登录视图位于views/bbronline/devise/sessions/new.html.haml且未加载视图。相反,标准设计登录视图被加载,即devise-2.1.0/app/views/devise/sessions/new.html.erb

当然,我可以通过用我自己的控制器覆盖每个控制器来解决这个问题,就像我对上面的registrations_controller所做的那样,但这看起来非常难看。要实现这个目标,每个控制器都在重写?是否有更方便的方法来从另一个可挂载引擎中覆盖可挂载引擎的视图?

回答

4

view_paths的顺序不正确。检查设计:: SessionsController的视图路径显示:

Devise::SessionsController.view_paths 
=> #<ActionView::PathSet:0x007fa1bf0e36f8 @paths= [/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/test/‌​dummy/app/views, 
/Users/harmdewit/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/devise-2.1.‌​0/app/views, 
/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/app/vi‌​ews]> 

的安装引擎的最后路径应该来的中间色器件路径之前。该解决方案是这样的设置在application.rb中加载的优先级:

#test/dummy/config/application.rb (the app that uses my mountable engine) 
... 
config.railties_order = [Blog::Engine, :main_app, :all] 
... 

这也记录在轨API:http://api.rubyonrails.org/classes/Rails/Engine.html#label-Loading+priority

感谢何塞·Valim在指向正确的方向。

+2

任何方式我可以做这个改变,而不必改变我的虚拟应用程序的配置?我更喜欢在加载我的宝石时将其设置为默认行为。 – Ajedi32

1

我需要更多信息。你正在定义哪个控制器,以及从哪个控制器继承?正在渲染哪个视图以及您期望渲染哪个视图?此外,.view_paths是你的朋友在你的轨道,从而尽量安慰以下:

Devise::SessionsController.view_paths 
YourApp::SomeDeviseController.view_paths 

这会给你每个控制器搜索模板的一个更好的主意。

+0

我没有定义控制器,我只是想重写视图。更具体地说,我想重写位于'devise-2.1.0/app/views/devise/sessions/new.html.erb'中的视图而不重写控制器。这可能吗? –

+0

哦.view_paths显示: Devise :: SessionsController。view_paths =># Bbronline :: SessionsController当然不存在,我不重写它 –

+1

如果你不想使用自定义控制器,只需重写你可以将你的新视图放在'your-engine/app/views/devise/sessions/new.html.erb'上,并确保Devise的引擎在你的可挂载引擎之前被加载(只需要在之前设计)。再次,在你的'Devise.parent_controller'或你的应用程序控制器中调用'.view_paths'会告诉你模板查找顺序。 –

7

如果您不想在使用你的引擎,只是require 'devise'的lib \ my_engine \ engine.rb文件的顶部每一个应用程序来调整config.railties_order

+1

耶,它的工作! +1 – Ajedi32

+1

虽然其他答案提供了深入探索view_paths,但如果您的引擎是用于加载和自定义其他引擎,这是答案 – prusswan

+0

拯救了我的生活= D –