ruby on rails - rails - Cómo "borrar de forma suave" al usuario con Devise
ruby on rails devise (4)
Actualmente uso Devise para el registro / autenticación de usuarios en un proyecto de Rails. Cuando un usuario desea cancelar su cuenta, el objeto del 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 registros.
Supongo que primero tendré que presentar una nueva columna "eliminada" para los usuarios. Pero luego estoy atascado con este código predeterminado en la vista de perfil del usuario:
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
¿Dónde puedo encontrar el :delete
método de :delete
? ¿Cómo debo sobrescribir los métodos predeterminados de Devise?
Añadiendo a la respuesta de hakunin :
Para evitar que los usuarios "eliminados temporalmente" active_for_authentication?
, anule active_for_authentication?
en su modelo de User
:
def active_for_authentication?
super && !deleted_at
end
Podría aconsejar reemplazar método de destroy
en su modelo de usuario simplemente hacer update_attribute(:deleted_at, Time.current)
(en lugar de destruir realmente), pero esta desviación de API estándar podría volverse onerosa en el futuro, así que aquí está cómo modificar el controlador.
Devise tiene un montón de controladores predeterminados listos para usar. La mejor forma de personalizarlos es crear su propio controlador heredando el controlador de diseño correspondiente. En este caso, estamos hablando de Devise::RegistrationsController
, que se reconoce fácilmente al mirar la fuente. Entonces crea un nuevo controlador.
class RegistrationsController < Devise::RegistrationsController
end
Ahora tenemos nuestro propio controlador heredando completamente toda la lógica proporcionada por el dispositivo. El siguiente paso es decirle a idear que lo use en lugar del predeterminado. En tus rutas has devise_for
línea. Debería cambiarse para incluir el controlador de registros.
devise_for :users, :controllers => { :registrations => ''registrations'' }
Esto parece extraño, pero tiene sentido porque, por defecto, es ''diseño / 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. Para destroy
acción del controlador de registros.
Actualmente el diseño 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 agreguemos 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. Use ámbitos para filtrar los usuarios eliminados.
Puede usar acts_as_paranoid para su modelo de usuario, que establece un deleted_at en lugar de eliminar el objeto.
Se puede encontrar un tutorial completo en Soft Delete a Devise User Account en la página wiki de Devise.
Resumen:
1. Agregue una columna "DATETIME" "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 compruebe si el usuario está activo en la autenticación
5. Agregue un mensaje de eliminación personalizado