【Rails7】ついにDeviseがTurboに対応しました(最新版のリリース)

Railsのメジャーなユーザー認証用gemである「Devise」が、1年以上の時を経てついにアップデートされました。

Rails7ではTurbo Streamが標準で有効化されているため、Deviseを導入する際にTurboが悪さをして不具合を引き起こしていました。

そのTurboの不具合対処のため、カスタムコントローラーを作成したりして色々と対処する必要があり、、正直かなり面倒でした。

あわせて読みたい
【Rails7】Deviseを導入する方法(Turbo対応済み, メールサーバー設定込み) 【重要】Rails7でDeviseを導入される方へ2023年2月17日に最新版Devise(v4.9.0)がリリースされ、Rails7のTurboに対応するようになりました。それに伴い、当記事で紹介...

ですが、今回のDeviseのアップデートにより、Rails7のTurboに標準で対応するようになりました。

これは嬉しい。

早速、最新版のDeviseをRails7に導入してみたので、忘備録として残しておこうと思います。

(Devise導入後のソースコードをこちらに載せておきます↓)

GitHub
GitHub - hirokirokki0820/devise-7.0.4-tailwind Contribute to hirokirokki0820/devise-7.0.4-tailwind development by creating an account on GitHub.
目次

開発環境

  • Ruby 3.1.2
  • Ruby on Rails 7.0.4
  • Devise 4.9.2
  • tailwindcss 3.1.8
  • M1 Macbook Air 2020
  • mac OS Monterey (ver. 12.4)
  • ターミナル bash (Rosetta 2 使用

最新版 Devise を Rails7 に導入する流れ

最新版 Devise の導入方法は以下の公式githubの手順を参考にしています。

GitHub
GitHub - heartcombo/devise: Flexible authentication solution for Rails with Warden. Flexible authentication solution for Rails with Warden. - heartcombo/devise

今回、改めてDeviseの導入手順についてまとめておきます。

Devise のインストール

まずはGemfileに下記のように記述します。

gem 'devise'

以下のコマンドでgemをインストールします。

$ bundle install

続いて、以下のコマンドでDevise本体をインストールします。

$ rails g devise:install

Deviseのインストールが完了すると、ターミナルに以下のような表示が出ます。

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

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 *

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

Userモデルの作成

以下のコマンドでUserモデルを作成します。

$ rails g devise user

Userモデルを作成すると、db/migrate以下にマイグレーションファイルが生成されます。

デフォルトではユーザー名カラムが作成されないため、必要であればマイグレーションファイルに追記します。

また、メール認証機能を有効化したい場合はConfirmableの箇所をコメントアウトしておきます(以下を参照)。

# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :name  #←ユーザー名カラムを追加する場合は追記
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, 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 ↓メール認証を利用する場合は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

編集が完了したら、以下のコマンドでマイグレーションを実行します。

$ rails db:migrate

メール認証機能を有効化する(マイグレーションファイルのConfirmableをコメントアウトする)場合は、app/models/user.rb:confirmableを追記します。

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable #←追記する
end

User、Adminなど複数モデルを作成したい場合は以下の記事を参考に進めてください。

あわせて読みたい
【Rails7】Deviseでユーザー(user)と管理者(admin)を分けてログインできるようにする Webサービスを運営するのであれば、少なくともユーザーアカウントと管理者アカウントの最低2つは要する必要があるかと思います。 そこで、今回はDeviseを使ってユーザ...

Viewの追加

以下のコマンドを実行し、Devise用の各種フォームのViewファイルを作成します。

$ rails g devise:views

ただし、この場合app/views/deviseディレクトリ以下にViewファイルが作成されることになるので、もしapp/views以下のディレクトリをモデル名(User)と同じ名称にしたい場合は、以下のコマンドを実行します。

$ rails g devise:views users

こうすることでapp/views/usersディレクトリ以下に各種Viewファイルが作成されます。

各種フォーム(新規登録、ログイン、パスワード再設定など)のカスタマイズをする場合はこれらのファイルを編集します。

「sign_up」「sign_in」へのリンクを貼る

適当なページに新規登録、ログイン、およびログアウト用のリンクを貼ります。

今回はトップページに貼ることにしましょう。

(ホームコントローラーを作成後、top.html.erbを追加しルートパスをhome#topとしておきます)

<h1>トップページ</h1>

<% if user_signed_in? %>
  <div class="my-5">
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete, data: { turbo_method: :delete, turbo_confirm: "本当にログアウトしますか?" }, class: "font-semibold py-2 px-4 rounded text-white bg-sky-600 hover:bg-sky-800 cursor-pointer" %>
  </div>
<% else %>
  <div class="my-5">
    <%= link_to "新規登録", new_user_registration_path, class: "font-semibold py-2 px-4 rounded text-white bg-sky-600 hover:bg-sky-800 cursor-pointer" %>
    <%= link_to "ログイン", new_user_session_path, class: "font-semibold py-2 px-4 rounded border-2 hover:bg-gray-100 px-3" %>
  </div>
<% end %>

リンクを貼ったら、実際に新規登録、ログイン、ログアウトができるかどうか試してみましょう。

メール認証を有効化する場合のメールサーバー設定

メール認証を有効化する場合(confirmableを設定した場合)は、使用するメーラーのアカウント登録、およびメールサーバー設定が必要になります。

ここではSendGridというメーラーを使う前提で話を進めて行きますが、SendGridは事前のアカウント登録とAPIキーの取得が必要です。登録における注意点もあるのでこちらで確認しておいてください。

(Gmailで設定したい場合は、アプリパスワード取得方法、およびメールサーバー設定でそれぞれ確認してください)

ちなみに、SendGridのアカウント登録については以下の記事が参考になります。

dotenv-railsの導入

メールサーバーの設定では、SendGridで取得したAPIキーを設定しますが、APIキーをそのまま設定ファイルに入力するのはセキュリティ上好ましくありません。

(SendGrid側も、生のパスワード使用を禁止しているみたいです)

アプリ内でAPIキーを使用する場合は、取得したAPIキーを環境変数として設定する必要があります。

以下、追加するGemはそのために必要なライブラリです。

gem 'dotenv-rails'

Gemを追記したら下記コマンドでインストールします。

$ bundle install

APIkey, Passwordなどを環境変数として設定(開発環境用)

アプリケーションフォルダ直下に.envという名前のファイルを新規作成し、SendGridで取得したAPIキーを以下のように追加します。

# SendGridのAPIキー
SENDGRID_API_KEY = "SendGridのAPIキー"

また、APIキーをgithub上にアップしてしまわないように、.gitignoreに以下の1行を追記します。

/public/assets

# Ignore master key for decrypting credentials and more.
/config/master.key

# ↓最下部に追記
/.env

環境設定にメールサーバーの情報を記述

開発環境の場合、config/environments/development.rbに以下のように記述します。

 # SendGrid用のメールサーバー設定(開発環境)
  config.action_mailer.perform_caching = false
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :domain => 'localhost',
    :user_name => 'apikey',
    :password => ENV['SENDGRID_API_KEY'],
    :authentication => :plain,
    :enable_starttls_auto => true
  }

:password欄には環境変数として設定したAPIキーENV['SENDGRID_API_KEY']を挿入します。

本番環境(Heroku)の場合はconfig/environments/production.rbに以下のように記述します。

 # SendGrid用のメールサーバー設定(本番環境→Heroku)
  config.action_mailer.default_url_options = { host: 'https://Herokuのアプリ名.herokuapp.com' }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_deliveries = true
  config.action_mailer.default :charset => "utf-8"
  config.action_mailer.smtp_settings = {
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :domain => 'heroku.com',
    :user_name => 'apikey',
    :password => ENV['SENDGRID_API_KEY'],
    :authentication => :plain,
    :enable_starttls_auto => true
  }

また、本番環境(Heroku)でも環境変数を利用できるようにするため、Heroku側で環境変数の設定を行います。

Herokuの対処アプリのSettingタブ > Config Varsへ進み、以下のように環境変数のキーと値を入力します。

これでメールサーバーの設定は完了です。

ただし、SendGridの場合はアプリ側で「メールの差出人情報(送信元メールアドレス)」の設定もする必要があります。

(SendGridのアカウント作成後、送信元メールアドレスの登録&認証を済ませておく必要があります。送信元メールアドレスの登録&認証方法はこちらの②をご確認ください)

メールの差出人(送信元)情報の設定

送信元メールアドレスも環境変数として設定しておきたいので、

.envファイルを開き、SendGridで事前に認証済みの送信元メールアドレスを追記します。

# SendGridのAPIキー
SENDGRID_API_KEY = "SendGridのAPIキー"

# 送信元のメールアドレス(↓追記)
SENDER_ADDRESS = "送信元のメールアドレス"

次に、app/mailers/application_mailer.rbdefault from:欄に先ほど環境変数として設定した送信元メールアドレスENV['SENDER_ADDRESS']を追記します。

class ApplicationMailer < ActionMailer::Base
  default from: ENV['SENDER_ADDRESS']
  layout "mailer"
end

また、config/initializers/devise.rbconfig.mailer_senderの箇所をコメントアウトし、以下のように編集します。

Devise.setup do |config|
  ・・・
  # config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
  # ↓以下のように変更
  config.mailer_sender = ENV['SENDER_ADDRESS']
 ・・・
end

これで、アプリケーション側からメールが送信できるようになるはずです。

新規登録(sign_up)時に、登録したメールアドレス宛に以下のようなアカウント有効化リンクを含むメールが届いたら成功です。

アカウント有効化リンクをクリックすると、アプリ内にログインできるようになるはずです。

その他の設定

エラーメッセージ表示用のタグをapplication.html.erbに埋め込む

application.html.erbの任意の場所に以下のタグを挿入します。

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

これで、タグを挿入した箇所にDeviseの確認メッセージ、およびエラーメッセージが表示されるようになります。

Deviseの各種メッセージを日本語化する

Deviseの確認メッセージおよびエラーメッセージはデフォルトで英語なので、これらを日本語化します。

まず、config/application.rbに下記のコードを記述。

config.i18n.default_locale = :ja
config.time_zone = "Tokyo"

次にconfig/locales内にdevise.ja.ymlおよびja.ymlファイルを作成します。

作成したファイルに翻訳データをコピーします。

devise.ja.ymlの翻訳ファイルはこちらから、ja.ymlの翻訳ファイルはこちらからそれぞれコピペします。

以上でDeviseの導入は完了です。

参考資料

Qiita
Devise 4.9をインストールしてRails 7.0 (Hotwire/Turbo)に対応する - Qiita はじめにRails 7.0が2021年の暮れにリリースされて以降、Deviseは長らくRails 7.0(というか、Hotwire/Turbo)に完全対応していない状態が続いていました。ですが、よ…
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

愛知の34歳。無職で暇になり始めたプログラミング(Ruby on Rails)の忘備録をまとめたブログです。最近は別にやりたいことができたのでプログラミングほぼやっていません。気が向いたらまた再開するかも。僕の日常はメインブログの方で更新しています。

コメント

コメントする

目次