stimulus-rails-nested-form icon indicating copy to clipboard operation
stimulus-rails-nested-form copied to clipboard

Unique Identifiers for Nested Form Fields to Prevent Data Overwrite

Open Arzamendiaariel opened this issue 1 year ago • 2 comments

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

Arzamendiaariel avatar Mar 20 '24 19:03 Arzamendiaariel

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)

searls avatar Apr 07 '24 11:04 searls

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!

agirlnamedsophia avatar Sep 13 '24 00:09 agirlnamedsophia