RoR User Auth
Devise is the most widely used authentication gem for Rails. It handles user registration, login, logout, password reset, and email confirmation out of the box. Instead of writing authentication from scratch — which is complex and error-prone — you install Devise and get a secure, battle-tested system in minutes.
Install Devise
Add Devise to your Gemfile:
gem "devise"
Run the installer:
bundle install rails generate devise:install
The installer prints a few instructions. Follow them:
1. Add this to config/environments/development.rb:
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
2. Make sure you have a root route in config/routes.rb:
root "pages#home"
3. Add flash messages to app/views/layouts/application.html.erb:
<%= notice %>
<%= alert %>
Generate the User Model
rails generate devise User rails db:migrate
This creates a fully configured User model and migration with columns for email, encrypted password, reset password tokens, and remember-me tokens.
What Devise Generates Automatically
Routes added to config/routes.rb: devise_for :users This creates all these URLs: GET /users/sign_in ← login form POST /users/sign_in ← submit login DELETE /users/sign_out ← logout GET /users/sign_up ← registration form POST /users/registration ← submit registration GET /users/password/new ← forgot password form POST /users/password ← send reset email GET /users/password/edit ← reset password form
Protecting Pages with Authentication
Add before_action :authenticate_user! to any controller to require login:
class ArticlesController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
# index and show are public — no login needed
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
# new, create, edit, update, destroy require login
def new
@article = Article.new
end
end
Devise Helper Methods
Devise provides helpers available in controllers and views:
current_user → the logged-in User object (nil if not logged in) user_signed_in? → true if someone is logged in user_signed_out? → true if no one is logged in authenticate_user! → redirects to login if not signed in sign_in(@user) → programmatically log in a user sign_out(current_user)→ programmatically log out
Use them in views:
<% if user_signed_in? %> <p>Welcome, <%= current_user.email %></p> <%= link_to "Log Out", destroy_user_session_path, method: :delete %> <% else %> <%= link_to "Sign In", new_user_session_path %> <%= link_to "Sign Up", new_user_registration_path %> <% end %>
Add Extra Fields to the User Model
Devise manages email and password. For extra fields like name, generate a migration:
rails generate migration AddNameToUsers name:string rails db:migrate
Then permit the extra field in your ApplicationController:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
end
Customizing Devise Views
Devise uses its own built-in views by default. Generate them to customize the HTML:
rails generate devise:views
This creates editable view files in app/views/devise/:
app/views/devise/
sessions/
new.html.erb ← login form
registrations/
new.html.erb ← sign up form
edit.html.erb ← edit profile form
passwords/
new.html.erb ← forgot password form
edit.html.erb ← reset password form
confirmations/
new.html.erb ← resend confirmation email
Devise Authentication Flow
User visits /posts/new (protected by authenticate_user!)
|
v
Devise checks: is current_user present?
|
+-- Yes → Continue to posts#new
|
+-- No → Redirect to /users/sign_in
User fills in email and password, submits
|
v
Devise looks up User by email
Devise compares password with stored hash using bcrypt
|
+-- Match → Create session, set current_user, redirect back to /posts/new
|
+-- No match → Show "Invalid email or password"
Devise Modules
Devise is modular. Enable only what you need in your User model:
class User < ApplicationRecord
devise :database_authenticatable, ← email/password auth
:registerable, ← sign up
:recoverable, ← password reset
:rememberable, ← "Remember me" checkbox
:validatable, ← email and password validations
:confirmable, ← email confirmation
:lockable, ← lock account after failed logins
:trackable ← track sign-in count and IP
end
Start with the first five modules for most apps. Add :confirmable when you need verified email addresses.
Connecting Posts to the Logged-In User
def create
@article = current_user.articles.build(article_params)
if @article.save
redirect_to @article, notice: "Article published."
else
render :new, status: :unprocessable_entity
end
end
Using current_user.articles.build automatically sets the user_id on the new article to the logged-in user's ID. No manual assignment needed.
Devise handles the hardest parts of authentication correctly — password hashing, session management, and secure token generation. Use it instead of building authentication manually.
