@@ -300,3 +300,44 @@ An _id, a hash of conditions, or ``false``/``nil`` can now be included:
300
300
Band.exists?(BSON::ObjectId('6320d96a3282a48cfce9e72c'))
301
301
Band.exists?(false) # always false
302
302
Band.exists?(nil) # always false
303
+
304
+
305
+ Added ``:replace`` option to ``#upsert``
306
+ ----------------------------------------
307
+
308
+ Mongoid 8.1 adds the ``:replace`` option to the ``#upsert`` method. This option
309
+ is ``false`` by default.
310
+
311
+ In Mongoid 8 and earlier, and in Mongoid 8.1 when passing ``replace: true``
312
+ (the default) the upserted document will overwrite the current document in the
313
+ database if it exists. Consider the following example:
314
+
315
+ .. code:: ruby
316
+
317
+ existing = Player.create!(name: "Juan Soto", age: 23, team: "WAS")
318
+
319
+ player = Player.new(name: "Juan Soto", team: "SD")
320
+ player.id = existing.id
321
+ player.upsert # :replace defaults to true in 8.1
322
+
323
+ p Player.find(existing.id)
324
+ # => <Player _id: 633b42f43282a45fadfaaf9d, name: "Juan Soto", age: nil, team: "SD">
325
+
326
+ As you can see, the value for the ``:age`` field was dropped, because the
327
+ upsert replaced the entire document instead of just updating it. If we take the
328
+ same example and set ``:replace`` to ``false``, however:
329
+
330
+ .. code:: ruby
331
+
332
+ player.upsert(replace: false)
333
+
334
+ p Player.find(existing.id)
335
+ # => <Player _id: 633b42f43282a45fadfaaf9d, name: "Juan Soto", age: 23, team: "SD">
336
+
337
+ This time, the value for the ``:age`` field is maintained.
338
+
339
+ .. note::
340
+
341
+ The default for the ``:replace`` option will be changed to ``false`` in
342
+ Mongoid 9.0, therefore it is recommended to explicitly specify this option
343
+ while using ``#upsert`` in 8.1 for easier upgradability.
0 commit comments