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

adding a replacement child via has_one doesn't delete original child

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.3.4
    • Affects Version/s: None
    • Component/s: None

      Hi,

      I'm somewhat new to Mongoid and MongoDB, my apologies if this doesn't actually turn out to be a bug.

      I'm using version 2.3.3 of Mongoid on Lion OS X, and here's the version of MongoDB that I'm using:

      ∴ mongod --version
      db version v2.0.0, pdfile version 4.5
      Sun Nov 20 22:35:17 git version: 695c67dff0ffc361b8568a13366f027caa406222
      

      When using has_one/belongs_to, and when replacing one belongs_to object with another, it looks like Mongoid is not destroying the replaced child.

      Given:

      ## A is parent of B
      class A
        include Mongoid::Document
        has_one :b, dependent: :destroy, autosave: true
      end
      
      class B
        include Mongoid::Document
        belongs_to :a
      end
      
      ## C is parent of D
      class C
        include Mongoid::Document
        embeds_one :d  
      end
      
      class D
        include Mongoid::Document
        embedded_in :c
      end
      

      When using has_one/belongs_to, I'm seeing the incorrect behavior:

      ruby-1.9.2-p180 :055 > a = A.create!
      #<A _id: 4ec9f0cea9ffd1dee200000a, _type: nil>
      ruby-1.9.2-p180 :056 > a.create_b
      #<B _id: 4ec9f0d2a9ffd1dee200000b, _type: nil, a_id: BSON::ObjectId('4ec9f0cea9ffd1dee200000a')>
      ruby-1.9.2-p180 :057 > a.create_b
      #<B _id: 4ec9f0d5a9ffd1dee200000c, _type: nil, a_id: BSON::ObjectId('4ec9f0cea9ffd1dee200000a')>
      ruby-1.9.2-p180 :058 > B.all.to_a
      MONGODB db_dev['bs'].find({})
      [
          [0] #<B _id: 4ec9f0d2a9ffd1dee200000b, _type: nil, a_id: BSON::ObjectId('4ec9f0cea9ffd1dee200000a')>,
          [1] #<B _id: 4ec9f0d5a9ffd1dee200000c, _type: nil, a_id: BSON::ObjectId('4ec9f0cea9ffd1dee200000a')>
      ]
      

      And here's a dump of the A and B collections via mongoexport:

      ∴ mongoexport --db db_dev --collection as
      connected to: 127.0.0.1
      { "_id" : { "$oid" : "4ec9f0cea9ffd1dee200000a" } }
      exported 1 records
      ∴ mongoexport --db db_dev --collection bs
      connected to: 127.0.0.1
      { "_id" : { "$oid" : "4ec9f0d2a9ffd1dee200000b" }, "a_id" : { "$oid" : "4ec9f0cea9ffd1dee200000a" } }
      { "_id" : { "$oid" : "4ec9f0d5a9ffd1dee200000c" }, "a_id" : { "$oid" : "4ec9f0cea9ffd1dee200000a" } }
      exported 2 records
      

      In contrast, when using embeds_one/embedded_in, I see correct behavior:

      ruby-1.9.2-p180 :059 > c = C.create!
      #<C _id: 4ec9f0e5a9ffd1dee200000d, _type: nil>
      ruby-1.9.2-p180 :060 > c.create_d
      #<D _id: 4ec9f0eba9ffd1dee200000e, _type: nil>
      ruby-1.9.2-p180 :061 > c.create_d
      #<D _id: 4ec9f0eda9ffd1dee200000f, _type: nil>
      ruby-1.9.2-p180 :062 > C.all.map{|c|c.d}
      MONGODB db_dev['cs'].find({})
      [
          [0] #<D _id: 4ec9f0eda9ffd1dee200000f, _type: nil>
      ]
      

      And here's a dump of the A collection via mongoexport:

      ∴ mongoexport --db db_dev --collection cs
      connected to: 127.0.0.1
      { "_id" : { "$oid" : "4ec9f0e5a9ffd1dee200000d" }, "d" : { "_id" : { "$oid" : "4ec9f0eda9ffd1dee200000f" } } }
      exported 1 records
      

      It doesn't seem to matter which method I use to create the B-child object: a.create_b() and B.create!(a: a) both produce the same behavior as show above.

      Additionally, I get the same behavior whether I use either of the following:

      has_one :b, dependent: :destroy, autosave: true
      

      or:

      has_one :b
      

      Unfortunately, because the "foreign key" is kept in the child object, Mongoid doesn't realize that the newest child added is the correct one:

      ruby-1.9.2-p180 :013 > a.b
      MONGODB db_dev['bs'].find({"a_id"=>BSON::ObjectId('4ec9f0cea9ffd1dee200000a')}).limit(-1).sort([[:_id, :asc]])
      #<B _id: 4ec9f0d2a9ffd1dee200000b, _type: nil, a_id: BSON::ObjectId('4ec9f0cea9ffd1dee200000a')>
      

      Thanks!

            Assignee:
            Unassigned Unassigned
            Reporter:
            jasonsydes Jason Sydes
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: