未経験からのRuby on Rails|ログイン機能

初めに

アプリケーション開発において一からログイン認証機能を作るというのはとても大変です。

Rails では、その苦労を取り除くdeviseというモジュールが提供されています。
実際に使ってみましょう。

device モジュールの追加

Ruby on Rails アプリケーションにモジュールを追加するために、Gemfile に追加したいモジュールを追記してあげる必要があります。
Gemfile の最後の行に以下を追記してみましょう。

gem ‘devise’

アプリケーションに読みかませるために以下コマンドを実行し、モジュールをインストールしてください。

bundle install

device モジュールの追加

device を使用するための初期設定を行います。
以下コマンドを叩くことで、設定ファイルがアプリケーションディレクトリに作成されます。

rails g devise:install

設定ファイルが作成されたら、準備完了です。

ユーザーテーブルの作成

device にはユーザー管理用のテーブルを自動的に作成してくれる機能があります。
これを利用することで面倒なテーブル設計を行う必要がなくなります。

実際に作ってみましょう。

rails g devise user

これで準備完了です。

アプリケーションディレクトリ/users/sign_up にログインしてください。

以上が表示されたら成功です。

実際にサインアップが表示されたら適当に Email と Password を入力してログインを完了してください。ログインが完了します。

ログイン判定

ログインが完了したか view 側で制御可能です。

以下構文をアプリケーション内の適当な View に記載してみましょう

当ブログでは application.html.erb を編集します。

/app/views/layouts/application.html.erb

<% if user_signed_in? %>

  • <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
  • <% else %>
  • <%= link_to "新規登録", new_user_registration_path %>
  • <%= link_to "ログイン", new_user_session_path %>
  • <% end %>

    <% if user_signed_in? %>に注目してください。
    user がログイン状態の場合、直下のコンテンツを表示そうでない場合は
    <% else %>から下を表示します。

    ユーザー詳細画面

    もちろんこのユーザー情報はコントローラーを介して操作できます。

    試しにユーザー詳細画面を作成してみます。以下コマンドを入力してください。

    rails g controller users

    users コントローラーの作成が完了したら、index アクションを追加し
    詳細画面へのページリンクをトップページに追加します。

    /app/controllers/users_controller.rb

    class UsersController < ApplicationController def index @user = User.find(params[:format]) end end

    /config/routes.rb

    Rails.application.routes.draw do devise_for :users root to: ‘homes#top’ resources :users, only: [:show] end

    /app/views/layouts/application.html.erb

    <% if user_signed_in? %>

  • <%= link_to "home", "/" %>
  • <%= link_to 'mypage', users_show_path(current_user.id) %>
  • <%= link_to "Books", destroy_user_session_path, method: :delete %>
  •   <li>
        <%= link\_to "logout", destroy\_user\_session\_path, method: :delete %>
      </li>
    <% else %>
      <li>
        <%= link\_to "HOME", '/' %>
      </li>
      <li>
        <%= link\_to "About", about\_top\_path %>
      </li>
      <li>
        <%= link\_to "sign up", new\_user\_registration\_path %>
      </li>
      <li>
        <%= link\_to "login", new\_user\_session\_path %>
      </li>
    

    <% end %>

    /app/views/users/index.html.erb (新規作成

    ユーザー名:<%= @user.name %>

    email:<%= @user.email %>

    パスワード:<%= @user.encrypted\_password %>

    試しにユーザ登録を行い、
    /users/show.1 に飛んでみましょう
    登録ユーザーが表示されるはずです。

    おまけ

    ユーザー登録に Email/Password 以外に名前入力も要求する方法を紹介します。

    /db/migrate/[日時]_devise_create_users.rb

    # frozen_string_literal: true

    class DeviseCreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" t.string :name, 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
    
      ## 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

    ユーザー登録の際に名前を登録するカラムが必要になるので、
    マイグレーションファイルに以下を追記してください。

    t.string :name, null: false, default: ""

    そしてマイグレーションします。
    今回は前回作成したテーブルを初期化する必要があるので reset オプションを追加してください。

    rails db:migrate:reset

    次にフォーム送信に必要な strong parameters を編集する必要があります。
    ですが、device モジュールのコントローラを直接編集できません。

    device のコントローラーを修正したい場合は、application_controller を修正してください。

    今回は name カラムを追加しているので、それを認証時に必要な情報として追加します。

    /app/controllers/application_controller.rb

    class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller?

    protected

    def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name]) end end

    やっていることを説明すると、全ての画面に対してアクセスを行ったときに、まず初めに device_controller か判定を行い、そうであった場合はその下で作成しているカスタムストロングパラメータで判定を行います。

    次に name のフォーム入力を view 側で作成します。

    device が提供しているデフォルトの画面のカスタマイズを行うには以下コマンドを実行します。

    rails g devise:views

    以上コマンドを叩くと以下フォルダが作成されます。

    今回編集する必要があるコードは作成されたフォルダ直下の new.html.erb です。

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

    Sign up

    <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= render “devise/shared/error_messages”, resource: resource %>

    <%= f.label :name %>
    <%= f.text\_field :name, autofocus: true %>
    <%= f.label :email %>
    <%= f.email\_field :email, autofocus: true, autocomplete: "email" %>
    <%= f.label :password %> <% if @minimum\_password\_length %> (<%= @minimum\_password\_length %> characters minimum) <% end %>
    <%= f.password\_field :password, autocomplete: "new-password" %>
    <%= f.label :password\_confirmation %>
    <%= f.password\_field :password\_confirmation, autocomplete: "new-password" %>
    <%= f.submit "Sign up" %>
    <% end %>

    <%= render “devise/shared/links” %>

    name フォームを追記しました。

    <%= f.label :name %>
    <%= f.text\_field :name, autofocus: true %>

    /users/sign_up アクセスすると以下画面が表示されるかと思います。

    これでユーザー登録の際に名前をユーザーに入力してもらうことができます。