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?
Yes, ordering is retained as-is, as @k-everest self-answered as a comment to original question.
Those asking for HTML, see the guide on how the attribute's name
is parsed.
Example of typically bad ordering:
cart[items][][id]=5
cart[items][][id]=6
cart[items][][name]=i1
cart[items][][name]=i2
And that gets parsed by Rails into this:
{ "cart"=> {"items"=> [
{"id"=>"5"},
{"id"=>"6", "name"=>"i1"},
{"name"=>"i2"}
]}}
Example source: https://spin.atomicobject.com/2012/07/11/get-and-post-parameter-parsing-in-rails-2/
The feature was added in Rails' initial commit, with method name build_deep_hash
. For more history, skip the flaming/semantics war and go for the last post from the end here: https://www.ruby-forum.com/topic/215584
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With