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.
rails generate migration add_username_to_users username:string:uniq
run the migration
STEP TWO: MODIFY APPLICATION CONTROLLER
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
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.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.