Using Devise Gem in Rails for Username-Based Login
Table of contents
Introduction
Hey there fellow developers! You know that feeling when you're trying to set up a new Rails app and you want to use the Devise gem for authentication, but you're dead set on using usernames for login instead of emails? I've been there, trust me. I've spent countless hours Googling, reading through forums, and scratching my head, wondering how on earth to make it work. But fear not, because, after some serious tinkering and a bit of trial and error, I've cracked the code. And guess what? I'm not keeping this gem of knowledge to myself. I'm sharing it with you, my fellow tech enthusiast, so you can breeze through this process without the hassle and stress that I went through.
Step 1: Setting Up Your Rails Application
Before we dive into the Devise gem setup, let's make sure you have a Rails application up and running. If you don't have one yet, fire up your terminal and run the following command:
rails new LoginApp
Navigate into your app's directory:
cd LoginApp
Step 2: Adding Devise to Your Gemfile
Now that you have your Rails app set up, it's time to add the Devise gem to your Gemfile. Open the Gemfile using your favorite text editor and add the following line:
gem 'devise'
Save the file and run the following command to install the gem:
bundle install
Step 3: Generating Devise Views and User Model
Devise provides a generator to create its views and user model. Let's go ahead and run it:
rails generate devise:install
rails generate devise User
This will generate the necessary views and a User model with default attributes, including an email column. But we want to use usernames, right? So, let's make some changes.
Step 4: Modifying the User Model
Open the app/models/user.rb
file and update it as follows:
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable
# Add the lines below to use username
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_hash).where(["username = :value OR lower(email) = lower(:value)", { value: login }]).first
else
where(conditions.to_hash).first
end
end
end
In the code above, we've defined a custom method find_first_by_auth_conditions
that allows us to use either the username or the email for authentication.
Step 5: Updating the Devise Views
Now, we need to update the Devise views to use usernames instead of emails. In your app/views/devise/sessions/new.html.erb
and app/views/devise/registrations/new.html.erb
files, replace occurrences of email
with login
.
Step 6: Configuring Routes
Open your config/routes.rb
file and add the following line to configure the routes for Devise:
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'register' }
Step 7: Updating Controllers and Views
Now, you'll need to update any references to email
in your controllers and views to use login
instead. This includes places like your SessionsController
and RegistrationsController
, as well as any other custom controllers you might have.
Step 8: Testing Your Setup
Phew! We've done a lot of work, so let's make sure everything's running smoothly. Start your Rails server:
rails server
Visit http://localhost:3000/register
in your browser to access the registration page and sign up using a username and password.
Conclusion
Congratulations, my friend! You've successfully set up Devise to use usernames for login in your Rails application. I hope this article has saved you some valuable time and spared you the headaches I went through. Keep coding and building amazing things!
References:
Devise GitHub Repository: https://github.com/heartcombo/devise
Devise Wiki: https://github.com/heartcombo/devise/wiki
Rails Guides on Devise: https://guides.rubyonrails.org/v5.2/devise.html
Stack Overflow - Using Username for Login with Devise: https://stackoverflow.com/questions/1177863/using-username-as-attribute-with-devise
Now go on, rock that username-based authentication like a pro! ๐