Answer by @François Beausoleil is awesome and solved a big problem. Great to learn about the concept of autosave_associated_record_for
.
However, I found one corner case in this implementation. In case of update
of existing post's author(A1
), if a new author name(A2
) is passed, it will end up changing the original(A1
) author's name.
p = Post.first
p.author #<Author id: 1, name: 'JK Rowling'>
# now edit is triggered, and new author(non existing) is passed(e.g: Cal Newport).
p.author #<Author id: 1, name: 'Cal Newport'>
Oringinal code:
class Post < ActiveRecord::Base
belongs_to :author, :autosave => true
accepts_nested_attributes_for :author
# If you need to validate the associated record, you can add a method like this:
# validate_associated_record_for_author
def autosave_associated_records_for_author
# Find or create the author by name
if new_author = Author.find_by_name(author.name)
self.author = new_author
else
self.author.save!
end
end
end
It is because, in case of edit, self.author
for post will already be an author with id:1, it will go in else, block and will update that author
instead of creating new one.
I changed the code(elsif
condition) to mitigate this issue:
class Post < ActiveRecord::Base
belongs_to :author, :autosave => true
accepts_nested_attributes_for :author
# If you need to validate the associated record, you can add a method like this:
# validate_associated_record_for_author
def autosave_associated_records_for_author
# Find or create the author by name
if new_author = Author.find_by_name(author.name)
self.author = new_author
elsif author && author.persisted? && author.changed?
# New condition: if author is already allocated to post, but is changed, create a new author.
self.author = Author.new(name: author.name)
else
# else create a new author
self.author.save!
end
end
end