Devise登出路径跳转至Users#show问题求助
嘿,我来帮你排查这个登出异常的问题!结合你给出的代码和路由配置,大概率是以下几个原因导致的,咱们一步步来解决:
1. 无效的登出链接导致请求方式错误
你代码里有两个登出链接,第一个<%= link_to "delete", :controller => "devise/sessions", :action => "destroy" %>没有指定method: :delete,默认会发送GET请求。而Devise的登出接口(destroy_user_session_path)只接受DELETE请求,这个GET请求会被Rails路由错误匹配——如果你的路由里有resources :users,它会把sign_out当成用户ID,直接跳转到Users#show页面。
解决方案:
- 删除第一个无效的登出链接,只保留正确的那个:
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
2. 路由顺序导致匹配优先级错误
如果你的路由文件里,resources :users写在了devise_for :users的前面,Rails会优先匹配resources :users的路由规则。这时候哪怕你用了正确的链接,一旦请求方式不对(比如UJS失效导致GET请求),就会被解析成user_path(id: 'sign_out'),跳转到Users#show。
解决方案:
- 调整路由顺序,把
devise_for :users放在resources :users之前,确保Devise的登出路由先被匹配:devise_for :users, controllers: { registrations: 'users/registrations', omniauth_callbacks: "users/omniauth_callbacks" } resources :users # 放在devise_for之后
3. Rails UJS未加载,导致method: :delete失效
link_to的method: :delete依赖Rails UJS来把GET请求转换成DELETE请求,如果UJS没加载,浏览器还是会发送GET请求,进而触发路由匹配错误。
解决方案:
- 检查你的
application.js(Rails 5及之前)是否包含://= require rails-ujs - Rails 6+则要确保在
application.js里导入:import Rails from "@rails/ujs" Rails.start() - 同时确认
application.html.erb里有CSRF meta标签:<%= csrf_meta_tags %>
替代方案:用button_to规避UJS依赖
如果不想依赖UJS,可以直接用button_to生成登出按钮,它默认会生成表单发送POST请求,配合method: :delete更可靠:
<%= button_to "Logout", destroy_user_session_path, method: :delete %>
你可以按这个顺序排查,应该能解决登出跳转的问题~
内容的提问来源于stack exchange,提问作者john seymour

