In Rails, you can easily implement login functionality using a gem called devise.
Add the following to your Gemfile:
gem 'devise'
Then run bundle install
.
Next, execute rails g devise:install
to generate the necessary initial setup and files for devise.
Create a user model to represent members:
$ rails g devise user
When you run rails g devise <model_name>
, routing settings for devise are automatically added.
By running rails g devise user
, a migration file for devise is also created. Check the migration file to confirm the table structure.
Next, generate the views. Simply run:
$ rails g devise:views
This completes the basic setup for devise. No controller was created because the routing for devise passes processing to the controllers within the gem.
Let’s try adding a name
column to devise.
$ rails g migration AddNameToUsers name:string
$ rake db:migrate
Add name
to devise’s strong parameters. Devise has a method called configure_permitted_parameters
for setting strong parameters, so add it there.
<!-- app/controllers/application_controller.rb -->
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
# Execute the method defined below with before_action
before_action :configure_permitted_parameters, if: :devise_controller?
# Assign the array [:name] to the variable PERMISSIBLE_ATTRIBUTES
PERMISSIBLE_ATTRIBUTES = %i(name)
protected
# Define a method to add columns to devise’s strong parameters
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: PERMISSIBLE_ATTRIBUTES)
devise_parameter_sanitizer.permit(:account_update, keys: PERMISSIBLE_ATTRIBUTES)
end
configure_permitted_parameters
is triggered only for devise controllers by adding if: :devise_controller?
to before_action
.
<!-- app/views/devise/registrations/new.html.erb -->
<div class="field">
<%= f.email_field :email, autofocus: true, class: "form-control", placeholder: "Email Address" %>
</div>
<!-- Add a field for name input -->
<div class="field">
<%= f.text_field :name, class: "form-control", placeholder: "Name" %>
</div>
<div class="field">
<%= f.password_field :password, autocomplete: "off", class: "form-control", placeholder: "Password" %>
</div>
<!-- app/views/devise/registrations/edit.html.erb -->
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<!-- Add a field for name input -->
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, class: "form-control" %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
If you’re using Heroku, additional configuration is required. Enable config.secret_key
in config/initializers/devise.rb
.