Nested fields and strong parameters

ruby-on-rails, ruby-on-rails-4

Solution

Now that I think about it, it might be related to strong parameters. For update to work you need to allow `id` attributes also. In your permit params add id for `speakers` and any other nested nested resources in use that will be updated.

Please give this a try:

def event_params
  params.require(:event).permit(:title, :description, :type_id, :price, :program,
                              :start_date, :end_date, :image, category_ids: [],
                              speakers_attributes: [ :id, :name ])
end 

Problem

I am having a complex issue in Rails 4, which I will try to describe below. I am using simple form and awesome_nested_fields gems. I have a bunch of events with some fields in my app Here's my working event_controller params before the implementation of accepts_nested_attributes: ``` private def event_params params.require(:event).permit(:title, :description, :type_id, :price, :program, :start_date, :end_date, :image, category_ids: []) end ``` Now I would like to add some speakers to my events, and make the user decide, how many speakers he wants per event. So I'm adding the nested fields gem and making speakers a nested field, as per their documentation. Event.rb ``` class Event < ActiveRecord::Base has_many :speakers accepts_nested_attributes_for :speakers, allow_destroy: true end ``` Speaker.rb ``` class Speaker < ActiveRecord::Base belongs_to :event end ``` Adding speakers (inside my add event simple_form_for): ``` <%= f.nested_fields_for :speakers do |f| %> <fieldset class="item"> <%= f.label :name %> <%= f.text_field :name %> <a href="#" class="remove">remove</a> <%= f.hidden_field :id %> <%= f.hidden_field :_destroy %> </fieldset> <% end %> ``` Update controller for strong parameters: ``` private def event_params params.require(:event).permit(:title, :description, :type_id, :price, :program, :start_date, :end_date, :image, category_ids: [], speakers_attributes: [ :name ]) end ``` Now when I launch my app, upon creation of the new event I'm getting: ``` can't write unknown attribute `event_id' ``` If I remove the ``` speakers_attributes: [ :name ] ``` from the strong parameters I will be able to create my event, however when trying to view or edit it I will get ``` SQLite3::SQLException: no such column: speakers.event_id: SELECT "speakers".* FROM "speakers" WHERE "speakers"."event_id" = ? ``` And of course there are no speakers created in the database. ``` >> s = Speaker.first => nil ``` I will appreciate any help or advice. Thank you! ===== UPDATED for the duplications issue Events controller ``` def update @event = Event.find(params[:id]) if @event.update(event_params) flash[:success] = "Event updated" redirect_to @event else render @event end end ``` event.rb ``` class Event < ActiveRecord::Base belongs_to :type has_many :categorizations has_many :categories, through: :categorizations has_many :speakers accepts_nested_attributes_for :speakers, allow_destroy: true @today = Date.today def self.future_events order('start_date ASC').where('start_date >= ?', @today) end scope :current_events, lambda { where('start_date < ? and end_date > ?', @today, @today) } scope :past_events, lambda { order('end_date DESC').where('end_date < ?', @today) } scope :future_by_type, lambda { |type| order('start_date ASC').where('type_id = ? and start_date >= ?', type, @today) } scope :current_by_type, lambda { |type| order('start_date ASC').where('type_id = ? and start_date < ? and end_date > ?', type, @today, @today) } scope :past_by_type, lambda { |type| order('start_date ASC').where('type_id = ? and end_date < ?', type, @today) } validates :title, presence: true mount_uploader :image, ImageUploader before_save :define_end_date before_save :zero_price private def define_end_date self.end_date ||= self.start_date end def zero_price if self.price.empty? self.price = 0 end end end ```

Original source