はじめに
Rails 7.0が2021年の暮れにリリースされて以降、Deviseは長らくRails 7.0(というか、Hotwire/Turbo)に完全対応していない状態が続いていました。ですが、ようやく2023年2月17日にRails 7.0に対応したDevise 4.9.0がリリースされました🎉
rails-ujsではなく、Hotwire/Turboを使っているRails 7.0にDeviseを組み込んでいる(もしくはこれから組み込もうとしている)人は、以下の手順に従ってDevise 4.9.0を導入してください。
備考
もともとこの記事は「開発中のDeviseをインストールしてRails 7.0 (Hotwire/Turbo)のテストに協力する」というタイトルで公開していましたが、Devise 4.9.0が正式リリースされたことに伴い、タイトルと本文を修正しました。
前提条件
- Rails 7.0を使っている
- Hotwire/Turboが有効になっている(Rails 7.0で
rails new
した場合はデフォルトで有効になっているはず)
手順
新規にDeviseを導入する場合はGemfileに以下の情報を追加して、bundle install
を実行してください。
gem "devise"
すでにDeviseを利用している場合は bundle update devise responders
を実行して、最新版のDeviseとRespondersをインストールしてください。
インストールが終わったら、念のためDevise 4.9.0以上とResponders 3.1.0以上がインストールされていることを確認しましょう。
$ bundle info devise
* devise (4.9.0)
Summary: Flexible authentication solution for Rails with Warden
Homepage: https://github.com/heartcombo/devise
Documentation: https://rubydoc.info/github/heartcombo/devise
Source Code: https://github.com/heartcombo/devise
Wiki: https://github.com/heartcombo/devise/wiki
Changelog: https://github.com/heartcombo/devise/blob/main/CHANGELOG.md
Bug Tracker: https://github.com/heartcombo/devise/issues
Path: /Users/jnito/dev/sandbox/devise-rails-7-sandbox/vendor/bundle/ruby/3.2.0/gems/devise-4.9.0
$ bundle info responders
* responders (3.1.0)
Summary: A set of Rails responders to dry up your application
Homepage: https://github.com/heartcombo/responders
Source Code: https://github.com/heartcombo/responders
Changelog: https://github.com/heartcombo/responders/blob/master/CHANGELOG.md
Bug Tracker: https://github.com/heartcombo/responders/issues
Path: /Users/jnito/dev/sandbox/devise-rails-7-sandbox/vendor/bundle/ruby/3.2.0/gems/responders-3.1.0
Reverse Dependencies:
devise (4.9.0) depends on responders (>= 0)
アップグレードガイドに目を通す
bundle install
を実行すると、以下のように「Changelogやアップグレードガイドを読んでくれ」というメッセージが出力されます。
$ bundle install
(略)
Bundle updated!
Post-install message from devise:
[DEVISE] Please review the [changelog] and [upgrade guide] for more info on Hotwire / Turbo integration.
[changelog] https://github.com/heartcombo/devise/blob/main/CHANGELOG.md
[upgrade guide] https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-%5BHotwire-Turbo-integration%5D
Changelogやアップグレードガイド(wiki)にはHotwire/Turbo対応に必要な技術情報が載っています。
僕が翻訳したアップグレードガイドの日本語訳を以下に載せておいたので、この記事を読み進める前にこちらのガイドにも目を通しておくことをお勧めします(この記事を執筆している時点ではChangelogもアップグレードガイドも内容はほぼ同じです)。
【日本語訳】How To: Upgrade to Devise 4.9.0 [Hotwire Turbo integration]
ここから下の手順は状況によって作業が必要だったり、不要だったりします。
ご自身のアプリの状況に応じて、適切な手順を取捨選択していってください。
rails g devise:install
をまだ実行していない場合
rails g devise:install
を実行します。
新規にDeviseをインストールする場合は、基本的にこれだけで対応は終わりです。ただし、ログアウト用のリンクまたはボタンの作り方だけ、この下の説明を参考にしてください。
rails g devise:install
をすでに実行済みの場合
config/initializers/devise.rb
に以下の2行を追加します。
# ==> Hotwire/Turbo configuration
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
もしくは rails g devise:install --force
で config/initializers/devise.rb
を再作成してください。
ログアウトリンクを用意していた場合
link_to
をbutton_to
に変えるか、link_to
にdata: { turbo_method: :delete }
を追加します。
<%# rails-ujsでは動作するが、Hotwire/Turboでは動作しない %>
<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>
<%# rails-ujsとHotwire/Turboの両方で動作する %>
<%= link_to 'Sign out', destroy_user_session_path, method: :delete, data: { turbo_method: :delete } %>
<%= button_to 'Sign out', destroy_user_session_path, method: :delete %>
独自のviewでアカウント削除ボタンを用意していた場合
ボタンにdata: { turbo_confirm: "Are you sure?" }
を追加します。
-Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>
+Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
ボタンではなくリンクにしたい場合は以下のコードを利用します。
<%# rails-ujsとHotwire/Turboの両方で動作する %>
Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?", turbo_method: :delete }, method: :delete %>
独自のviewでOmniAuthを使ってログインリンクを用意していた場合
link_to
をbutton_to
に変え、Turboを無効化します。Turboを無効化するのはCORSエラーの発生を防止するためです。
-<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
+<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
devise-i18nを使っていた場合
devise-i18nはバージョン1.11.0でDevise 4.9.0に対応しています。
devise-i18nを使っている場合はbundle update devise-i18n
でバージョンを1.11.0以上に上げてください。
また、viewをカスタマイズしている場合は、上で説明した内容を手作業で反映するか、rails g devise:i18n:views
でviewを再生成してください。
すでにTurboを動かすためにあれこれ変更していた場合
Deviseで特に凝ったことをやる必要がなければ、上記の対応でDeviseがTurboに対応するはずです。
ただし、ネットの情報を参考にしてすでにDeviseのTurbo対応を進めていた場合は、その対応を元に戻す必要があります。
以下に僕が以前書いた記事を例に挙げて、元に戻す内容を記述します。
上記の記事を読んでTurbo対応していた場合は、修正点を元に戻すため、以下の対応を実施してください。
- Deviseのformに付けていた
data: { turbo: false }
を外す(Turboを有効化する) - RegistrationsControllerとSessionsControllerを削除する
-
config/routes.rb
のcontrollersオプションを無くす
-devise_for :users, controllers: { registrations: 'registrations', sessions: 'sessions' }
+devise_for :users
上記の記事を読んでTurbo対応していた場合は、修正点を元に戻すため、以下の対応を実施してください。
- TurboDeviseControllerを削除する
-
config/initializers/devise.rb
内のTurboFailureAppを削除する -
config/initializers/devise.rb
内のparent_controller
、navigational_formats
、warden
の設定をそれぞれコメントアウトする
まとめ
手順は以上です。これで心置きなくRails 7.0に移行できますね!!🎉