>> patrick = Poster.first
=> #<Poster id: 1, name: "Patrick S.", created_at: "2009-03-21 03:55:17", updated_at: "2009-03-21 03:55:17">
>> patrick.posts.size
=> 0
>> new_post = patrick.posts.new(:title => "Another post")
=> #<Post id: nil, title: "Another post", text: nil, poster_id: 1, created_at: nil, updated_at: nil>
>> patrick.posts.size
=> 0
If I like the post and decide to save it to the database, my cached posts still doesn't get updated:
>> new_post.save
=> true
>> patrick.posts.size
=> 0
In order to get the collection up-to-date I have to know that this is a trouble spot, and call #reload on the association:
>> patrick.posts.reload; patrick.posts.size
=> 1
If, instead, I try to push that new instance onto the collection explicitly, it gets saved automatically, which doesn't seem very intuitive (I *much* prefer to have to explicitly save changes to the database):
>> patrick.posts << Post.new(:title => "pushing onto collection")
Post Create (0.8ms) INSERT INTO "posts" ("created_at", "title", "poster_id", "updated_at", "text") VALUES('2009-03-21 06:14:03', 'pushing onto collection', 1, '2009-03-21 06:14:03', NULL)
=> [#<Post id: 12, title: "pushing onto collection", text: nil, poster_id: 1, created_at: "2009-03-21 06:14:03", updated_at: "2009-03-21 06:14:03">]
The right way to do this seems to be the undocumented #build, which does exactly what I was wanting in the first place (create an unsaved instance and append it to the collection):
>> patrick.posts.size
=> 0
>> patrick.posts.build(:title => 'Built')
=> #<Post id: nil, title: "Built", text: nil, poster_id: 1, created_at: nil, updated_at: nil>
>> patrick.posts.size
=> 1
>> patrick.posts
=> [#<Post id: nil, title: "Built", text: nil, poster_id: 1, created_at: nil, updated_at: nil>]
>> patrick.posts[0].new_record?
=> true
(Unfortunately, there seems to be a related problem with the association's #delete/#destroy)
>> patrick.posts.size
=> 2
>> patrick.posts.last
=> #<Post id: 13, title: "Another", text: nil, poster_id: 1, created_at: "2009-03-21 06:19:55", updated_at: "2009-03-21 06:19:55">
>> patrick.posts.last.destroy
=> #<Post id: 13, title: "Another", text: nil, poster_id: 1, created_at: "2009-03-21 06:19:55", updated_at: "2009-03-21 06:19:55">
>> patrick.posts.size
=> 2
>> patrick.posts.reload; patrick.posts.size
=> 1
