-
Type: Task
-
Resolution: Done
-
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!