Arel
Arel

Reputation: 3938

HABTM Adding new associations to join table

How do I add multiple records to a has_and_belongs_to_many table between two models?

All I can figure out how to do so far is create one record, and then update that record. I want to add multiple records to the join table.

Right now I have a collection_select, but the update method only allows me to update the record, not add new records.

My best guess is to add something like @group.workouts << workout_id to the update method in the group controller, but I can't figure out how to get it to work.

Am I on the right track here?

I am trying to add workouts to groups and groups to workouts.

Thanks for the help!

EDIT 1:

I have a collection_select that allows me to add a single record to the join table, but I'm trying to figure out how to add a second, third, etc. record to the join table. My collection_select is:

<div class="field">
    <%= f.collection_select 'workout_ids', Workout.all, :id, :name, { :include_blank => ""} %>
</div>

So simply, I want to add a workout to a group, which I can do. Then I want to add another workout to that same group, then another, etc.

Upvotes: 1

Views: 2431

Answers (2)

Arel
Arel

Reputation: 3938

EDIT:

The actual way to do this properly is detailed in this Gist

So the answer to this is to edit the update action in the controller with this:

workout_id = params[:group].delete(:workout_ids)

    # Adding a workout
    if workout_id
      workout = Workout.find(workout_id)
      @group.workouts << workout
    end

The above code creates a local variable workout_id that takes the parameters :group and :workout_id from within :group the .delete method removes the second parameter for updating the actual group when you change the name of the group, for example.

Then we simply push a new workout onto @group.workouts, creating a new record in the join table every time we add a new workout to the group from the collection select.

Upvotes: 5

Andrew
Andrew

Reputation: 43113

In the console you can do like you guessed:

group.workouts << workout

or

workout.groups += [group_a, group_b, group_c]

Of the top of my head I think you'll want to pass actual objects, not just the IDs, but it may work both ways.

In a form builder should be able to use collection_select for this:

= form_for @workout do |f|
  = f.collection_select :group_id, Group.all, :id, :name, :prompt => true

Other tools like Simple Form's association method make this easier.

Upvotes: 2

Related Questions