LoginSignup
0
1

More than 1 year has passed since last update.

【初学者向け】Devise導入(nameカラム追加)

Last updated at Posted at 2021-05-26

Devise導入

Deviseとは
Deviseはユーザー登録やログイン機能などの認証に必要な機能を簡単に追加できるRails用のGemです。

▼公式ドキュメント▼

Gemをインストール

まずGemfileの最下部に以下のコードを追加

gemfile
gem 'devise'

追加したgemを反映させるためにbundle installを実行。

ターミナル
bundle inatall

次に、公式ドキュメントにあるように以下のコマンドを実行。

ターミナル
rails generate devise:install

上記、コマンド実行で2つのファイルが生成されます。
create config/initializers/devise.rb
create config/locales/devise.en.yml

ファイルを作成すると、以下のようなメッセージが表示されます。

こちらはdeviseを使う上での初期設定になります。

Qiita【devise】.png

Deviseの初期設定

1. デフォルトURLの指定

英文の例に書いてあったconfig.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
を以下のファイルに追加します。

メール送信の設定でメール送信の実装は行わない場合、飛ばしてOK。

config/environments/development.rb
Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

(省略)

  # mailer setting
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

2. root_urlの指定

http://localhost:3000/」 
にアクセスした際に表示されるページを指定します。
現状ページは1つも作っていないため、先に追加します。

homeコントローラーと、indexページを追加してみます。

ターミナル
rails g controller home index

関係ファイルの生成とルーティングの記述がされました。
Qiita【devise_2】.png

Qiita【devise_3】.png

3. flashメッセージの設定

フラッシュメッセージとは
ある動作を行った時、成功したのか、もしくは失敗したのか、相手に知らせる機能のことです。
例えばメールアドレスが正しくない状態でログインしようとしたときに、ログインに失敗した旨をメッセージとして表示したりします。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>DeviseApp</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    ----- 追加 ----
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    ---- ここまで追加 ----

    <%= yield %>
  </body>
</html>

4. DeviseのViewを生成

Deviseの導入で追加されるViewは、以下のコマンドを実行しなければデザインを変更できないので、デザインをカスタマイズするためにも実行します。

ターミナル
rails g devise:views

実行すると以下のようなファイルが生成されます。
コマンドを実行するだけでこれだけのファイルが生成されるのはありがたいですね!

Qiita【devise_4】.png

Userモデルを作成

以下のコマンドでDevise用のUserモデルを作成します。
(モデル名の値は任意です。作成したいモデル名で作成できます。今回はUserというモデル名で作成します。)

ターミナル
rails g devise User

Qiita【devise_5】.png

最後の行にroute devise_for :usersという記載があります。
これはconfig/routes.rbにdeviseのルーティングを追加しています。

config/routes.rb
Rails.application.routes.draw do
  --- 自動で追加される ---
  devise_for :users
  --- ここまで ---
  get 'home/index'
end

usersテーブルにnameカラムを追加

先ほどUserモデルを作成した際に、db/migrate/フォルダの中にマイグレーションファイルが作成されました。
Deviseのデフォルトではnameカラムがありません。
今回はユーザー名が必要なサービスを想定してカラム追加の記述をします。

db/migrate/20210525153350_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
   --- 一行追加 ---
      t.string :name,               null: false
     --- ここまで追加 ----
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

   (以下、省略)

Usersテーブル作成

マイグレーションファイルを作成しただけでは、テーブルに反映されないので、
マイグレーションファイルをテーブルに反映するにはマイグレーションファイルを実行する必要があります。
以下のコマンドで実行します。

ターミナル
rails db:migrate

バリデーションの設定

バリデーションとは
値がデータベースに保存される前に、そのデータが正しいかどうかを検証する仕組みをといいます。

ユーザーの新規登録をする際に、ユーザー名が何もない状態で登録できてしまう事を防ぐため、
nameカラムにバリデーションを設定します。models/user.rbに以下のコードを追加してください。

app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  --- 一行追加---
  validates :name, presence: true, length: { maximum: 20 }
  --- ここまで ---
end

presence: trueは値が空ではないということ確かめるバリデーションです。
また、length: { maximum: 20 }は値の文字数が最大20文字までということを表すバリデーションです。
つまりこの場合、登録するユーザーは名前必須、かつ20文字以内で入力しないといけません。

nameカラムを保存できるようにする

デフォルトだとメールアドレスとパスワードだけパラメータを受け取るようにストロングパラメーターが設定されています。

ストロングパラメーターとは
指定していないパラメーターを受け取るのを禁止します。
外部に公開する必要のない情報を誤って公開してしまう可能性が生じるため、
そのような事態を防ぐために行います。

今回nameカラムを保存できるようにストロングパラメーターを追記します。

app/models/user.rb
class ApplicationController < ActionController::Base

--- 追加 ---
  protect_from_forgery with: :exception           #クロスサイトリクエストフォージェリ (CSRF)への対応策

  before_action :authenticate_user!               #ユーザーがログインしているかどうか確認
  before_action :configure_permitted_parameters, if: :devise_controller?
                                                  #devise_controllerを使うときしか処理しない

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
      devise_parameter_sanitizer.permit(:account_update, keys: [:name])
    end
--- ここまで追加 ---
end

protect_from_forgery with: :exceptionというコードはクロスサイトリクエストフォージェリ (CSRF)への対応策のコードです。
クロスサイトリクエストフォージェリー(CSRF)とは利用者の意図しないWebアプリケーション上の処理実行される攻撃手法のことだそうです。

▼クロスサイトリクエストフォージェリー(CSRF)についての参考

またApplicationコントローラーは全てのコントローラーが読まれる前に必ず読まれるコントローラーです。
例えばhomeコントローラーのindexアクションが読まれる前にApplicationコントローラーが読まれます。

ただ、nameカラムを保存できるようにする記述はサインアップやアカウントをアップデートするときだけにしか必要がありません。

なので、before_action :configure_permitted_parameters, if: :devise_controller?と記載することで、configure_permitted_parametersというメソッドは、devise_controllerを使うときしか処理しないということをApplicationコントローラーを読み込む前に判断します。

サインアップ画面のビューを変更する

生成されたビューのままだと下記画像のようにnameの入力フォームが存在しません。

Qiita【devise_7】.png

下記のようにコードを追加します。

app/views/devise/registrations/new.html.erb
<h2>Sign up</h2>

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

  --- 追加 ---
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
  </div>
  --- ここまで追加 ---

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

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>

nameの入力フォームが追加されました。

Qiita【devise_8】.png

以上で、終了です。

Deviseを使うことにより手軽にユーザー認証機能を実装できます。
また、カラムを追加して入力フォームを充実させたり、モデルのモジュールの設定を変えることで、一定回数サインインを失敗するとアカウントをロックしたり・TwitterやFacebookなどの認証を追加できるようになるようです。
また、別の機会に学ぼうと思います。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1