Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add association (<<) without committing to database

Is it possible in Rails to add an association to an existing record without immediately committing this change to the database? E.g. if I have Post has_many :tags

post.tags << Tag.first

This will commit to database immediately. I've tried other ways instead of <<, but without success (what I want is to create the association when saving the parent object). Is it possible to get behavior like when you are adding association to a new record with build?

post.tags.build name: "whatever"

I think this is kind of inconsistent in Rails, in some cases it would be useful to have an option to do this.

In other words I want

post.tags << Tag.first # don't hit the DB here!
post.save # hit the DB here!
like image 557
mrbrdo Avatar asked Nov 02 '12 14:11

mrbrdo


3 Answers

This should work in Rails 3.2 and Rails 4:

post.association(:tags).add_to_target(Tag.first)

See this gist: https://gist.github.com/betesh/dd97a331f67736d8b83a

Note that saving the parent saves the child and that child.parent_id is NOT set until you save it.

EDIT 12/6/2015: For a polymorphic record:

post.association(:tags).send(:build_through_record, Tag.first)
# Tested in Rails 4.2.5
like image 121
Isaac Betesh Avatar answered Nov 09 '22 19:11

Isaac Betesh


post_tag = post.post_tags.find_or_initialize_by_tag_id(Tag.first.id)
post_tag.save
like image 3
jimworm Avatar answered Nov 09 '22 20:11

jimworm


To add to Isaac's answer, post.association(:tags).add_to_target(Tag.first) works for has_many relationships, but you can use post.association(:tag).replace(Tag.first, false) for has_one relationships. The second argument (false) tells it not to save; it will commit it to the database by default if you leave the argument empty.

like image 1
John Mangel Avatar answered Nov 09 '22 18:11

John Mangel