Roemer
Roemer

Reputation: 3576

Associate existing models when creating a new one with many to many relations

I have the following models

# Database fields: id, name
Book < ActiveRecord::Base
    has_many :books_selections
    has_many :selections, :through => :books_selections

# Database fields: id, name
Selection < ActiveRecord::Base
    has_many :books_selections
    has_many :books, :through => :books_selections
    attr_accessible :books_attributes
    accepts_nested_attributes_for :books

# Database fields: book_id, selection_id
Books_Selection < ActiveRecord::Base
    belongs_to :book
    belongs_to :selection

Here a Selection is a collection of book, but because books can be in multiple selections I use the double has_many construction with a join table. Note that the join table does not have a 'id' attribute, is that a problem?

I try to let my Create action for Selection direct associate multiple existing Books to it. In the view, i dynamic create input elements, with e.g. the following final html:

<input type="hidden" name="selection[books_attributes][id]" value="5" />
<input type="hidden" name="selection[books_attributes][id]" value="9" />

The Create method of the Selection controller has no specific code in it, just:

@selection = Selection.new(params[:selection])

When the New view is submitted the selection is created (as a model) but the books are not associated with it. How can this be solved?

Upvotes: 1

Views: 390

Answers (1)

Viktor Tr&#243;n
Viktor Tr&#243;n

Reputation: 8894

Not sure how you populate you hidden field but its name selection[books_attributes][id] is incorrect. http://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions

For a has many association, nested attributes is an array of hashes:

selection.books_attributes = [{ :id => 5}, { :id => 9 }]

which will then send selection[books_attributes][][id].

Nested attributes are for situations when you are creating new associations or updating existsing ones. If you just want to assign existing books to selections, you can use selection[books_ids][].

Upvotes: 1

Related Questions