2012-06-29 17 views
6

Estoy en el proceso de convertir mi aplicación Rails estándar en un motor montable. La aplicación es comparable a una aplicación de blog estándar y quiero que cada modelo, controlador y vista sean extensibles, de ahí mi elección para un motor de montaje.Motor montable en rieles y anulación de otro motor

Una de las gemas que uso es Devise, que por lo que entiendo es una especie de motor montable. Se puede usar dentro de un motor montable como se indica here.

Puedo usarlo parcialmente dentro de mi motor. Todo está funcionando bien entre ellos algunos controlador Diseñar puedo reemplazar como éste:

# 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 
    ... 

La opinión correcta 'vistas/bbronline/devise_overrides/registros/new_intermediair.html.haml también se está cargando correctamente como se esperaba.

Sin embargo, mi problema es que las vistas que anulo sin un controlador personalizado no se cargan correctamente. Por ejemplo, la vista que debería tener la vista de inicio de sesión ubicada en views/bbronline/devise/sessions/new.html.haml y no está cargada. En cambio, la vista de inicio de sesión estándar de Devise se carga, es decir, devise-2.1.0/app/views/devise/sessions/new.html.erb

Por supuesto que podría resolver este problema anulando cada controlador con mi propio controlador como lo hice con el registrador_controlador anterior, pero esto parece muy feo. ¿Está anulando cada controlador la forma de hacer esto? ¿Existe alguna manera más conveniente de anular las vistas de un motor montable dentro de otro motor montable?

Respuesta

4

Los view_paths están en orden incorrecto. Comprobación de los caminos de la vista Diseñar :: SessionsController muestra:

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]> 

La última ruta del motor montable debe venir antes de la ruta legado medio. La solución es establecer la prioridad de carga en application.rb así:

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

Esto también se documenta en la API de rieles: http://api.rubyonrails.org/classes/Rails/Engine.html#label-Loading+priority

Gracias a José Valim para apuntar en la dirección correcta.

+2

¿De qué forma podría hacer este cambio sin tener que cambiar la configuración de mi aplicación ficticia? Prefiero hacer que este sea el comportamiento predeterminado cada vez que cargue mi gema. – Ajedi32

1

Necesito más información. ¿Qué controlador estás definiendo y de qué controlador hereda? ¿Qué vista se está representando y cuál esperaba obtener? Además, .view_paths es su amigo a fin de tratar en sus rieles consola lo siguiente:

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

Esto le dará una mejor idea de donde cada controlador es la búsqueda de plantillas.

+0

No estoy definiendo un controlador, solo quiero anular la vista. Más específicamente, quiero anular la vista ubicada en 'devise-2.1.0/app/views/devise/sessions/new.html.erb' sin anular el controlador. es posible? –

+0

Oh .view_paths muestra: Devise :: SessionsController.view_paths => # Bbronline :: SessionsController no existe, por supuesto, no lo anulo –

+1

Si no desea utilizar un controlador personalizado, simplemente anule el ver, simplemente coloque su nueva vista en: 'su-motor/app/views/idear/sessions/new.html.erb' y asegúrese de que el motor de Devise esté cargado antes de su motor montable (solo se requiere diseñar antes). De nuevo, al llamar '.view_paths' en su' Devise.parent_controller' o en su controlador de aplicación le dirá el orden de búsqueda de la plantilla. –

7

Si no desea ajustar el config.railties_order en cada aplicación que utiliza su motor, justo require 'devise' encima de su lib \ my_engine \ engine.rb archivo .

+1

¡Sí, funcionó! +1 – Ajedi32

+1

Mientras que las otras respuestas ofrecen información para explorar view_paths, esta es la respuesta si su motor está destinado a cargar y personalizar otros motores – prusswan

+0

me salvó la vida = D –