Deviseを使って一般ユーザーのログイン機能を実装する

前回までblogの機能を作りました。

maa0917.hatenablog.com

今回はDeviseを使って一般ユーザーのログイン機能を実装していきます。

  • Deviseを使って一般ユーザのログイン機能実装
  • ユーザー名(name)のカラムを追加
  • 未ログイン状態ではブログの閲覧のみ権限
  • devise-i18nでメッセージを日本語化

Deviseの導入

deviseと日本語化のためのdevise-i18nをインストールします。

(Gemlfile)

gem 'devise'
gem 'devise-i18n'
$ bundle install

以下のコマンドを実行します。

rails g devise:install

ターミナルにいくつか指示が出てきます。 今回はその指示のrootの設定をします。

(config/routes.rb)

Rails.application.routes.draw do
  root 'blogs#index'
  resources :blogs
end

これでログイン後に、rootにリダイレクトされます。

Userモデルの作成

Userモデルを作成します。

rails g devise user

ユーザー情報としてユーザーネームも持たせたいのでuserテーブルにnameカラム追加します。

$ rails g migration AddColumnToUser name:string

NN制約つけるためにnull: false, default: ""を追記します。

(db:migrate/**************_add_column_to_user.rb)

class AddColumnToUser < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :name, :string, null: false, default: ""
  end
end

マイグレーションします。

$ rails db:migrate

反映させるには一度サーバを立ち上げ直す必要があります。

$ rails s

ストロングパタメータの設定

つづいてストロングパラメータの設定をします。

deviseのコントローラはgem本体にあるため、ストロングパラメーターapplication_controllerに設定します。専用のメソッドconfigure_permitted_parametersを使います。

(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: [:name])
  end
end

if: :devise_controller?によって、deviseコントローラのみでの制御をしています。

viewの作成

必要なviewを作成します。

rails g devise:views

form_for内に以下を追加します。

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

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

editにも追加します。 (app/views/devise/registrations/edit.html.erb)

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

ログインユーザーの権限設定

コントローラでauthenticate_user!メソッドを使って制限をします。 before_action :authenticate_user!でnew、edit、update、destroyを制限します。

(app/controllers/blogs_controller.rb)

before_action :authenticate_user!, only: [:new, :edit, :create, :update, :destroy]

viewでuser_signed_in?メソッドを使って非表示にします。

(app/views/blogs/index.html.erb)

<% if user_signed_in? %>
  <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
  <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
<%= link_to t('New Blog'), new_blog_path if user_signed_in? %>

(app/views/blogs/show.html.erb)

<% if user_signed_in? %>
  <%= link_to 'Edit', edit_blog_path(@blog) %> |
<% end %>

これでログインしていないユーザーの投稿や編集などを制限できます。

devise-i18nで日本語化

次に日本語化を設定します。config.i18n.default_locale = :jaを記載します。 config/initializers/locale.rbというファイルを作成して設定を記載します。

(config/initializers/locale.rb)

I18n.config.available_locales = [:en, :ja]
I18n.default_locale = :ja

辞書ファイルをプロジェクト内にコピーします。

$ rails g devise:i18n:locale ja

追加したnameカラムにはデフォルトでi18nの設定がないので、設定します。

(config/locals/devise.views.ja.yml)

ja:
  activerecord:
    attributes:
      user:
        name: ユーザー名
          (省略)

ヘッダーにログインメニューを書いていきます。

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

  <% if user_signed_in? %>
    ユーザー名:<%= link_to current_user.name, edit_user_registration_path %>
    <%= link_to "ブログ一覧", blogs_path %>
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
  <% else %>
    <%= link_to "新規登録", new_user_registration_path %>
    <%= link_to "ログイン", new_user_session_path %>
  <% end %>
  <%= link_to "ブログ一覧", blogs_path %>

以上です。