Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5254

Reassigning has_one persists as nil

    • Type: Icon: Bug Bug
    • Resolution: Won't Do
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • None

      The following case has a problem, take the following class:

      class Post
        include Mongoid::Document
        field :title, type: String
      
        has_one :comment, inverse_of: :post
      end
      
      class Comment
        include Mongoid::Document
      
        field :content, type: String
        belongs_to :post, inverse_of: :comment, optional: true
      end

      And then we do the following operations:

      post = Post.create!
      comment1 = Comment.create!(content: "Comment 1")
      comment2 = Comment.create!(content: "Comment 2") 
      
      post.comment = comment1
      post.reload
      expect(post.comment).to eq(comment1) # works
      
      post.comment = comment2
      post.reload
      expect(post.comment).to eq(comment2) # works
      
      post.comment = comment1
      post.reload
      expect(post.comment).to eq(comment1) # fails: post.comment returns nil

      I have successfully identified the bug here. What's happening is:

      1. We are setting post.comment to comment1, which populates the post_id on the comment
      2. We reload, now post.comment does not refer to the same object as comment1
      3. Assign comment2 to post.comment. Now comment1 is out of sync, since when assigning comment2 to post.comment, it populates the post_id on comment2 and removes the post_id of the original comment. However, since post.comment no longer refers to the same object as comment1, comment1 still has the post_id populated, while in the database its post_id is nil. Note that this problem disappears and the test passes if you reload the comment.
      4. Reassign comment1. During this operation, we try to update comment1 with the post_id, since it's post_id should be nil, and when we try to persist the operation, mongoid sees no changes made to the document and doesn't persist it. 

      To reiterate, the problem arises when you try to assign to a has_one relationship with the correct foreign key already (and prematurely) assigned to the object. This can happen in two ways, in the case described above, and in that case where you try to set the same object to the has_one multiple times. The second case is MONGOID-4646.

            Assignee:
            neil.shweky@mongodb.com Neil Shweky (Inactive)
            Reporter:
            neil.shweky@mongodb.com Neil Shweky (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: