ฉันพบพฤติกรรม ActiveRecord ของ Rails 2.3.5 บางอย่างที่ฉันไม่เข้าใจ ดูเหมือนว่าออบเจ็กต์สามารถอัปเดตรหัสการเชื่อมโยงในลักษณะที่ไม่สอดคล้องกัน
นี่เป็นคำอธิบายที่ดีที่สุดด้วยตัวอย่าง:
สร้างโมเดล Post
ด้วยแอตทริบิวต์สตริง 'title'
และโมเดล Comment
ด้วยแอตทริบิวต์สตริง 'content'
นี่คือสมาคม:
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
end
สถานการณ์ #1: ในโค้ดต่อไปนี้ ฉันสร้าง Post
อันหนึ่งโดยมี Comment
ที่เกี่ยวข้องกัน สร้างอันที่สอง Post
โดย find
' โดยอันแรก เพิ่ม Comment
อันที่สองเข้ากับอันแรก Post
และค้นพบว่าอันที่สอง Post
มีอันที่สอง Comment
เชื่อมโยงอยู่ด้วยโดยไม่มี การมอบหมายที่ชัดเจน
post1 = Post.new
post1 = Post.new(:title => 'Post 1')
comment1 = Comment.new(:content => 'content 1')
post1.comments << comment1
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
# Note that both Comments are associated with both Post objects even
# though I never explicitly associated it with post2.
post1.comment_ids # => [12, 13]
post2.comment_ids # => [12, 13]
สถานการณ์ #2: เรียกใช้คำสั่งข้างต้นอีกครั้ง แต่คราวนี้ใส่คำสั่งพิเศษหนึ่งคำสั่งที่ด้านหน้าของคำสั่งนั้น ไม่ควรส่งผลกระทบต่อผลลัพธ์ คำสั่งพิเศษคือ post2.comments
ซึ่งเกิดขึ้น หลัง สร้าง comment2
และ ก่อน เพิ่ม comment2
ไปยัง post1
post1 = Post.new
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')
post2.comments # !! THIS IS THE EXTRA COMMAND !!
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_ids # => [14]
โปรดทราบว่ามีเพียง หนึ่ง ความคิดเห็นที่เกี่ยวข้องกับ post2
ในสถานการณ์นี้ ในขณะที่ในสถานการณ์ที่ 1 มีเพียงสองความคิดเห็น
คำถามสำคัญ: เหตุใดการรัน post2.comments
ก่อนที่จะเพิ่ม Comment
ใหม่เป็น post1
จึงสร้างความแตกต่างให้กับความคิดเห็นที่เกี่ยวข้องกับ post2