nathanvda / cocoon

Dynamic nested forms using jQuery made easy; works with formtastic, simple_form or default forms
http://github.com/nathanvda/cocoon
MIT License
3.08k stars 383 forks source link

Problem when editing - duplicates child items #596

Closed gabydi106 closed 3 years ago

gabydi106 commented 3 years ago

The nested form works great when creating new records. However when I edit the record, it creates duplicate child items even if I do not mean to add new items.

How do I prevent it from creating new child items when updating the Sales Order?

class SalesOrderItem < ApplicationRecord
  belongs_to :item
  belongs_to :sales_order

class SalesOrder < ApplicationRecord
  has_many :sales_order_items, dependent: :destroy, inverse_of: :sales_order
  accepts_nested_attributes_for :sales_order_items

Sales Order Controller (parent)

  def new
    @sales_order = SalesOrder.new
    @items = Item.all
    @customers = Customer.all
    @sales_order.sales_order_items.build
  end

  def edit
  end

  def update
    respond_to do |format|
      if @sales_order.update(sales_order_params)
        format.html { redirect_to @sales_order, notice: 'Sales order was successfully updated.' }
        format.json { render :show, status: :ok, location: @sales_order }
      else
        format.html { render :edit }
        format.json { render json: @sales_order.errors, status: :unprocessable_entity }
      end
    end
  end

-----------------------------------------------
def sales_order_params
      params.require(:sales_order).permit(:customer_id,
                                          :date,
                                          :user_id,
                                          :remarks,
                                          :vat_ex,
                                          :sales_order_items_attributes => [:item_id, :price, :quantity]
                                          )
 end
nathanvda commented 3 years ago

Hi there, thank you for your first issue and taking the time to write a good and clear explanation.

The problem is your sales_order_params : because you do not allow the :id as a parameter for your sales-order-items, rails has no way of knowing if the received items match the existing ones and will assume they are new items.

So you will have to change your sales_order_params as follows:

:sales_order_items_attributes => [:id, :item_id, :price, :quantity, :_destroy]

So to be extra clear: I added

gabydi106 commented 3 years ago

Thank you so much for pointing this out to me. I have amended my code and it works smoothly now. I appreciate your detailed explanation as well. Today I learned something new :1st_place_medal: Thank you!

Issue resolved, will close with comment.