web-dev-qa-db-fra.com

disposition différente pour l'action sign_in dans devise

J'essaie d'utiliser une disposition différente/personnalisée nommée "devise" pour l'action sign_in. J'ai trouvé this page dans le wiki de devise, et le deuxième exemple dit même que vous pouvez le faire par action (dans ce cas, sign_in action), mais cela ne montre aucun exemple. Quelqu'un sur IRC m'a dit que je pouvais essayer ceci:

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

Mais cela ne semble pas fonctionner car il charge toujours la disposition d'application par défaut. J'apprécierais toute aide.

80
Jorge Israel Peña

Je l'ai compris, mais je vais garder cette question ici au cas où d'autres personnes seraient curieuses.

C'était une stupide erreur. Le fait est sign_in est le chemin, pas l'action. En regardant le source pertinente , je peux voir que l'action requise est new, c'est-à-dire créer un nouveau Concevoir la session. Changer la condition de mon code ci-dessus en:

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

Fonctionne magnifiquement.

J'espère que cela aide quelqu'un là-bas.

44
Jorge Israel Peña

Une autre façon d'appliquer la disposition personnalisée à une action est la suivante.

Selon Comment: créer des dispositions personnalisées "Vous pouvez également définir la disposition de contrôleurs Devise spécifiques à l'aide d'un rappel dans config/environment.rb (Rails 2) ou config/application.rb (Rails 3). Cela doit être fait dans un rappel to_prepare car il est exécuté une fois en production et avant chaque demande en développement. "

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

Habituellement, une distinction de mise en page est faite entre les pages derrière la connexion et les pages qui ne nécessitent pas d'authentification, donc l'approche ci-dessus fonctionne la plupart du temps. Mais j'ai aussi expérimenté l'utilisation de action_name helper pour définir une mise en page pour une action particulière et cela a fonctionné comme un charme:

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

Je pense que c'est le meilleur moyen intégré de changer la disposition en fonction du contrôleur/action de conception au lieu de créer un assistant dans ApplicationController.

92
Zeeshan

Je viens de créer app/views/layouts/devise/sessions.html.erb et d'y mettre ma mise en page.

61
Josh

Voilà comment je l'ai fait. Je voulais une mise en page différente si l'utilisateur devait se connecter, mais une mise en page différente si l'utilisateur devait modifier son profil.

J'utilise Rails 4.1.1

Dans le contrôleur d'application, ajoutez ceci:

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

La solution de loin la plus simple consiste à simplement créer une mise en page appelée devise.html.haml dans votre dossier app/views/layouts. et la magie Rails s'occupe du reste.

app/views/layouts/devise.html.haml
8
John

Surpris de ne voir cette réponse nulle part, mais vous pouvez également le faire:

Dans routes.rb, changez la configuration de votre devise pour qu'elle ressemble à ceci:

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

Puis dans app/controllers/sessions_controller.rb

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

Cela est particulièrement utile si vous devez effectuer des remplacements logiques supplémentaires dans l'un des contrôleurs Devise.

7
streetlogics

Au cas où vous ne le sauriez pas, vous pouvez également utiliser rake routes Pour voir les itinéraires dans votre application Rails ainsi que l'action/le contrôleur auquel ils sont mappés.

 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"}
1
Dty

Voici un one-liner pour ceux qui veulent que toutes les actions de conception utilisent une nouvelle disposition:

class ApplicationController < ActionController::Base
  protect_from_forgery

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