stimulus-rails-nested-form
stimulus-rails-nested-form copied to clipboard
Unique Identifiers for Nested Form Fields to Prevent Data Overwrite
When using the stimulus-rails-nested-form library to dynamically add nested form fields, it has been observed that if the "add" action is triggered multiple times, the newly added input fields end up having the same name attribute value. This behavior results in only the last input's data being submitted, as the preceding input values are overwritten due to the shared name attribute among them. This issue fundamentally affects the form's ability to correctly handle multiple nested records, leading to data loss and inconsistent submissions.
I propose modifying the nested form field addition process to include a unique identifier within each name attribute of newly added input fields. This can be achieved by appending a timestamp or a sequentially incremented value to the name attribute, ensuring its uniqueness across the form. I have prepared a pull request that implements this solution by extending the current functionality of the stimulus-rails-nested-form library's controller to include this adjustment.
I''ll send a PR
Is it possible you're using this component to render multiple nested fields on a single model? This component is designed to be used across an association boundary with fields_for/accepts_nested_attributes, such that (for each associated model) the attribute names don't change (and Rails generates unique name="blah_attributes[1]name" sort of attributes for each that are unique to the name and index of the associated model)
Just to clarify, would this scenario be supported by your tool? whereby the has many points to the same model? or are you saying this is not supported?
class WritingTask < ApplicationRecord
has_many :sections, dependent: :destroy
accepts_nested_attributes_for :sections, allow_destroy: true
end
class Section < ApplicationRecord
belongs_to :parent, class_name: 'Section'
has_many :children, class_name: 'Section', foreign_key: 'section_id', dependent: :destroy
accepts_nested_attributes_for :children, allow_destroy: true
end
then in the views
= simple_nested_form_for [:admin, writing_task], data: { controller: 'nested-form', nested_form_wrapper_selector_value: '.nested-form-wrapper' } do |f|
template data-nested-form-target="template" class="section"
= f.fields_for :sections, Section.new, child_index: 'NEW_RECORD' do |section|
= render 'section_fields', f: section
= f.fields_for :sections do |section|
= render 'section_fields', f: section
div data-nested-form-target="target"
button type="button" data-action="nested-form#add" Add Section
then in the section_fields
div class="nested-form-wrapper" data-new-record="#{f.object.new_record?}"
.nested-fields.subsection_place
= render 'shared_section_fields', f: f
button type="button" data-action="nested-form#remove" Remove section
= f.hidden_field :_destroy
template data-nested-form-target="template" class="children"
= f.fields_for :children, Section.new, child_index: 'NEW_RECORD' do |child|
= render 'child_fields', f: child
= f.fields_for :children do |child|
= render 'child_fields', f: child
div data-nested-form-target="target"
button type="button" data-action="nested-form#add" Add
my assumption is no because it's not working 😆 but i figured I'd check here!