Custom user delete in Devise

Devise‘s default behaviour to delete a user is to actually delete them from the database. This isn’t the right approach for every site; in my case, I prefer to hang on to users in perpetuity and simply mark their record as deleted. The steps are simple.

Create a migration:

  def up
    add_column :users, :deleted_at, :timestamp

When deleted_at gets a value, we’ll consider the record deleted. Otherwise, it is active. Now we need to change the log in behaviour to check if the user has been deleted or not. Devise provides the valid_for_authentication? method, which you can override as I did below:

  def valid_for_authentication?
    result = super
    self.deleted_at.present? ? false : result

This method first checks whatever ‘super’ has to say about the user’s eligibility to log in, and then checks whether the deleted_at value has been set. If it has, the user is not allowed to log in (returning false). If it has not, then whatever the value for result is is used.

Finally, you’ll want a scope for active users:

scope :active, where(:deleted_at => nil, :confirmation_token => nil)

If you’re using devise_invitable you’ll also want to include :invitation_token => nil, or any other rules for what defines an active user.

  • ror

    Exactly whats needed but unclear on where to place the code you pasted. Could you add the right locations to your blog to where the code should be placed? would help a lot , thx

    • Amit Kumar Jangu

      I accomplished this using the method active_for_authentication
      You need to add the method to you User model (or whatever model name you are using for devise). Here the explaination, why :

      After authenticating a user and in each request, Devise checks if your model is active by calling model.active_for_authentication?
      However i tried with valid_for_authentication too. It worked fine :)

  • arnau sanchez

    This seems more declarative (and concise): def valid_for_authentication? !self.deleted_at && super end