Before I post this as a bug to the rails team, I wanted to see if I'm doing something wrong that may be causing this behavior. Specifically, the :autosave property of has_many associations doesn't seem to be working as per the docs.
For reference, here is the most current API documentation: http://api.rubyonrails.org/classes/Acti … ation.html
Take a look at the "One-to-many Example" section. I have duplicated the code there exactly in a test application, and it isn't working for me. Specifically, the parent object is updated, but the child object is not.
My schema is as follows:
create_table :posts do |t|
t.string :title
t.timestamps
end
create_table :comments do |t|
t.text :body
t.integer :post_id
t.timestamps
My models are as follows:
class Post < ActiveRecord::Base
has_many :comments, :autosave => true
end
class Comment < ActiveRecord::Base
belongs_to :post
end
In the console, I run the following commands (the post and comments objects are already in the DB at this point):
post = Post.find(1)
post.title # => "The current global position of migrating ducks"
post.comments.first.body # => "Wow, awesome info thanks!"
post.comments.last.body # => "Actually, your article should be named differently."
post.title = "On the migration of ducks"
post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
post.save
post.reload
But this is what I get for output:
post.title # => "On the migration of ducks"
post.comments.last.body # => "Actually, your article should be named differently."
Further, looking in the logs this is the only update statement I see:
Post Update (0.6ms) UPDATE "posts" SET "updated_at" = '2010-01-18 23:32:39', "title" = 'On the migration of ducks' WHERE "id" = 1
So it appears that the save didn't cascade down to the comments object, which seems clearly broken to me. I have tried this on two different systems running 2.3.4 and the behavior is repeatable.
Here's the weird part, though: If I first call "post.comments" before I try to set the value, it works fine! To be exact:
post.title = "On the migration of ducks"
post.comments #Note that this line was not called above
post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
post.save
post.reload
Now the output gives me the correct results:
post.title # => "On the migration of ducks"
post.comments.last.body # => "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
And the logs contain the correct update:
Comment Update (0.3ms) UPDATE "comments" SET "updated_at" = '2010-01-18 23:44:43', "body" = 'Actually, your article should be named differently. [UPDATED]: You are right, thanks.' WHERE "id" = 2
So this really looks broken to me. I'm guessing that it's a problem with the way that object references are handled, i.e. that once the object is part of an allocated collection it saves fine but does not save when it is pulled as a single object from the database. But before I submit this to the Rails team as a bug I wanted to see if anybody else had run into this issue, or if I'm just doing something completely boneheaded that I'm not seeing because I've spent all day on this.