Cómo “eliminar suavemente” el usuario con Devise

Actualmente utilizo Devise para el registro / autenticación de usuarios en un proyecto de Rails. Cuando un usuario desea cancelar su cuenta, el objeto de usuario se destruye, lo que deja mi aplicación en un estado no deseado.

¿Cuál es la forma más fácil de implementar una “eliminación suave”, es decir, solo eliminar datos personales y marcar al usuario como eliminado? Todavía quiero mantener todas las asociaciones de registro.

Supongo que primero tendré que introducir una nueva columna “eliminada” para los usuarios. Pero luego me quedo con este código predeterminado en la vista de perfil del usuario:

Unhappy? "Are you sure?", :method => :delete %>.

¿Dónde puedo encontrar el :delete método? ¿Cómo debo sobrescribir los métodos predeterminados de Devise?

Podría recomendar anular el método de destroy en su modelo de Usuario para hacer simplemente update_attribute(:deleted_at, Time.current) (en lugar de destruir), pero esta desviación de la API estándar podría volverse pesada en el futuro, así que aquí le update_attribute(:deleted_at, Time.current) cómo modificar el controlador.

Devise tiene un montón de controladores predeterminados fuera de la caja. La mejor manera de personalizarlos es crear su propio controlador heredando el controlador de dispositivo correspondiente. En este caso, estamos hablando de Devise::RegistrationsController , que se reconoce fácilmente mirando la fuente. Así que crea un nuevo controlador.

 class RegistrationsController < Devise::RegistrationsController end 

Ahora tenemos nuestro propio controlador que hereda completamente toda la lógica provista por el dispositivo. El siguiente paso es decirle al dispositivo que lo use en lugar del predeterminado. En tus rutas tienes línea de devise_for . Se debe cambiar para incluir el controlador de registros.

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

Esto parece extraño, pero tiene sentido porque, de forma predeterminada, es 'diseñar / registros', no simplemente 'registros'.

El siguiente paso es anular la acción de destroy en el controlador de registros. Cuando usa registration_path(:user), :method => :delete - ahí es donde se vincula. destroy acción del controlador de registros.

Actualmente el dispositivo hace lo siguiente.

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

En su lugar podemos usar este código. Primero vamos a agregar un nuevo método al modelo de User .

 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 

Ahora deberías estar todo listo. Utilice los ámbitos para filtrar a los usuarios eliminados.

Añadiendo a la respuesta de hakunin :

Para evitar que los usuarios “eliminados” inicien active_for_authentication? , anule active_for_authentication? en su modelo de User :

 def active_for_authentication? super && !deleted_at end 

Podría usar acts_as_paranoid para su modelo de usuario, que establece un deleted_at en lugar de eliminar el objeto.

Puede encontrar un tutorial completo en Soft Delete a Devise User Account en la página de la wiki de Devise.

Resumen:
1. Agregue una columna DATETIME de “deleted_at”
2. Anular usuarios / registros # destruir en sus rutas
3. Anular usuarios / registros # destruir en el controlador de registros
4. Actualice el modelo de usuario con un soft_delete y verifique si el usuario está activo en la autenticación
5. Agrega un mensaje personalizado de borrado