Rails7单页多表单按钮始终传递首个ID问题求助
问题原因分析
你遇到的核心问题是Stimulus Target重复绑定:循环渲染的每个表单都设置了data-manage-cart-target="form",Stimulus会将所有同名target收集到formTargets数组中,若控制器使用单数formTarget(如this.formTarget),只会返回第一个匹配的表单元素,导致无论点击哪个按钮,都提交第一个表单的数据,最终控制器始终收到tool_id=1。
另外remote: true会触发Rails UJS的AJAX处理,可能和自定义Stimulus逻辑冲突,需要同步调整。
解决方案
1. 调整Stimulus控制器,通过事件获取当前表单
修改manage_cart_controller.js,移除对target的依赖,直接从submit事件中取触发提交的表单:
import { Controller } from "@hotwired/stimulus" export default class extends Controller { manage(event) { // 阻止默认表单提交行为 event.preventDefault(); // 获取当前提交的表单元素 const form = event.currentTarget; // 手动发送AJAX请求 fetch(form.action, { method: form.method, headers: { "Accept": "application/json", "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content }, body: new FormData(form) }) .then(response => response.json()) .then(data => { // 可添加成功后逻辑,比如更新购物车UI console.log(data); }) .catch(error => { console.error('请求失败:', error); }); } }
2. 修改ERB表单代码,移除重复Target并关闭Rails UJS
去掉data-manage-cart-target="form"和remote: true(已用Stimulus手动处理AJAX):
<%= form_with(url: devis_path, method: :post, data: { action: "submit->manage-cart#manage" }) do |f| %> <%= f.hidden_field :tool_id, value: tool.id %> <%= tool.id %> <!-- 确认显示正确的ID --> <%= f.submit "Ajouter à mon devis", class: "mt-4 text-xl w-full text-white py-2 rounded-xl shadow-lg cursor-pointer hover:bg-indigo-400", style: "background-color: #3949ab" %> <% end %>
3. 可选:用hidden_field_tag替代表单助手(更直观)
因为未关联ActiveRecord模型到表单,直接用hidden_field_tag可避免表单助手自动生成的额外参数:
<%= form_with(url: devis_path, method: :post, data: { action: "submit->manage-cart#manage" }) do %> <%= hidden_field_tag :tool_id, tool.id %> <%= tool.id %> <%= submit_tag "Ajouter à mon devis", class: "mt-4 text-xl w-full text-white py-2 rounded-xl shadow-lg cursor-pointer hover:bg-indigo-400", style: "background-color: #3949ab" %> <% end %>
验证要点
- 点击不同卡片的提交按钮,查看浏览器控制台请求数据,确认
tool_id为当前卡片对应值 - 检查Rails服务器日志,确认
params[:tool_id]收到正确ID值
内容的提问来源于stack exchange,提问作者Julien KARMANN
相关产品推荐
相关产品推荐

