Rails 5 Ajax创建关联Comment模型报错:参数数量不符
ArgumentError问题 错误根源分析
你遇到的ArgumentError (wrong number of arguments (given 1, expected 0))是因为Rails 5的form_with语法要求使用关键字参数,而你直接把关联对象数组作为位置参数传递了。另外你的表单还有嵌套<form>标签的问题,这也是需要修复的。
具体修复步骤
修正
form_with的调用方式
在Rails 5中,form_with不支持直接将对象/数组作为第一个位置参数,必须通过model:关键字指定关联对象。同时,你已经在Posts#show中初始化了@comment = @post.comments.build,所以不需要在表单里再次调用build,直接复用这个实例变量即可。移除多余的外层
<form>标签form_with会自动生成完整的<form>标签,手动添加的外层<form>会导致嵌套表单,这是无效的HTML,还可能引发其他行为异常。确保Ajax请求正确触发
Rails 5中form_with默认是通过Ajax提交的(local: false是默认值),所以不需要额外配置,但要确保你的create.js.erb能正确找到目标元素(比如页面上要有id="comments"的容器来渲染新评论)。
修正后的代码
comments/_form.html.erb
<%= form_with model: [@post, @comment], id: :new_comment do |form| %> <div class="form-group"> <%= form.label :description %> <%= form.text_field :description, id: :comment_description, class: "form-control" %> </div> <div class="form-group"> <%= form.submit "Comment it", class: "btn btn-default", data: { "disable-with": "Comment is saving..." } %> </div> <% end %>
额外必要检查
- 确保你的
posts/show.html.erb中有一个id="comments"的容器,用来渲染评论列表,比如:<div id="comments"> <%= render @comments %> </div> - 确认
comments/create.js.erb中的选择器正确,因为你用了prepend,新评论会被添加到列表顶部。
错误原因详解
在Rails 5中,form_with的方法签名是form_with(options = {}, &block),所有配置都要通过选项哈希传递。你直接传递[@post, @post.comments.build]作为第一个位置参数,Ruby会把这个数组当作options哈希处理,而form_with内部逻辑期望的是键值对形式的哈希,从而触发了参数数量不匹配的错误。Rails 6及以后版本才支持直接将对象/数组作为第一个参数的简化写法。
内容的提问来源于stack exchange,提问作者anndrew78

