-
Type:
Bug
-
Resolution: Duplicate
-
Priority:
Major - P3
-
None
-
Affects Version/s: 9.1.0
-
Component/s: Associations, Persistence
-
None
Assigning a new `embeds_one` document to an *already-persisted* parent (with timestamps) and saving does not write the embedded document. It looks correct in memory (`child.persisted? == true`) but never reaches MongoDB.
*Broken:* 9.1.0 — `reloaded child` is `nil`
*Works:* 9.0.11 — `reloaded child` has `value: "hello"`
Cause
9.1.0 added touch-merging to `Persistable::Creatable#insert_as_embedded`:
operations = atomic_inserts # embeds_one ⇒ { '$set' => { '<assoc>' => {...} } } operations['$set'] = touches # ⚠️ overwrites the embedded insert's $set
For an `embeds_one`, `atomic_inserts` is a `$set` carrying the whole embedded document, so overwriting it with the touch `$set` drops the insert. (`embeds_many` uses `$push`, so it's unaffected.) Fix is to merge, like previous version did:
operations['$set'] = (operations['$set'] || {}).merge(touches)
Repro
Attached self-contained (pins the gem via `bundler/inline`), needs a local MongoDB. Run `ruby BUG_REPRO.rb`; swap the pin to `9.0.11` to see it pass.
- duplicates
-
MONGOID-5944 Broken embeds_one insert on parent which gets touched
-
- Closed
-