I'm using simple_nested_form_for
to build a form with nested fields. Fields are added dynamically
When rendering the form with errors (via create
) the nested fields go wrong.
The same nested fields are shown multiple times and with the wrong index values in the name
elements.
For example the FormBuilder
index
in the nested field is initially a random number such as 1454793731550
. After re-rendering they simply become normal increments 0-n
.
Why is the FormBuilder
index
initially a random number?
Any suggestion what could be going on here?
def new
@transaction = current_company.transactions.build
@transaction.subtransactions.build
end
def create
@transaction = current_company.transactions.new(transaction_params)
if @transaction.save
redirect_to dashboard_url
else
@transaction.subtransactions.build
render :action => 'new'
end
The index
is the child_index
of the nested fields. This is simply a way for Rails to individually identify the various field names of the HTML form elements:
<%= f.fields_for :association do |a| %>
<%= a.text_field :x %> #-> "child_index" id will either be sequential (0,1,2)
<% end %>
The child_index
doesn't matter. As long as it's unique, it should be passed to the controller as follows:
params: {
association_attributes: {
0: { x: "y", z: "0" },
1: { ... }
}
}
A trick often used is to set the child_index
to Time.now.to_i
, which allows you to add new fields out of scope:
<%= f.fields_for :association, child_index: Time.now.to_i do |a| %>
In regards your new
action with the likely issue is that your subtransactions
object is being built each time (irrespective of whether the instance is populated with previous data).
We've had this issue before, and I believe that we solved it with a conditional:
def new
@transaction = current_company.transactions.build
@transaction.subtransactions.build unless @transaction.errors.any?
This should maintain the object's integrity through the submission process. IE if an error occurs, I believe Rails stores the associated object in memory (like it does with the parent).