Ask A Question

Notifications

You’re not receiving notifications from this thread.

Nested attributes with collection_select not saving

Brent C asked in General

In my edit form I simply cannot figure out why collection_select isn’t saving the various values when it's nested. It works fine if I use a {multiple: true} and pull it outside of the fields_for event_types. Am I missing something? I have tried many configurations regarding strong params.. nothing.

Thanks for any assistance.


class Race < ActiveRecord::Base
    has_many :race_events, dependent: :destroy
    has_many :event_types, through: :race_events 
    accepts_nested_attributes_for :event_types
end

class EventType < ActiveRecord::Base
    belongs_to :discipline
      has_many :race_events
      has_many :races, through: :race_events
end

class RaceEvent < ActiveRecord::Base
      belongs_to :race
      belongs_to :event_type
end

class RacesController < ApplicationController

  def edit
    authorize! :add_details, @race
    if @race.links.empty?
      @race.links.new
    end
  end

  def update
    authorize! :add_details, @race
    if @race.update(race_params)
      redirect_to …
    else
      render :edit
    end
  end
end

private
  def race_params
    params.require(:race).permit(:name, :description,:event_type_ids => [], event_types_attributes: [:id, :name])
end

Edit View

<%= form_for(@race, ... ) do |f| %>
  <%= f.fields_for :event_types do |event|  %>  

    <%= event.collection_select(:id, EventType.all, :id, :name) %> # This displays the collections correctly but they don's save when updated.

  <% end %>
  ...
<% end %>

Reply

Are you specifically having trouble saving the records or is the form having trouble rendering?

Reply

Saving the records. Form renders perfectly.

Reply

Okay cool. Can you paste the log of the post request?

Reply
Started PATCH "/assistants/134-gilbert-event" for ::1 at 2015-03-19 13:36:57 -0700
Processing by AssistantsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"nsJc3ywZCW9hhk7fyY3jZeuwEhTpOQ4IwOxVYUoLRuMplW7bkCnHZgrt024RL0NVa8v6doFaJPjVPcwTc2Hxg==", "race"=>{"name"=>"Gilbert Event", "race_date"=>"2014-11-22", "city"=>"Gilbert", "state"=>"Alabama", "address"=>"", "zipcode"=>"", "country"=>"Australia", "email"=>"director@gilbertevent.org", "phone"=>"", "links_attributes"=>{"0"=>{"website"=>"http://gilbertevent.org", "registration"=>"", "other"=>"", "id"=>"32"}}, "start_time(1i)"=>"2000", "start_time(2i)"=>"1", "start_time(3i)"=>"1", "start_time(4i)"=>"00", "start_time(5i)"=>"00", "price"=>"", "event_types_attributes"=>{"0"=>{"id"=>"2"}, "1"=>{"id"=>"3"}, "2"=>{"id"=>"5"}, "3"=>{"id"=>"6"}}, "headline"=>"", "description"=>""}, "va"=>"employee_11", "commit"=>"Add Race", "id"=>"134-gilbert-event"}

Reply

I got it!

Since I was dealing with a has_many through relationship I needed to reorder a few things. I will post it up shortly.

:)

Reply

Brent,

Definitely post up what you changed so that it may help others.

Reply

Awesome, glad you got it fixed. I'd love to see the solution as well. Sometimes it is hard to debug those issues.

Reply

First thing was organization. In order to achieve my main goal, I had to rethink what I was trying to do first. Needing to create/update new RaceEvents(join Model) for each Race. However for each RaceEvent I needed to display all the options in a collection_select that was populated from EventTypes.

The short of it was to make the join model my nested model form and inside of that fields_for block, add the collection_select. I then needed to make sure those params were accepted so I had to edit my strong params to make reference of the event_type_id in side of the join models attributes. I will display the updated code below.

class Race < ActiveRecord::Base
  has_many :race_events, dependent: :destroy
  has_many :event_types, through: :race_events
  accepts_nested_attributes_for :race_events, allow_destroy: true
end

class EventType < ActiveRecord::Base
  has_many :race_events
  has_many :races, through: :race_events
  accepts_nested_attributes_for :race_events
end

class RaceEvent < ActiveRecord::Base
  belongs_to :race
  belongs_to :event_type    
end

Now for the Strong Params. Notice how in the join model attributes (race_events_attributes) I needed to include :event_type_id. This through me for awhile. It’s needed to make the proper association, seems almost obvious now. But a couple days ago it definitely wasn’t. :P

def race_params
    params.require(:race).permit(:name, :description, race_events_attributes: [:id, :price, :summary, :event_type_id, :_destroy] )
  end
end

Finally the view. A couple of gotchas here too. On the collection_select it’s not necessary and important not to include the object directly. This seems to cause a bit of confusion (as this is most of the people problems regarding Collection_select on SO)

<%= form_for @race do |f| %>
   <%= f.fields_for :race_events do |event| %>
    <div>
      <%= event.collection_select :event_type_id, EventType.all, :id, :name %>
      <%= event.text_area :summary %>
      <%= event.text_field :price %>
      <%= event.check_box :_destroy %>
      <%= event.label :_destroy, “remove event” %>
    </div>
  <% end %>
<% end %>

At the end of the day, it wasn’t one problem it was an assortment that needed rethinking and refactoring to get working properly.

Hope that clears it up a little for anyone in need. And thanks GoRails team and community for support!

Reply

Ah, I see where you're going with this. Makes sense to me. Good catch(s).

Reply

Thanks. Yeah, as you can see and as Chris mentioned it was a bugger of a bug. Hard to nail down what was causing the issue, just took some time.

Reply

Brent, could you post your schema.rb and your race controller? Maybe it's just me, but I don't really understand why you have so many attributes in the relationship model (EventRace).

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 86,946+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.