Rails中No route matches [GET] "/accounts/sign_out"问题求助
问题分析与解决方案
核心问题定位
你的Devise登出按钮指定了method: "delete"但功能失效,排除路由缺失、JS文件缺失后,问题出在菜单的事件冒泡阻止逻辑干扰了Rails UJS的正常工作。
你的菜单代码中:
- 父元素
<ul id="menu-content">绑定了onclick="event.stopPropagation();" - 菜单切换函数
toggleMenu也调用了e.stopPropagation();
而Rails UJS(处理data-method="delete"的核心机制)是通过给链接绑定全局点击事件来实现请求方法转换的,事件冒泡被阻止后,UJS无法捕获到登出按钮的点击事件,自然无法生成预期的DELETE请求。
具体解决方案
方案1:移除不必要的事件冒泡阻止
如果菜单的点击阻止冒泡不是必须的,直接删除<ul>上的阻止逻辑:
<ul id="menu-content" class="shadowed-menu"> <!-- 其余菜单内容保持不变 --> </ul>
方案2:保留菜单逻辑,给登出按钮单独放行
若必须保留菜单的阻止冒泡,修改登出按钮的点击事件,让UJS能正常捕获请求:
<li> <%= link_to 'Se déconnecter', destroy_account_session_path, method: "delete", class: "button button-primary", onclick: "event.stopPropagation = function(){};" %> </li>
或者手动用JS处理登出请求(绕过UJS的事件依赖):
// 在现有JS代码后添加 document.getElementById('logout-btn').addEventListener('click', function(e) { e.preventDefault(); fetch(this.href, { method: 'DELETE', headers: { 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content } }).then(() => { window.location.href = '/' // 替换为登出后要跳转的页面路径 }); });
对应的ERB给按钮添加ID:
<li> <%= link_to 'Se déconnecter', destroy_account_session_path, id: "logout-btn", class: "button button-primary" %> </li>
方案3:确认UJS/Turbo加载状态
检查布局文件中是否正确引入了Rails UJS(若使用Turbo需兼容处理):
<%= javascript_include_tag 'application', 'data-turbo': false %>
如果启用了Turbo,也可以给登出链接添加data-turbo-method="delete"属性替代原有的method: "delete"。
验证方法
- 打开浏览器开发者工具的Network标签
- 点击登出按钮,查看请求方法是否为DELETE
- 若仍为GET,回到上述方案逐一排查
内容的提问来源于stack exchange,提问作者Philippe Dubé-Tremblay
相关产品推荐
相关产品推荐

