What is the best way to ban/block users with Devise for Rails?

I would do it like this:

def after_sign_in_path_for(resource)
  if resource.is_a?(User) && resource.banned?
    sign_out resource
    banned_user_path
  else
   super
  end
end

A better solution is to override the active_for_authentication? method on the devise model (User). Like so:

    def active_for_authentication?
      super && !self.banned?
    end

The best approach is to do it in Devise way:

Below assumes that you are using Devise database_authenticatable module and your application's users model names User.

1. Implement an account_active? method.

Add boolean account_active column in users table or define account_active? method in User model (you can chose your own method name). For example:

    # app/models/user.rb
    def account_active?
      blocked_at.nil?
    end

2. Overwrite the active_for_authentication? method in your model (User).

    # app/models/user.rb
    def active_for_authentication?
      super && account_active?
    end

3. Add method which returns translation for flash message.

Whenever active_for_authentication? returns false, Devise asks the reason why your model is inactive using the inactive_message method.

    # app/models/user.rb 
    def inactive_message
      account_active? ? super : :locked
    end

And that's it. You don't need to care about sign_out or redirect_to user.

Moreover, user is locked immediately, with next request, not after next sign in.

More: devise/authenticatable.rb.