67 votes

Comment "supprimer en douceur" un utilisateur avec Devise ?

J'utilise actuellement Devise pour l'enregistrement/authentification des utilisateurs dans un projet Rails. Lorsqu'un utilisateur veut annuler son compte, l'objet utilisateur est détruit, ce qui laisse mon application dans un état indésirable.

Quel est le moyen le plus simple de mettre en œuvre une "suppression douce", c'est-à-dire de ne supprimer que les données personnelles et de marquer l'utilisateur comme supprimé ? Je veux toujours conserver toutes les associations d'enregistrements.

Je suppose que je devrai d'abord introduire une nouvelle colonne "supprimé" pour les utilisateurs. Mais alors je suis coincé avec ce code par défaut dans la vue du profil de l'utilisateur :

<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>

Où puis-je trouver le :delete méthode ? Comment écraser les méthodes Devise par défaut ?

103voto

hakunin Points 13171

Je pourrais conseiller de remplacer destroy sur votre modèle d'utilisateur pour simplement faire update_attribute(:deleted_at, Time.current) (au lieu de la détruire réellement), mais cet écart par rapport à l'API standard pourrait devenir fastidieux à l'avenir. Voici donc comment modifier le contrôleur.

Devise a un tas de contrôleurs par défaut dans la boîte. La meilleure façon de les personnaliser est de créer votre propre contrôleur en héritant du contrôleur Devise correspondant. Dans ce cas, nous parlons de Devise::RegistrationsController - qui est facilement reconnaissable en regardant la source. Donc, créez un nouveau contrôleur.

class RegistrationsController < Devise::RegistrationsController
end

Maintenant, nous avons notre propre contrôleur qui hérite de toute la logique fournie par l'appareil. La prochaine étape est de dire à devise de l'utiliser à la place du contrôleur par défaut. Dans vos routes, vous avez devise_for ligne. Elle doit être modifiée pour inclure le contrôleur des enregistrements.

devise_for :users, :controllers => { :registrations => 'registrations' } 

Cela semble étrange, mais c'est logique car, par défaut, il s'agit de "devise/registrations", et pas simplement de "registrations".

L'étape suivante consiste à remplacer le destroy action dans le contrôleur des enregistrements. Lorsque vous utilisez registration_path(:user), :method => :delete - c'est là qu'il y a un lien. À destroy action du contrôleur des enregistrements.

Actuellement, devise fait ce qui suit.

def destroy
  resource.destroy
  set_flash_message :notice, :destroyed
  sign_out_and_redirect(self.resource)
end

Nous pouvons à la place utiliser ce code. Tout d'abord, ajoutons une nouvelle méthode à User modèle.

class User < ActiveRecord::Base
  def soft_delete
    # assuming you have deleted_at column added already
    update_attribute(:deleted_at, Time.current)
  end
end

# Use this for Devise 2.1.0 and newer versions
class RegistrationsController < Devise::RegistrationsController

  def destroy
    resource.soft_delete
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
    set_flash_message :notice, :destroyed if is_navigational_format?
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
  end
end

# Use this for older Devise versions
class RegistrationsController < Devise::RegistrationsController
  def destroy
    resource.soft_delete
    set_flash_message :notice, :destroyed
    sign_out_and_redirect(resource)
  end
end

Maintenant, vous devriez être prêt. Utilisez les scopes pour filtrer les utilisateurs supprimés.

90voto

Peyman Points 774

Ajouter à réponse de hakunin :

Pour empêcher les utilisateurs "soft deleted" de se connecter, remplacez active_for_authentication? sur votre User modèle :

def active_for_authentication?
  super && !deleted_at
end

10voto

rausch Points 954

Vous pourriez utiliser agit_comme_paranoïaque pour votre modèle User, qui définit un deleted_at au lieu de supprimer l'objet.

7voto

Christopher Ickes Points 1663

Un tutoriel complet est disponible à l'adresse suivante Suppression douce d'un compte utilisateur Devise sur la page wiki de Devise.

Résumé :
1. Ajouter une colonne DATETIME "deleted_at".
2. Remplacez users/registrations#destroy dans vos routes.
3. Remplacer users/registrations#destroy dans le contrôleur des enregistrements.
4. Mettre à jour le modèle d'utilisateur avec un soft_delete et vérifier si l'utilisateur est actif lors de l'authentification.
5. Ajouter un message de suppression personnalisé

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X