6

According to the Rails Guides and this Railscasts episode, when there's a one-to-many association between two objects (e.g. Project and Task), we can submit multiple instances of Task together with the Project during form submission similar to this:

<% form_for :project, :url => projects_path do |f| %>
  <p>
    Name: <%= f.text_field :name %>
  </p>
  <% for task in @project.tasks %>
    <% fields_for "project[task_attributes][]", task do |task_form| %>
      <p>
        Task Name: <%= task_form.text_field :name %>
    Task Duration: <%= task_form.text_field :duration %>
      </p>
    <% end %>
  <% end %>
  <p><%= submit_tag "Create Project" %></p>
<% end %>

This will result multiple copies of an HTML block like this in the form, one for each task:

<p>
    Task Name: <input name="project[task_attributes][name]">
    Task Duration: <input name="project[task_attributes][duration]">
</p>

My question is, how does Rails understand which

    (project[task_attributes][name], project[task_attributes][duration])

belong together, and packing them into a hash element of the resulting array in params? Is it guaranteed that the browsers must send the form parameters in the same order in which they appear in the source?

4

2 回答 2

4

是的,订单按原样保留,因为@k-everest 自我回答作为对原始问题的评论。

那些要求 HTML 的人,请参阅有关如何解析属性的指南。name

典型的错误排序示例:

cart[items][][id]=5
cart[items][][id]=6
cart[items][][name]=i1
cart[items][][name]=i2

Rails 将其解析为:

{ "cart"=> {"items"=> [
                        {"id"=>"5"},
                        {"id"=>"6", "name"=>"i1"},
                        {"name"=>"i2"}
                       ]}}

示例来源:https ://spin.atomicobject.com/2012/07/11/get-and-post-parameter-parsing-in-rails-2/

该功能是在 Rails 的初始提交中添加的,方法名称为build_deep_hash。要了解更多历史,请跳过火焰/语义大战,然后从最后开始阅读最后一篇文章:https ://www.ruby-forum.com/topic/215584

于 2016-03-31T12:52:55.133 回答
2

如果您正在处理直接数据并希望在不使用任何这些@objects 的情况下发回数组

<%= form_for :team do |t| %>
  <%= t.fields_for 'people[]', [] do |p| %>
    First Name: <%= p.text_field :first_name %>
    Last Name: <%= p.text_field :last_name %>
  <% end %>
<% end %>

你的参数数据应该像这样返回

"team" => {
  "people" => [
    {"first_name" => "Michael", "last_name" => "Jordan"},
    {"first_name" => "Steve", "last_name" => "Jobs"},
    {"first_name" => "Barack", "last_name" => "Obama"}
  ]
}
于 2015-02-19T00:36:36.377 回答