ruby-on-railsnested-formsform-forfields-fornested-form-for

Rails - Use fields_for to create multiple nested objects


Hoping someone can help out with this. I have two models order and date_order. Each order can have multiple date_orders, and I should be able to create many date_orders as I create an order.

How do I do that? As you can see, my code is working well for creating ONE date_order and relating it to the created order.

UPDATE: I have tried to create many "builders" in my orders/new file. It worked on the view, and created an order when I entered multiple dates and times. But the fields_for did not create any date_orders.

orders_controller.rb

def new
    @order = Order.new
    @order.date_orders.build
end

def create
    @order = Order.new(order_params)
    if @order.save
        flash[:success] = "blah"
        redirect_to @order
    else
        render 'new'
    end
end

private

def order_params
    params.require(:order).permit(:user_id, :purpose, 
    date_orders_attributes: [:id, :order_date, :time_start, :time_end, :order_id])
end

order.rb

class Order < ActiveRecord::Base

     has_many :date_orders, :dependent => :destroy
     accepts_nested_attributes_for :date_orders, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

date_order.rb

class DateOrder < ActiveRecord::Base
    belongs_to :order
end

order/new.html.erb

<%= form_for(@order, :html => {:multipart => true}) do |f| %>
    ## SOME QUESTIONS ##
    <%= f.fields_for :date_orders do |builder| %>
        <%= builder.label :date %>
        <%= builder.date_field :order_date %>

        <%= builder.label :starting_time %>
        <%= builder.time_field :time_start %>

        <%= builder.label :ending_time %>
        <%= builder.time_field :time_end %>

    <% end %>
<% end %>

Solution

  • Build more orders_dates:

    class OrdersController < ApplicationController
        def new
            @order = Order.new
            5.times { @order.date_orders.build }   # < === HERE ===
        end
    
        private
    
        def order_params
            params.require(:order).permit(:user_id, :purpose, 
            #                                 |-  === HERE ===
            date_orders_attributes: [:id, :content, :order_date, :time_start, :time_end, :order_id])
        end
    end
    

    Update:

    Also, add content to your strong params whitelist.