shou2017.com
JP

Using devise with Rails 5.2

Sat Aug 4, 2018
Sat Aug 10, 2024

Environment

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
$ rails -v
Rails 5.2.0

In Rails, you can easily implement login functionality by using a gem called devise.

Initial setup for devise

Add gem 'devise' to your Gemfile:

gem 'devise'

After adding it, run bundle install.

Next, run rails g devise:install to generate the initial settings and files required for devise.

$ rails g devise:install

When you run rails g devise:install, the following will be displayed. Follow the instructions to configure it.

$ rails g devise:install
Running via Spring preloader in process 9646
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. You can copy Devise views (for customization) to your app by running:

If you haven’t done the above steps yet, follow them. For step 1, add the following to config/environments/development.rb:

 <!-- config/environments/development.rb -->

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

Creating the User model

Create the user model as a member by running:

$ rails g devise user

When you run rails g devise user, routing settings for devise will be automatically added.

Creating the users table

When you use devise, running rails g devise user will also create a migration file for devise.

Check the migration file to ensure the table is created.

Creating views

Next is the view side. This is also done by simply running rails g devise:views.

$ rails g devise:views

The basic setup for devise is now complete. We didn’t create a controller because when devise routing is executed, the process is passed to the controller within the gem.

Adding columns to devise

Let’s try adding a column called name to devise.

$ rails g migration AddNameToUsers name:string
$ rake db:migrate

Add name to the strong parameters of devise.

Devise has a method called configure_permitted_parameters to set 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

  # before_action to execute the method defined below
  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 the strong parameters of devise
    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 added to before_action with if: :devise_controller? to activate it only for the devise controller.

※protected and private

Methods written within private cannot be called from outside the class, but methods within protected can be called. Writing methods within protected prevents them from being called unexpectedly.

Add an input field for name to the registration screen.

<!-- app/views/devise/registrations/new.html.erb -->

<div class="field">
  <%= f.email_field :email, autofocus: true, class: "form-control", placeholder: "メールアドレス" %>
</div>

<!-- Add an input field for name -->
<div class="field">
  <%= f.text_field :name, class: "form-control", placeholder: "名前" %>
</div>

<div class="field">
  <%= f.password_field :password, autocomplete: "off", class: "form-control", placeholder: "パスワード" %>
</div>

Add an edit field for name to the edit screen.

<!-- app/views/devise/registrations/edit.html.erb -->

<div class="field">
  <%= f.label :メールアドレス %><br />
  <%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>

<!-- Add an input field for name -->
<div class="field">
  <%= f.label :名前 %><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 are using heroku

If you are using heroku, you need to configure it for heroku.

Enable config.secret_key in config/initializers/devise.rb.

See Also