gem Devise. 10 Step to install in 2023
Hello everyone! Today it is time to revisit installation and setup process of gem devise. Devise is the most popular and famous Ruby on Rails gem for authentication. Simpler, If you want to provide login/logout functionality in a Ruby on Rails application, gem devise is good choice for you!
Rails 7. Start Kit is the Best Playground
Any author of a RoR article should provide to readers a way to review a code and a way how to run an application to check a result.
Great news! No problems anymore. We have Rails 7. Start Kit.
All the code required you can review here PULL REQUEST.
The application with the result you can run with using an only command
eval "$(curl -sSL rails-start.com)"
Devise Installation Step by Step
Step 1
Add the gem in Gemfile
# Authentication solution
gem "devise", "4.8.1"
Step 2
Install the gem with running bundle install. Run in terminal from the root of your app:
$ bundle install
Step 3
Generate User Model. Run in terminal from the root of your app:
$ rails generate devise user
Step 4
Choose and uncomment the most useful and common settings in app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable,
:registerable,
:confirmable,
:rememberable,
:recoverable,
:trackable,
:validatable
end
Step 5
Check and uncomment required fields in order to the options you have chosen for the User Model
In the file db/migrate/XXX_devise_create_users.rb you should have the following:
# frozen_string_literal: true
# rails generate devise user
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
class DeviseCreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ''
t.string :encrypted_password, null: false, default: ''
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
# NameError in Devise::RegistrationsController#create
# undefined local variable or method `unconfirmed_email'
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
Potential problem 1
You should be careful here. I missed uncommenting unconfirmed_email and later got the following issue. Iw was not very clear to me, that I need to uncomment it. There was a mention of reconfirmable option bit in my User Model I have confirmable. At a first moment I thought that these things are different.
Step 6
Let’s setup typical routes in config/routes.rb
Rails.application.routes.draw do
devise_for :users
# Defines the root path route ("/")
root 'demo#index'
end
Step 7
Run migration command to create User Model in your database. Run in terminal from the root of your app:
$ rake db:migrate
Step 8
It is difficult to me to imagine how to work with Devise without a customisation of views and mailers. Now I install the view files. Run in terminal from the root of your app:
$ rails generate devise:views
It will create app/views/devise folder with view files
Some most useful views I’ve wrapped with <div class=”devise”> and added to my CSS some very initial CSS rules like that
.devise {
background-color: aliceblue;
padding: 20px;
margin-bottom: 20px;
}
.devise input[type=email],
.devise input[type=password],
.devise input[type=submit] {
font-size: 16px;
padding: 10px;
}
.devise .field,
.devise .actions {
margin-bottom: 20px;
}
.devise #error_explanation {
padding: 10px;
background: antiquewhite;
border: 1px solid rgb(242, 189, 120);
list-style: circle;
}
Step 9
Add in your Layout lines to check routes and registration process
<% if user_signed_in? %>
<%= current_user.email %> |
<%= link_to "Sign Out", destroy_user_session_path%>
<% else %>
<%= link_to "Sign In", new_user_session_path %> |
<%= link_to "Sign Up", new_user_registration_path %>
<% end %>
Potential Problem 2
If you do not use something like ujs or turbo-rails than Sign Out link will work by default via http GET method, but Devise expects DELETE method. It may lead you the the issue like that
You have multiple options here.
- Allow using GET method for log out
- Use turbo-rails
- Emulate DELETE method with button_to helper
I’ve chosen the first option and made a change in config/initializers/devise.rb
# The default HTTP method used to sign out a resource. Default is :delete.
# Devise. Make sign out work with GET method
config.sign_out_via = :get
Step 10
Run the app and play with Devise.
Righ After you set up your data you can go to Mailer Service and confirm your registration
That is it!
Happy coding with Rails 7. Start Kit