Rails 7 でのログアウト処理問題とその解決策
Railsアプリケーションで以下のようにログアウトリンクを設定している場合、
<%= link_to 'ログアウト', destroy_user_session_path, data: { turbo_method: :delete } %>
次のエラーに直面することがあります。
ActiveRecord::RecordNotFound at /users/sign_out Couldn't find User with 'id'=sign_out
Rails 6 では以下の方法でログアウトリンクを記述していましたが、
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
Rails 7 からは data: { turbo_method: :delete }
を使用する必要があります
※そうしないとGETメソッドで予期しないリンク先に遷移しようとします。
しかし、この方法でもエラーが発生することがあります。この記事では、その原因解明と解決策を探求します。
[補足]簡易な応急策としては以下のものがある
<%= button_to 'ログアウト', destroy_user_session_path, method: :delete %>
※HTTPメソッドの送信方法の不具合や予期しない挙動が解消したわけではないことに注意してください。
根本的な問題
プロジェクトの現状は以下の通りです。
pin "application", preload: true
pin "@hotwired/turbo-rails", to:"turbo.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers", preload: true
import "@hotwired/turbo-rails"
import "controllers/application"
<!DOCTYPE html>
<html>
<head>
...
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= vite_client_tag %>
<%= vite_javascript_tag "entrypoints/application" %>
<%= javascript_importmap_tags %>
</head>
...
</html>
console.log('Vite ⚡️ Rails')
console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify.app/guide/rails')
import 'vue2-animate/dist/vue2-animate.min.css';
import { createApp } from 'vue';
import ExampleComponent from '../components/ExampleComponent.vue';
const app = createApp(ExampleComponent);
app.mount('#app');
この構成において、<%= vite_javascript_tag "entrypoints/application" %>
をコメントアウトすることで、importmap
とvite
の競合が解消され、ログアウトが可能になりましたが、Vue.js
をVite
で管理しているため、このアプローチは適切ではありません。
なお、importmap
とvite
の競合でimportmap
の設定が有効にならないのはおそらくimportmap
の後でvite
(app/javascript/entrypoints/application.js
)でVue
アプリケーションを初期化されているからと思われます(詳細未調査)。
解決策
解決策として、config/importmap.rb
とapp/javascript/application.js
を削除し、Viteのみを使用する構成に変更します。
-
application.html.erb の更新
application.html.erb<!DOCTYPE html> <html> <head> ... <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= vite_client_tag %> <%= vite_javascript_tag "entrypoints/application" %> </head> ... </html>
-
entrypoints/application.js の更新
entrypoints/application.jsconsole.log('Vite ⚡️ Rails') console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify.app/guide/rails') import "@hotwired/turbo-rails" import "@hotwired/stimulus" import "@hotwired/stimulus-loading" import "../controllers/application" import 'vue2-animate/dist/vue2-animate.min.css'; import { createApp } from 'vue'; import ExampleComponent from '../components/ExampleComponent.vue'; const app = createApp(ExampleComponent); app.mount('#app');
これにより、Viteを使用しつつ、@hotwired/turbo-rails
と Stimulus を適切にインポートし、Rails 7のアプリケーションで問題なく動作するようになります。