How can I create, associate, and de-associate related records in Rails ActiveRecord with accepts_nested_attributes_for
I have a typical has_many relationship between two models (lets say Article has_many Authors.)
My Article form lets the user:
- Create new Authors and associate them with the Article,
- Select existing Authors to associate with the Article,
- Remove the association with an Author (without deleting the Author record.)
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 a开发者_如何学Pythonctually 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.
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
}
]
}
}
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..
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..
精彩评论