Sometimes, when I find the time (which happens roughly 23–37 times each and every day), I visit Stack Overflow, hopefully to solve a problem, but regularly leave irritated and heartbroken because the solution is too geeky and doesn’t explain the core of the problem (translation: it’s hard to copy/paste). The reason for writing this post was a few hours of struggle reading a lot of unnecessary code without reasonable explanations and the need to stop deleting important stuff from the database, so I just wanted to create something easy, quick, and readable for the community. Enough of the smart talk; let’s begin with the real reason why we are here.
I assume you already passed the Devise tutorial and already have an existing User model in your project (if not, do it here!). So, first off, we are going to run this command inside of our console to add a column named deactivated with a bool value to our User model:
rails g migration add_deactivated_to_users deactivated:boolean
Just to be sure before running migrations – check your newly created file in db/migrate, it should contain the following:
class AddDeactivatedToUsers < ActiveRecord::Migration
add_column :users, :deactivated, :boolean
If it looks as inviting as this, run this command in your console:
Now it’s time for some real stuff, we are going to override the User destroy method. Open up your user.rb in your models folder and add this:
update_attributes(deactivated: true) unless deactivated
A quick explanation for curious souls: when the destroy method is called on the User model, we are updating the User’s deactivated column to true only if the user is not currently deactivated.
Now when a User is being a baddie, they won’t be deleted, they’ll only get deactivated. Still, we have to prevent them from logging in. If you closed your user.rb file, open it again and put this inside:
super && !deactivated
This method will be our insurance that the user can only login when he/she is not deactivated. When the user is deactivated and tries to login, he/she will see the following message: ‘Your account is not activated yet’. To mix it up a bit or use something more appropriate for your own use case, we will need to change our local Devise messages.
Open up config/locales/devise.en.yml (if you have more supported languages, be sure to change the message on them too) and you will find our message under devise: failure: inactive: and change it to anything you find good for this bad user.
I hope you liked it and that it helps. Thanks for reading.