自己紹介
プログラミング初学者のtomaです。
学習の中で詰まったことを記事にして、同じ問題で困っている方の役に立てたらと思い投稿しました。
理解が浅い部分もあるかと思いますので、間違いがあればぜひご指摘いただけると嬉しいです。
この記事でわかること
- Devise 5系 + Turbo(Hotwire)でサインアップが動かない原因
- 解決策と設定方法
- サインアップ後のリダイレクト設定方法
環境
- Ruby 3.4.3
- Rails 7.2.3.1
- Devise 4.9.4
- Turbo(Hotwire)
- Docker
起きた問題
Deviseを導入してサインアップフォームから登録しようとしたところ、
以下の2つの問題が発生しました。
問題① サインアップフォームを送信しても何も起きない
エラーメッセージも表示されず、ページがそのまま残る状態でした。
Dockerのログを確認すると以下のようになっていました。
TRANSACTION (0.4ms) BEGIN
web-1 | 17:36:11 web.1 | ↳ app/controllers/users/registrations_controller.rb:5:in 'Users::RegistrationsController#create'
web-1 | 17:36:11 web.1 | User Exists? (3.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "[FILTERED]"], ["LIMIT", 1]]
web-1 | 17:36:11 web.1 | ↳ app/controllers/users/registrations_controller.rb:5:in 'Users::RegistrationsController#create'
web-1 | 17:36:11 web.1 | TRANSACTION (0.1ms) ROLLBACK
ROLLBACKとはDBへの変更をなかったことにする操作です。
つまりユーザーの保存が取り消されていました。
問題② サインアップ成功後にエラーが発生
undefined method 'user_url' for an instance of Devise::RegistrationsController
サインアップ後のリダイレクト先が見つからないエラーでした。
原因
問題①の原因
Gemfileでバージョン指定をしなかったため、Devise 5.0.4(最新版)がインストールされていました。
Devise 5系はTurbo(Hotwire)との互換性に問題があり、フォーム送信がROLLBACKしてしまいます。
gem "devise" # これだと最新版(5系)が入ってしまう
問題②の原因
サインアップ成功後のリダイレクト先が設定されていなかったため、
Deviseがデフォルトの user_url を探してしまっていました。
解決策
問題①の解決策|Deviseのバージョンを指定する
Gemfileを以下のように修正します。
修正前
gem "devise"
修正後
gem "devise", "~> 4.9"
bundle installを実行してDockerを再ビルドします。
docker compose exec web bundle install
docker compose down
docker compose build
docker compose up
また config/initializers/devise.rb を開くと以下がコメントアウトされているので
コメントアウトを外します。
TurboからのリクエストをDeviseが処理できるようになる
# config.navigational_formats = ['*/*', :html, :turbo_stream]
# ↓ コメントアウトを外す
config.navigational_formats = ['*/*', :html, :turbo_stream]
問題②の解決策|リダイレクト先を設定する
app/controllers/application_controller.rb に以下を追加します。
class ApplicationController < ActionController::Base
def after_sign_up_path_for(resource)
root_path
end
def after_sign_in_path_for(resource)
root_path
end
end
Devise導入の全手順
1. Gemfileに追加
gem "devise", "~> 4.9"
docker compose exec web bundle install
2. Deviseの初期設定
docker compose exec web bin/rails generate devise:install
3. フラッシュメッセージを追加
app/views/layouts/application.html.erb の bodyタグ内に追加
<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
4. Userモデル作成
docker compose exec web bin/rails generate devise User
5. マイグレーション実行
docker compose exec web bin/rails db:migrate
6. リダイレクト設定
app/controllers/application_controller.rb に追加
def after_sign_up_path_for(resource)
root_path
end
def after_sign_in_path_for(resource)
root_path
end
まとめ
| 問題 | 原因 | 解決策 |
|---|---|---|
| サインアップが動かない | Devise 5系とTurboの相性問題 | バージョンを4.9に指定 |
| user_urlエラー | リダイレクト先が未設定 | after_sign_up_path_forを追加 |
Gemfileにバージョンを指定しないと最新版がインストールされ、
互換性の問題が起きることがあると学びました。
特にTurboを使っているRails 7系のプロジェクトでは注意が必要です。
同じ問題で詰まっている方の参考になれば嬉しいです!
参考
- Devise公式GitHub: https://github.com/heartcombo/devise
- Devise CHANGELOG: https://github.com/heartcombo/devise/blob/main/CHANGELOG.md