web-dev-qa-db-fra.com

Où remplacer la méthode d'assistance actuelle_utilisateur de pierre précieuse

Comment puis-je remplacer utilisateur actuel de gEM. En fait, je dois ajouter des services Web pour application mobile.

Actuellement, le logiciel gère la session et "current_user" pour l'application Web.

Maintenant, l'application mobile va envoyer user_id au serveur. J'ai besoin de remplacer l'utilisateur actuel comme celui-ci

def current_user
  if params[:user_id].blank?
    current_user
  else
    User.find(params[:user_id])
  end   
end

Devrais-je modifier un gem en tant que plugin? ou autre chose ?
Veuillez expliquer en détail car je suis nouvelle dans Rails.

Sincères amitiés,

24
Omer Aslam

Selon le module Devise :: Controllers :: Helpers , current_user (ainsi que tous les autres assistants), est ajouté à ApplicationController, ce qui signifie que vous pouvez le remplacer de la manière suivante:

# in application_controller.rb
alias_method :devise_current_user, :current_user
def current_user
  if params[:user_id].blank?
    devise_current_user
  else
    User.find(params[:user_id])
  end   
end
48
Limbo Peng

L’autre réponse suggérant l’aliasing de la méthode n’est en réalité pas la meilleure solution. Le commentaire de Doug English est la meilleure solution:

# In ApplicationHelper
def devise_current_user
   @devise_current_user ||= warden.authenticate(:scope => :user)
end

Voici la raison:

Supposons que vous incluiez ApplicationHelper dans votre contrôleur. Si vous avez besoin d'une méthode dans votre ApplicationHelper qui s'appuie sur invent_current_user, étant donné la solution d'alias à l'intérieur du contrôleur, vous n'avez pas de chance.

Mais avec la définition de méthode explicite ci-dessus, vous pouvez déplacer la définition vers le programme d'assistance et l'appeler depuis d'autres méthodes, mais vous pouvez toujours l'inclure dans le contrôleur.

Cela est utile, par exemple, lorsque vous développez une solution d'emprunt d'identité d'utilisateur et que vous devez afficher deux utilisateurs différents dans la vue, l'un pour l'administrateur réel (legs_current_user) et l'autre, l'utilisateur avec emprunt d'identité (current_user).

5
Amin Ariana

En supposant que nous puissions faire confiance à nos données de session (qui dépendent du fait que vous y mettiez une entrée d'utilisateur sans autorisation appropriée ou non), cela pourrait fonctionner comme une préoccupation:

module Concerns
  module ControllerWithImpersonation
    extend ActiveSupport::Concern

    included do
      helper_method :devise_current_user
    end

    def current_user
      if session[:impersonated_user_id].blank?
        devise_current_user
      else
        User.find(session[:impersonated_user_id])
      end
    end

    def devise_current_user
      @devise_current_user ||= warden.authenticate(:scope => :user)
    end

  end
end

J'utilise ceci dans un projet pour le moment.

Une question mineure (dans la réponse, désolé) ... devrais-je être au courant de tout changement dans Devise ou Warden qui rend devise_current_user ci-dessus obsolète?

0
haslo

La réponse de Limbo-Peng est excellente, mais peut être améliorée un peu pour s'assurer que seuls les administrateurs peuvent le faire:

Vous devrez également définir une méthode is_admin? ou un attribut is_admin dans la classe User.

Vous voudrez peut-être aussi utiliser une clé différente de user_id pour éviter les conflits avec vos paramètres habituels.

# to impersonate another user, e.g. for customer support
# only admins can do this..
#
alias_method :devise_current_user, :current_user
def current_user
  if ! params[:user_id].blank? \
     && devise_current_user && devise_current_user.is_admin? 
    User.find(params[:user_id])
  else
    devise_current_user
  end
end
0
Tilo