[Ruby on Rails] How to log in with only your name and password using the gem devise

Target

画面収録 2020-09-01 22.17.23.mov.gif

Development environment

ruby 2.5.7 Rails 5.2.4.3 OS: macOS Catalina

Premise

Created a homes controller and described the following.

config/routes.rb


root 'homes#top'
get 'mypage', to: 'homes#mypage'

app/controllers/homes_controller.rb


class HomesController < ApplicationController
 def top
 end
 def mypage
 end
end

1, install devise

Add the following to the end of the Gemfile.

Gemfile



gem 'devise'

After saving, move to the terminal and execute the following.

Terminal


$ bundle install

Terminal


$ rails g devise:install
Explanation rails g devise: install does the initial setup of devise.

It is OK if the following display is displayed.

Terminal


===============================================================================

Depending on your application's configuration some manual setup may be required:

  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.

     * Required for all applications. *

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

       root to: "home#index"
     
     * Not required for API-only Applications *

  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>

     * Not required for API-only Applications *

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

       rails g devise:views
       
     * Not required *

===============================================================================
On error If you see an error, it's likely an error due to a Rails update. Review gem'sqlite3' in Gemfile.

2, display the login screen

Create table (add name)

Unlike the usual description, Described as "rails g devise model name" which is a unique rule of devise. To create the User model this time, execute the following on the terminal.

Terminal


$ rails g devise User

Describe t.string: name in the following folder.

db/migrate/xxxxxxxxxxxxx_devise_create_users.rb


...

      t.string :name  #← Add here
      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

Supplement 1 By writing null: false, you can prevent saving in the empty state. About null: false [here](https://qiita.com/ryuuuuuuuuuu/items/2841cddf8b541c336ebd)
Supplement 2 If you want to add registration information other than your name, Possible by writing in the same way as t.string: name. ex) t.string: phone_number etc.

Then move to the terminal and do the following:

Terminal


$ rails db:migrate

It is OK if the following display is displayed.

Terminal


== 20200901103907 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0038s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0013s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0013s
== 20200901103907 DeviseCreateUsers: migrated (0.0067s) =======================

Create view (add name)

Terminal


$ rails g devise:views users
Explanation By setting rails g devise: views users devise views can be stored in app / views / users. You can also edit views.

Describe the following in <% = form_for%> on the 3rd line.

erb:app/views/devise/registrations/new.html.erb


...

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
  </div>

...

Change the following 3 emails to name and email_field to text_field

erb:app/views/devise/sessions/new.html.erb


  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>
  
  ↓

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
  </div>

Uncomment the following description near line 49 and change [: email] to [: name]

config/initializers/devise.rb



config.authentication_keys = [:name]

View before login

erb:app/views/homes/top.html.erb


<%= link_to 'sign up', new_user_registration_path %><br>
<%= link_to 'Login', new_user_session_path %>

View after login

erb:app/views/homes/mypage.html.erb


<%= current_user.name %><br>
<%= current_user.email %><br>
<%= link_to 'Log out', destroy_user_session_path, method: :delete %>
Explanation current_user is a helper method of devise and can get user information during login. At the time of logout, although there is no cover with the http method, It is sure to specify method:: delete.

3, Create controller

Terminal


$ rails g devise:controllers users

Uncomment lines 4, 44-46, 54-56, Changed: attribute on line 45 to: name,: email. Change the path where you want to skip super (resource) on the 55th line.

app/controllers/users/registrations_controller.rb


# frozen_string_literal: true

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

...

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :email])
  end

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_account_update_params
  #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
  # end

  # The path used after sign up.
  def after_sign_up_path_for(resource)
    mypage_path
  end

  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
end

Explanation Specify the column save permission when registering as a new member on lines 44 to 46. Specify the transition destination after new member registration on the 55th to 56th lines.
Supplement The transition destination after updating the member information can also be changed as described above. The description is OK on the 57th line or less.  def after_update_path_for(resource)   mypage_path  end

Added below line 27.

app/controllers/users/sessions_controller.rb


...

  def after_sign_in_path_for(resource)
    mypage_path
  end

  def after_sign_out_path_for(resource)
    root_path
  end
end

Explanation Specify the transition destination at login and logout.

devise_for: users Additional description below.

config/routes.rb


Rails.application.routes.draw do
  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
  }
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  root 'homes#top'
  get 'mypage', to: 'homes#mypage'
end

Recommended Posts