2011-02-13 21 views
79

Estoy tratando de usar un diseño diferente/personalizado denominado "idear" para la acción sign_in. Encontré this página en el wiki de diseño, y el segundo ejemplo incluso dice que puede hacerlo por acción (en este caso, acción sign_in), pero no muestra ningún ejemplo de hacer eso. Alguien en IRC me dijo que podía probar esto:diseño diferente para la acción sign_in en el diseño

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    layout :layout_by_resource 

    def layout_by_resource 
    if devise_controller? && resource_name == :user && action_name == 'sign_in' 
     "devise" 
    else 
     "application" 
    end 
    end 
end 

Pero no parece estar funcionando, ya que todavía está cargando el diseño de la aplicación por defecto. Apreciaría cualquier ayuda.

Respuesta

43

Lo descubrí, pero voy a mantener esta pregunta aquí en caso de que otras personas tengan curiosidad.

Fue un error estúpido. El hecho es sign_in es la ruta, no la acción. Mirando el relevant source, puedo ver que la acción requerida es new, es decir, crear una nueva sesión Devise. Cambiar mi condicional de código anterior a:

if devise_controller? && resource_name == :user && action_name == 'new' 

Funciona muy bien.

Espero que ayude a alguien por ahí.

+0

¿No aplicaría esto el diseño para ambos registros # new y sessions # new? – Ayrad

1

Por si acaso no lo sabía, también puede usar rake routes para ver las rutas en su aplicación de rieles junto con la acción/controlador al que se asignan.

new_user_registration GET /accounts/sign_up(.:format)  {:action=>"new", :controller=>"devise/registrations"} 
edit_user_registration GET /accounts/edit(.:format)   {:action=>"edit", :controller=>"devise/registrations"} 
         PUT /accounts(.:format)    {:action=>"update", :controller=>"devise/registrations"} 
         DELETE /accounts(.:format)    {:action=>"destroy", :controller=>"devise/registrations"} 
+0

Gracias, de hecho sabía/sabía sobre rutas de rake, simplemente no había pensado por un segundo que 'sign_in' podría no ser el nombre de la acción real, pensé que sería, entonces me di cuenta de que todo gira en torno a sesiones por lo que corresponde a la nueva acción. –

90

Otra forma de aplicar el diseño personalizado para una acción es la siguiente.

Según How To: Create custom layouts "También puede configurar el diseño para controladores Devise específicos mediante una devolución de llamada en config/environment.rb (rails 2) o config/application.rb (rails 3). Esto debe hacerse en un to_prepare devolución de llamada porque se ejecuta una vez en producción y antes de cada solicitud en desarrollo ".

config.to_prepare do 
    Devise::SessionsController.layout "devise" 
    Devise::RegistrationsController.layout proc{ |controller| user_signed_in? ? "application" : "devise" } 
    Devise::ConfirmationsController.layout "devise" 
    Devise::UnlocksController.layout "devise"    
    Devise::PasswordsController.layout "devise"   
end 

Por lo general, una distinción diseño se hace entre las páginas de inicio de sesión y detrás de las páginas que no requieren autenticación, por lo que el enfoque anterior funciona la mayor parte del tiempo. Pero también he experimentado con el uso de action_name ayudante para establecer un diseño para una acción particular y funcionó como encanto:

config.to_prepare do 
    Devise::SessionsController.layout proc{ |controller| action_name == 'new' ? "devise" : "application" } 
end 

Creo que este es el mejor y construidas en forma de cambiar el diseño basado en idear controlador/acción en vez de crear un ayudante en ApplicationController.

+3

Además, no olvide reiniciar el servidor cada vez que realice un cambio en cualquier archivo de la carpeta config, en este caso config/application.rb para Rails3 o config/environment.rb para Rails 2, para que los cambios surtan efecto . – Zeeshan

+0

** Tenga cuidado ** Probé este método en Rails 3.1 y hace que la carga de activos desde la carpeta de activos sea significativamente más lenta. Esto no afectará a los servidores de producción, pero cuando tenga más de unos pocos archivos css/js, lo notará. – Gazler

+0

en el ejemplo anterior, ¿es posible configurar diseños para recursos de diseño independientes (por ejemplo, imaginemos que tenemos dos tipos diferentes de usuarios de diseño y cada uno necesita su propio diseño) – ckarbass

61

Acabo de crear una aplicación/views/layouts/devise/sessions.html.erb y coloco mi diseño allí.

+23

¡Gran solución! También puede poner un diseño en /app/views/layouts/devise.html.erb y hacer que se aplique a _all_ your idee views – Basti

0

Aquí hay una sola línea para aquellos que quieren todo idear acciones a utilizar un nuevo diseño:

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' } 
end 
8

Ésta es la forma en que lo hice. Quería un diseño diferente si el usuario tenía que iniciar sesión, pero un diseño diferente si el usuario tenía que editar su perfil.

Estoy usando Rails 4.1.1

En el controlador de aplicación, añadir lo siguiente:

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 
    before_action :configure_permitted_parameters, if: :devise_controller? 

    layout :layout_by_resource 

    # Define the permitted parameters for Devise. 
    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :lastname, :email, :password, :password_confirmation)} 
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:avatar, :firstname, :lastname, :email, :password, :password_confirmation, :current_password) } 
    end 

    def layout_by_resource 
    if devise_controller? and user_signed_in? 
     'dashboard' 
    else 
     'application' 
    end 
    end 
end 
5

sorprendido de no ver esta respuesta en cualquier lugar, pero también se puede hacer esto:

En routes.rb, cambiar su configuración legado que debe buscar algo como esto:

devise_for :users, controllers: { 
    sessions: 'sessions' 
    } 

Luego, en app/controllers/sessions_controller.rb

class SessionsController < Devise::SessionsController 
    layout 'devise', only: [:new] 
end 

Esto es especialmente útil si necesita hacer anulaciones lógicas adicionales en cualquiera de los controladores Devise.

+1

¡Esto es exactamente lo que estaba buscando! Ninguno de los otros funcionó por alguna razón:/ – djGrill

7

La solución, por mucho más simple, es simplemente crear un diseño llamado devise.html.haml en su carpeta de aplicaciones/vistas/diseños. y la magia de Rails se ocupa del resto.

app/views/layouts/devise.html.haml 
+1

esa es la manera más simple de establecer un diseño para el dispositivo. ¡Gracias! – phlegx

+1

Esta solución funciona increíble. – karlihnos

Cuestiones relacionadas