You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7中link_to指定POST/DELETE方法仍默认发起GET请求的问题

问题核心原因

Rails 7 对前端默认依赖做了重大调整:旧版本负责处理link_to非GET请求的rails-ujs不再默认加载,框架原生改用Turbo作为交互驱动。
浏览器原生的<a>标签本身仅支持GET请求,link_to生成的非GET链接必须依赖前端JS拦截点击事件、构造带_method参数的表单提交才能实现POST/DELETE/PATCH等请求。如果对应JS逻辑未加载或未生效,点击链接就会直接 fallback 为原生GET请求。
button_to不受这个逻辑影响:它是服务端直接渲染一个完整的form表单,内置隐藏的_method参数提交,完全不需要前端JS做额外拦截,所以不管前端配置如何,指定的请求方法都能正常生效。

常见触发场景
  • 自定义布局文件遗漏了JS入口标签引入:使用Importmap管理JS的项目漏加<%= javascript_importmap_tags %>,使用jsbundling(esbuild/webpack等)的项目漏加对应javascript_include_tag,导致处理链接请求方法的JS根本没有在页面加载
  • 给链接手动加了data-turbo="false"属性禁用了Turbo处理,同时项目又没有加载rails-ujs
  • 链接指向跨域地址,Turbo默认不会对跨域链接应用data-turbo-method拦截逻辑
可落地方案

根据你的技术选型二选一即可:

方案1:适配Rails 7默认Turbo约定(官方推荐)

  1. 首先确认布局文件正确引入了JS入口,确保Turbo能正常加载运行
  2. 正常使用link_to ... method: :delete写法即可,Rails的视图助手会自动给生成的a标签加上data-turbo-method="delete"属性,Turbo会自动拦截点击事件完成对应方法的请求
  3. 如果仍然不生效,执行bin/importmap pin @hotwired/turbo-rails(Importmap场景)或对应包管理更新命令,升级Turbo到最新稳定版即可

注意:跨域场景下不要用link_to发非GET请求,这是Turbo的安全限制,这类场景直接用button_to即可。

方案2:回退使用旧版rails-ujs逻辑

如果不想适配Turbo的规则,可以重新引入rails-ujs接管链接处理:

  1. 安装依赖:Importmap项目执行bin/importmap pin @rails/ujs,npm/yarn管理的项目执行yarn add @rails/ujs
  2. 在JS入口文件(默认路径app/javascript/application.js)添加初始化代码:
import Rails from "@rails/ujs"
Rails.start()
  1. 如果需要完全禁用Turbo避免冲突,在config/application.rb中添加配置:
config.turbo.enabled = false
样式统一技巧

不需要为了视觉统一强行用link_to实现非GET请求,给button_to加几行CSS重置就能和普通链接视觉完全一致:

.btn-link {
  display: inline;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: var(--link-color, #06c);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

给button_to加上class: "btn-link"即可,渲染出来的按钮和普通a标签链接没有视觉差别,还不需要依赖JS处理,兼容性更好。

内容的提问来源于stack exchange,提问作者H Zaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:18:20