Adding Username to Devise

Posted by lawrend on September 16, 2017

Devise is great for out-of-the-box user authentication, but it can feel like you get what Devise gives you and nothing else.

I had a bit of a struggle adding a username to Devise so I thought I’d store it here for easy reference in case I or anyone else needs it again.

STEP ONE: ADD USERNAME FIELD TO USERS TABLE

Yeah, I know it’s super basic and who would ever forget this first step? Me? Yes. Yes I did. Shut up, it’s not funny.

Migration rails generate migration add_username_to_users username:string:uniq

run the migration rake db:migrate

STEP TWO: MODIFY APPLICATION CONTROLLER

Modify application_controller.rb by adding a method configure_permitted_parameters and add :username, :email, :password, :password_confirmation, and :remember_me.

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end

STEP THREE: CREATE A VIRTUAL ATTRIBUTE CALLED ‘LOGIN’ IN THE USER MODEL

You can add login as an attr_accessor in your User model and then it will refer to either :username or :email.

class User < ApplicationRecord

attr_accessor :login

If :login is going to be used elsewhere in your code, write a reader and writer instead of using attr_accessor.

class User < ApplicationRecord

  def login=(login)
    @login = login
  end

  def login
    @login || self.username || self.email
  end

STEP FOUR: TELL DEVISE TO USE LOGIN IN AUTHENTICATION KEYS

Finally, add this to your config/initializers/devise.rb file:

config.authentication_keys = [ :login ]

That should do it. You still have to modify your views so username shows up, but now you can go cray throwing :username into your code and letting your users know they are special, because they are, dammit.