nestedsaveruby-on-rails-5fields-for

fields_for not saving nested parameters in rails 5.0.1


I'm fairly new to rails, though I've made some basic apps and read several tutorials, this is the first time I've delved into nested attributes inside forms and the use of fields_for.

I've searched trough many similar questions and have read the documentation on fields_for, however my form doesn't seem to save whenever I use fields_for inside my form. I've tested without the fields_for and saves as it should (without saving to the nested DB, obviously).

What I'm trying to do is a simple Event registration, which in turn has some attributes and a date in a separate model.

I've tried with and without validations, many different things inside the strong parameters

Here is my Event models:

class Event < ApplicationRecord
  has_many :eventdates, dependent: :destroy
  accepts_nested_attributes_for :eventdates

  validates :name, :description, :city, :street, :postal_code, presence: true

end

The Eventdate model:

class Eventdate < ApplicationRecord
  belongs_to :event

  validates :date, :start_hour, :finish_hour, :event_id, presence: true
end

The Event controller:

class EventsController < ApplicationController

  def new
    @event = Event.new
    @event.eventdates.build
  end

  def create
    @event = Event.new(event_params)
    if @event.save
      redirect_to root_url
    else
      render "static_pages/home"
    end
  end

  private

    def event_params
      params.require(:event).permit(:name, :description, :street, :city, :postal_code, :address_number, :additional_info, 
      eventdates_attributes: [:id, :date, :start_hour, :finish_hour, :event_id])
    end

And the form:

<%= form_for(@event, url: events_path) do |f| %>
  <p>
    <%= f.label :nombre %>
    <%= f.text_field :name %>
  </p>

  <div>
    <%= f.fields_for :eventdates do |eventdate_fields| %>

      <%= eventdate_fields.label :fecha %>
      <%= eventdate_fields.date_field :date %>

      <%= eventdate_fields.label :hora_de_inicio %>
      <%= eventdate_fields.time_field :start_hour %>

      <%= eventdate_fields.label :hora_de_termino %>
      <%= eventdate_fields.time_field :finish_hour %>
    <% end %>
  </div>

  <p>
  <%= f.label :infomaciĆ³n_adicional %>
  <%= f.text_area :additional_info %>
  </p>

  <p>
    <%= f.submit "Crear evento" %>
  </p>
<% end %>

I'm pretty sure this is a very simple form, but somehow refuses to save at all into the database.


Solution

  • In eventdate.rb model, append optional: true to this line: belongs_to :event

    class Eventdate < ApplicationRecord
      belongs_to :event, optional: true
    
      validates :date, :start_hour, :finish_hour, :event_id, presence: true
    end
    

    Because Rails will create eventdates first, then create event and links to those evendates (by updating all event_id in these evendates). But when creating eventdates, column event_id is nil and eventdates cannot be saved.