Reputation: 1350
I have a typical has_many relationship between two models (lets say Article has_many Authors.)
My Article form lets the user:
I am using accepts_nested_attributes_for and this handles #1 perfectly. However, I am yet to find the best way of implementing #2 and #3 while still using accepts_nested_attributes_for.
I actually had this all working with Rails 3.0.0. ActiveRecord would automatically create a new association when given an Author id that it had not seen before. But it turned out I was accidentally exploiting the security bug that was then fixed in Rails 3.0.1.
I've tried a bunch of different approaches, but nothing works completely and I can't find much information on best practices in this case.
Any advice would be appreciate.
Thanks,
Russell.
Upvotes: 4
Views: 737
Reputation: 2375
For completeness, the way I'm doing this now is this:
class Article < ActiveRecord::Base
belongs_to :author, validate: false
accepts_nested_attributes_for :author
# This is called automatically when we save the article
def autosave_associated_records_for_author
if author.try(:name)
self.author = Author.find_or_create_by_name(author.name)
else
self.author = nil # Remove the association if we send an empty text field
end
end
end
class Author < ActiveRecord::Base
has_many :articles
end
I haven't found a way to validate the associated model (Author) with it's validations..
Upvotes: 1
Reputation: 7586
Assuming you probably need to use a join table. Give this a go:
class Article < ActiveRecord::Base
has_many :article_authors
accepts_nested_attributes_for :article_authors, allow_delete: true
end
class Author < ActiveRecord::Base
has_many :article_authors
end
class ArticleAuthor < ActiveRecord::Base
belongs_to :article
belongs_to :author
accepts.nested_attributes_for :author
end
# PUT /articles/:id
params = {
id: 10,
article_authors_attributes: {
[
# Case 1, create and associate new author, since no ID is provided
{
# A new ArticleAuthor row will be created since no ID is supplied
author_attributes: {
# A new Author will be created since no ID is supplied
name: "New Author"
}
}
],
[
# Case 2, associate Author#100
{
# A new ArticleAuthor row will be created since no ID is supplied
author_attributes: {
# Referencing the existing Author#100
id: 100
}
}
],
[
# Case 3, delete ArticleAuthor#101
# Note that in this case you must provide the ID to the join table to delete
{
id: 1000,
_destroy: 1
}
]
}
}
Upvotes: 2
Reputation: 11821
Look at this: http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes
its for rails 2.3, but most of the syntax is the same with rails3... It mentions all things you look for..
Upvotes: 1