diseño diferente para la acción sign_in en devise

84

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

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 parece que no funciona ya que todavía está cargando el diseño de aplicación predeterminado. Apreciaría cualquier ayuda.

Jorge Israel Peña
fuente

Respuestas:

96

Otra forma de aplicar un 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 específicos de Devise usando una devolución de llamada en config / environment.rb (rieles 2) o config / application.rb (rieles 3). Esto debe hacerse en un to_prepare callback 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, se hace una distinción de diseño entre las páginas detrás del inicio de sesión y las páginas que no requieren autenticación, por lo que el enfoque anterior funciona la mayor parte del tiempo. Pero también experimenté con el uso de action_namehelper para establecer un diseño para una acción en particular y funcionó a la perfección:

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

Creo que esta es la mejor forma incorporada de cambiar el diseño en función del controlador / acción del dispositivo en lugar de crear un ayudante en ApplicationController.

Zeeshan
fuente
3
Además, no olvide reiniciar el servidor cada vez que realice un cambio en cualquier archivo de la carpeta de configuración, en este caso config / application.rb para Rails3 o config / environment.rb para Rails 2, para que los cambios surtan efecto.
Zeeshan
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
en el ejemplo anterior, ¿es posible configurar diseños para recursos de dispositivos separados (por ejemplo, supongamos que tenemos dos tipos diferentes de usuarios de
dispositivos
Cuando intento esto, aparece un error que indica que ahora está intentando obtener una plantilla de dos ubicaciones. ¿Cómo se consigue que Rails anule la configuración anterior de Devise?
Adam Grant
Para aquellos que se lo perdieron, la configuración de Rails 3 es diferente, haga esto en: config / application.rb (rails 3).
Stone
66

Acabo de crear app / views / layouts / devise / sessions.html.erb y puse mi diseño allí.

Josh
fuente
28
¡Gran solución! También puede poner un diseño en /app/views/layouts/devise.html.erb y hacer que se aplique a todas las vistas de su dispositivo
Basti
45

Lo descubrí, pero mantendré esta pregunta aquí en caso de que otras personas sientan curiosidad.

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

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

Funciona maravillosamente.

Espero que eso ayude a alguien.

Jorge Israel Peña
fuente
¿No aplicaría esto el diseño tanto para registros # nuevos como para sesiones # nuevas?
Ayrad
12

La solución, con mucho, más simple es simplemente crear un diseño llamado devise.html.haml en su carpeta app / views / layouts. y la magia de Rails se encarga del resto.

app/views/layouts/devise.html.haml
Juan
fuente
3
esa es la forma más sencilla de establecer un diseño para devise. ¡Gracias!
phlegx
8

Así es como 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 la aplicación, agregue esto:

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
Sankalp Singha
fuente
7

Sorprendido de no ver esta respuesta en ningún lado, pero también puede hacer esto:

En route.rb, cambie la configuración de su dispositivo para que se vea así:

  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 de Devise.

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

En caso de que no lo supiera, también puede usar rake routespara 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"}
Dty
fuente
Gracias, en realidad sabía / sabía sobre rutas de rake, simplemente no había pensado ni por un segundo que 'sign_in' podría no ser el nombre de la acción real, pensé que lo sería, luego me di cuenta de que todo gira en torno a sesiones por eso corresponde a la nueva acción.
Jorge Israel Peña
0

Aquí hay un resumen para aquellos que quieren que todas las acciones de diseño usen un nuevo diseño:

class ApplicationController < ActionController::Base
  protect_from_forgery

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