Как сохранить сразу два объекта в форме Rails?

Я использую Rails 4.2.3. Как сохранить два объекта в одной форме? У меня есть эти две модели …

class MyObject < ActiveRecord::Base
  belongs_to :user
  has_many :my_object_times
  attr_accessor :hour, :minute, :second

  accepts_nested_attributes_for :my_object_times
end

и

class MyObjectTime < ActiveRecord::Base
  belongs_to :my_object
end

Я хочу отправить одну форму, которая создает как объект MyObject, так и объект MyObjectTime. Поэтому я создал свою форму

<%= form_for @my_object do |f| %>
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label "Time" %>
    <%= select_tag('my_object[hour]', options_for_select((0..12).to_a), {:prompt => 'Select Hour'} ) %> hrs
    <%= select_tag('my_object[minute]', options_for_select((0..60).to_a), {:prompt => 'Select Minutes'} ) %> min
    <%= select_tag('my_object[second]', options_for_select((0..60).to_a), {:prompt => 'Select Seconds’} ) %> sec
    <%= f.fields_for :my_object_time do |mot| %>
      <%= mot.number_field :time_in_ms %>
    <% end %>
  </div>

  <div class="actions">
    <%= button_to "Save", { :action => "create" }, :method => :post, :class => 'button' %>
  </div>
<% end %>

и вот мой контроллер …

  def create
    @my_object = MyObject.new(my_object_params)
    @current_user = User.find(session["user_id"])
    @my_object.user = @current_user
    if @my_object.save
      respond_to do |format|
        format.html { redirect_to controller: "users", action: "index", notice: 'Saved successfully.' }
      end
    else
      format.html { render action: "index" }
    end
  end

  private

    def my_object_params
      # Main Code goes here
      params[:my_object][:time_in_ms] = (params[:my_object][:hour].to_i * 60 * 60 + params[:my_object][:minute].to_i * 60 + params[:my_object][:second].to_i) * 1000
      params.require(:my_object).permit(:name, my_object_times_attributes: [:time_in_ms])
    end

Однако сохраняется только объект MyObject, а не соответствующий MyObjectTime. Есть ли способ сделать так, чтобы и то, и другое было создано одновременно? Я не хочу ситуации, когда один создается, а второй нет. Я хочу, чтобы либо оба были созданы, либо ничего не происходило вообще и возвращалась ошибка.

1 ответ

  1. Так как у вас есть has_many :my_object_times, вы должны использовать my_object_times( множественное число ) вместо my_object_time( единственное число ) В fields_forи в my_object_paramsметоде

    <%= f.fields_for :my_object_times do |mot| %>
    

    И убедитесь, что у вас есть построить ребенка с родителем в newметоде

    #my_object_controller
    def new
      @my_object = MyObject.new
      @my_object.my_object_times.build
    end