title: Rails 5 Has Many Through with Nested Form and Cocoon
body: <p><strong>Solverd: see bottom</strong></p>
  
  <p>I am building a ordering system of many products, with a HBTM from Join Table to anotherModel, but I have some problems when creating and editing a new record of a nested form.</p>
  
  <p>I have tried many solutions from other questions and followed some tutorial like <a href="https://www.sitepoint.com/better-nested-attributes-in-rails-with-the-cocoon-gem/" rel="nofollow noreferrer">this</a> or <a href="https://github.com/nathanvda/cocoon/wiki/A-guide-to-doing-nested-model-forms" rel="nofollow noreferrer">this</a>, but nothing solved my issues.</p>
  
  <p>Product Model:</p>
  
  <pre><code>class Product &lt; ApplicationRecord
    belongs_to :subcategory
  
    has_many :order_products, inverse_of: :product
    has_many :order, :through =&gt; :order_products
  end
  </code></pre>
  
  <p>Order Model:</p>
  
  <pre><code>class Order &lt; ApplicationRecord
    has_many :order_products, inverse_of: :order
    has_many :products, :through =&gt; :order_products
  
    accepts_nested_attributes_for :products, reject_if: :all_blank, allow_destroy: true
  end
  </code></pre>
  
  <p>Join Table:</p>
  
  <pre><code>class OrderProduct &lt; ApplicationRecord
    belongs_to :order
    belongs_to :product
  
    has_and_belongs_to_many :ingredients
    accepts_nested_attributes_for :ingredients, reject_if: :all_blank, allow_destroy: true    
  end
  </code></pre>
  
  <p>Ingredients Model associated with join table: (<strong>many-to-many</strong> to save added ingredients to every products on the order)</p>
  
  <pre><code>class Ingredient &lt; ApplicationRecord
    has_and_belongs_to_many :order_products
  end
  </code></pre>
  
  <p>Order Controller:</p>
  
  <pre><code>  # GET /orders/new
    def new
      @order = Order.new
    end
  
    # GET /orders/1/edit
    def edit
    end
  
    # POST /orders
    # POST /orders.json
    def create
      @order = Order.new(order_params)
  
      respond_to do |format|
        if @order.save
          format.html { redirect_to @order, notice: 'Order was successfully created.' }
          format.json { render :show, status: :created, location: @order }
        else
          format.html { render :new }
          format.json { render json: @order.errors, status: :unprocessable_entity }
        end
      end
    end
  
      def order_params
        params.require(:order).permit(:subtotal, :discount, :total,
        order_products_attributes: [[:id, :order_id, :product_id , :_destroy]])
      end
  </code></pre>
  
  <p>Views:</p>
  
  <pre><code>&lt;%= simple_form_for(@order) do |f| %&gt;
    &lt;%= f.error_notification %&gt;
  
    &lt;div class="form-inputs"&gt;
      &lt;%= f.input :subtotal %&gt;
      &lt;%= f.input :discount %&gt;
      &lt;%= f.input :total %&gt;
    &lt;/div&gt;
  
    &lt;%= f.simple_fields_for :order_products do |o| %&gt;
        &lt;%= render 'order_product_fields', f: o %&gt;
    &lt;% end %&gt;
  
    &lt;%= link_to_add_association "aggiungi prodotto", f, :order_products %&gt;
  
    &lt;div class="form-actions"&gt;
      &lt;%= f.button :submit %&gt;
    &lt;/div&gt;
  &lt;% end %&gt;
  </code></pre>
  
  <p>Partial: (unable to add cocoon's destroy link: <strong>undefined method `reflect_on_association' for NilClass:Class</strong> due to auto add of blank fields)</p>
  
  <pre><code>&lt;div class="nested-fields order-product-fields"&gt;
    &lt;%= f.input :product %&gt;
    &lt;%= f.input :order %&gt;
  
    &lt;%= f.check_box :_destroy %&gt;
  
  &lt;/div&gt;
  </code></pre>
  
  <p>I get this on console:</p>
  
  <pre><code> Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"PRNzrnxk/jrsAyPK5OzFxix2hIUmjCeWpD8Fkuhuhx8Wp3/xYTbTTvsfQkhnMDEBNnC/iNL46kl68XR7skb03g==", "order"=&gt;{"subtotal"=&gt;"", "discount"=&gt;"", "total"=&gt;"", "order_products"=&gt;{"product"=&gt;"", "order"=&gt;"", "_destroy"=&gt;"0"}}, "commit"=&gt;"Create Order"}
  Unpermitted parameter: order_products
  </code></pre>
  
  <p>My throubles are: <strong>EDIT: Solution on each point</strong></p>
  
  <ol>
  <li>When I load order pages, <strong>blanks fields for nested attributes are automatically created</strong> ()</li>
  </ol>
  
  <p><strong>Was wrong nested_attributes on Order Model:</strong></p>
  
  <pre><code>accepts_nested_attributes_for **:order_products**, reject_if: :all_blank, allow_destroy: true
  </code></pre>
  
  <ol start="2">
  <li><p>When submitting form no entry are created. (but I can add product to order via console .ex: order.products &lt;&lt; product1)</p></li>
  <li><p>When I add more product via cocoon's add link, <strong>only first is sent to controller</strong></p></li>
  <li>Don't know how to implements Strong Parameters and views for Ingredient's attributes inside the form of Order</li>
  </ol>
  
  <p>Got this working:</p>
  
  <p>Ingredient model:</p>
  
  <pre><code>has_many :ingredient_order_products, inverse_of: :ingredient
  has_many :order_products, :through =&gt; :ingredient_order_products
  </code></pre>
  
  <p>IngredientOrderProduct model:</p>
  
  <pre><code>  belongs_to :ingredient
    belongs_to :order_product
  </code></pre>
  
  <p>Order Product model:</p>
  
  <pre><code>  has_many :ingredient_order_products, inverse_of: :order_product
    has_many :ingredients, :through =&gt; :ingredient_order_products
    accepts_nested_attributes_for :ingredient_order_products, reject_if: :all_blank, allow_destroy: true
  </code></pre>
  
  <p>Order Controller:</p>
  
  <pre><code>def order_params
    params.require(:order).permit(:customer_id, :subtotal, :discount, :total,
    order_products_attributes: [[:id, :order_id, :product_id, :qty, :gift, :_destroy,
      ingredient_order_products_attributes: [:id, :order_id, :ingredient_id, :_destroy]]])
  end
  </code></pre>
  
  <p>_order_product_fields Partial:</p>
  
  <pre><code>  &lt;div id="ingredient"&gt;
      &lt;%= f.simple_fields_for :ingredient_order_products do |ingredient| %&gt;
        &lt;%= render 'ingredient_order_product_fields', f: ingredient %&gt;
      &lt;% end %&gt;
      &lt;%= link_to_add_association "Aggiungi Ingrediente", f, :ingredient_order_products %&gt;
    &lt;/div&gt;
  </code></pre>