web-dev-qa-db-fra.com

Rails - Comment remplacer le SessionsController pour effectuer des tâches spécifiques lorsque l'utilisateur se connecte?

À l'aide de Devise pour gérer les sessions/inscriptions des utilisateurs, j'aurais besoin d'effectuer des tâches spécifiques (mise à jour de certains champs de la table des utilisateurs pour cet utilisateur spécifique par exemple) chaque fois qu'un utilisateur se connecte, et avant qu'il ne soit redirigé par concevoir vers la page d'accueil pour se connecter utilisateurs.

Dois-je remplacer le programme SessionsController, et si oui, comment?

40
Patrice Navarre

Alternativement, vous pouvez créer votre propre contrôleur de sessions

class SessionsController < Devise::SessionsController
  def new
    super
  end

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    if !session[:return_to].blank?
      redirect_to session[:return_to]
      session[:return_to] = nil
    else
      respond_with resource, :location => after_sign_in_path_for(resource)
    end
  end
end

Et en routes.rb ajouter:

devise_for :users, controllers: {sessions: "sessions"}
60
Pykih

Devise fournit after_database_authentication méthode de rappel. Vous avez un accès complet pour l'objet utilisateur authentifié actuel là-bas.

Si vous souhaitez mettre à jour le nom d'utilisateur actuel après chaque connexion réussie, vous pouvez le faire comme ci-dessous.

class User < ActiveRecord::Base
  devise :database_authenticatable

  def after_database_authentication
    self.update_attributes(:name => "your name goes here")
  end 
end
18
Soundar Rathinasamy

Si vous regardez implémentation de Devise of sessions_controller#create, vous remarquerez qu'ils cèdent si vous passez un bloc.

Donc, il suffit de sous-classer leurs contrôleurs de sessions et de passer un bloc lorsque vous appelez super. Pour ce faire, dites d'abord à Devise dans routes.rb que vous souhaitez utiliser votre propre contrôleur de sessions:

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

Et puis créez une classe SessionsController et passez un bloc lorsque vous appelez super dans votre méthode create. Cela ressemblerait à quelque chose comme ceci:

class Users::SessionsController < Devise::SessionsController
  layout "application"

  # POST /login
  def create
    super do |user|
      if user.persisted?
        user.update(foo: :bar)
      end
    end
  end
end

La plupart des méthodes du contrôleur Devise acceptent un bloc, vous pouvez donc le faire pour l'enregistrement, le mot de passe oublié, etc.

15
stephen.hanson