这与活动记录缓存请求的方式以及处理多个关联的方式有关。
除非该关联在查找过程中被急切地加载了:include选项。在需要之前,Rails不会填充找到的记录的关联。当需要关联时
memoization
这样做是为了减少执行的SQL查询的数量。
单步执行问题中的代码:
post1 = Post.new(:title => 'Post 1')
comment1 = Comment.new(:content => 'content 1')
post1.comments << comment1 # updates post1's internal comments cache
post1.save
# Create a second Post object by find'ing the first
post2 = Post.find_by_title('Post 1')
# Add a new Comment to the first Post object
comment2 = Comment.new(:content => 'content 2')
post1.comments << comment2 # updates post1's internal comments cache
# Note that both Comments are associated with both Post objects even
# though I never explicitly associated it with post2.
post1.comment_ids # => [12, 13]
# this is the first time post2.comments are loaded.
# SELECT comments.* FROM comments JOIN comments.post_id = posts.id WHERE posts.id = #{post2.id}
post2.comment_ids # => [12, 13]
情景2:
post1 = Post.new(:title => 'Post 1A')
comment1 = Comment.new(:content => 'content 1A')
post1.comments << comment1
post1.save
# Create a second Post object by find'ing the first
post2 = Post.find_by_title('Post 1A')
# Add a new Comment to the first Post object
comment2 = Comment.new(:content => 'content 2A')
# first time post2.comments are loaded.
# SELECT comments.* FROM comments JOIN comments.post_id = posts.id WHERE
# posts.id = post2.comments #=> Returns one comment (id = 14)
# cached internally.
post1.comments << comment2
# Note that both Comments are associated with both Post objects even
# though I never explicitly associated it with post2.
post1.comment_ids # => [14, 15]
# post2.comment has already been cached, so the SQL query is not executed again.
post2.comment_ids # => [14]
N.B.
post2.comment_ids
内部定义为
post2.comments.map(&:id)
P.S.我的回答
this question
也许可以帮助你理解为什么post2会被更新,尽管你没有接触它。