Skip to content

Commit 60e28ae

Browse files
authored
MONGOID-5363 Change #upsert to perform updating upsert rather than replacing upsert (#5492)
* MONGOID-5363 add :replace option to upsert method * MONGOID-5363 add docs, release notes for 8.1/9.0
1 parent c16e3dd commit 60e28ae

File tree

4 files changed

+64
-5
lines changed

4 files changed

+64
-5
lines changed

source/reference/crud.txt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ operations with examples.
5151
has been retrieved from the database, and a* ``Hash`` *with string keys
5252
if it is a new document.*
5353

54-
*The attributes hash also contains the attributes of all embedded
55-
documents, as well as their embedded documents, etc. If an embedded
54+
*The attributes hash also contains the attributes of all embedded
55+
documents, as well as their embedded documents, etc. If an embedded
5656
association is empty, its key will not show up in the returned hash.*
5757

5858
-
@@ -224,9 +224,12 @@ operations with examples.
224224
* - ``Model#upsert``
225225

226226
*Performs a MongoDB replace with upsert on the document. If the document
227-
exists in the database, it will get overwritten with the current
228-
document in the application (any attributes present in the database but
229-
not in the application's document instance will be lost).
227+
exists in the database and the* ``:replace`` *option is set to true, it
228+
will get overwritten with the current document in the application (any
229+
attributes present in the database but not in the application's document
230+
instance will be lost). If the* ``:replace`` *option is false (default),
231+
the document will be updated, and any attributes not in the application's
232+
document will be maintained.
230233
If the document does not exist in the database, it will be inserted.
231234
Note that this only runs the* ``{before|after|around}_upsert`` *callbacks.*
232235
-
@@ -237,6 +240,7 @@ operations with examples.
237240
last_name: "Heine"
238241
)
239242
person.upsert
243+
person.upsert(replace: true)
240244

241245
* - ``Model#touch``
242246

source/release-notes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Release Notes
99
.. toctree::
1010
:titlesonly:
1111

12+
release-notes/mongoid-9.0
1213
release-notes/mongoid-8.1
1314
release-notes/mongoid-8.0
1415
release-notes/mongoid-7.5

source/release-notes/mongoid-8.1.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,44 @@ An _id, a hash of conditions, or ``false``/``nil`` can now be included:
300300
Band.exists?(BSON::ObjectId('6320d96a3282a48cfce9e72c'))
301301
Band.exists?(false) # always false
302302
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.

source/release-notes/mongoid-9.0.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,16 @@ the type conversion.
7373
Note that in prior Mongoid versions, typecasting Date to Time during
7474
persistence operations was already correctly using the
7575
``Mongoid.use_activesupport_time_zone`` setting.
76+
77+
78+
Flipped default for ``:replace`` option in ``#upsert``
79+
------------------------------------------------------
80+
81+
Mongoid 8.1 added the ``:replace`` option to the ``#upsert`` method. This
82+
option was used to specify whether or not the existing document should be
83+
updated or replaced.
84+
85+
Mongoid 9.0 flips the default of this flag from ``true`` => ``false``.
86+
87+
This means that, by default, Mongoid 9 will update the existing document and
88+
will not replace it.

0 commit comments

Comments
 (0)