Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9b29d25

Browse filesBrowse files
Merge 4.7 into 4.8 (#3096)
2 parents 497a074 + 1bb6edd commit 9b29d25
Copy full SHA for 9b29d25

File tree

Expand file treeCollapse file tree

6 files changed

+271
-81
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+271
-81
lines changed

‎docs/feature-compatibility.txt

Copy file name to clipboardExpand all lines: docs/feature-compatibility.txt
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ The following Eloquent methods are not supported in {+odm-short+}:
151151
- *Unsupported as MongoDB uses ObjectIDs*
152152

153153
* - Upserts
154-
- *Unsupported*
154+
- ✓ See :ref:`laravel-mongodb-query-builder-upsert`.
155155

156156
* - Update Statements
157157
- ✓
@@ -216,7 +216,7 @@ Eloquent Features
216216
- ✓
217217

218218
* - Upserts
219-
- *Unsupported, but you can use the createOneOrFirst() method*
219+
- ✓ See :ref:`laravel-modify-documents-upsert`.
220220

221221
* - Deleting Models
222222
- ✓

‎docs/fundamentals/write-operations.txt

Copy file name to clipboardExpand all lines: docs/fundamentals/write-operations.txt
+86-4Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,88 @@ An **upsert** operation lets you perform an update or insert in a single
258258
operation. This operation streamlines the task of updating a document or
259259
inserting one if it does not exist.
260260

261+
Starting in v4.7, you can perform an upsert operation by using either of
262+
the following methods:
263+
264+
- ``upsert()``: When you use this method, you can perform a **batch
265+
upsert** to change or insert multiple documents in one operation.
266+
267+
- ``update()``: When you use this method, you must specify the
268+
``upsert`` option to update all documents that match the query filter
269+
or insert one document if no documents are matched. Only this upsert method
270+
is supported in versions v4.6 and earlier.
271+
272+
Upsert Method
273+
~~~~~~~~~~~~~
274+
275+
The ``upsert(array $values, array|string $uniqueBy, array|null
276+
$update)`` method accepts the following parameters:
277+
278+
- ``$values``: Array of fields and values that specify documents to update or insert.
279+
- ``$uniqueBy``: List of fields that uniquely identify documents in your
280+
first array parameter.
281+
- ``$update``: Optional list of fields to update if a matching document
282+
exists. If you omit this parameter, {+odm-short+} updates all fields.
283+
284+
To specify an upsert in the ``upsert()`` method, set parameters
285+
as shown in the following code example:
286+
287+
.. code-block:: php
288+
:copyable: false
289+
290+
YourModel::upsert(
291+
[/* documents to update or insert */],
292+
'/* unique field */',
293+
[/* fields to update */],
294+
);
295+
296+
Example
297+
^^^^^^^
298+
299+
This example shows how to use the ``upsert()``
300+
method to perform an update or insert in a single operation. Click the
301+
:guilabel:`{+code-output-label+}` button to see the resulting data changes when
302+
there is a document in which the value of ``performer`` is ``'Angel
303+
Olsen'`` in the collection already:
304+
305+
.. io-code-block::
306+
307+
.. input:: /includes/fundamentals/write-operations/WriteOperationsTest.php
308+
:language: php
309+
:dedent:
310+
:start-after: begin model upsert
311+
:end-before: end model upsert
312+
313+
.. output::
314+
:language: json
315+
:visible: false
316+
317+
{
318+
"_id": "...",
319+
"performer": "Angel Olsen",
320+
"venue": "State Theatre",
321+
"genres": [
322+
"indie",
323+
"rock"
324+
],
325+
"ticketsSold": 275,
326+
"updated_at": ...
327+
},
328+
{
329+
"_id": "...",
330+
"performer": "Darondo",
331+
"venue": "Cafe du Nord",
332+
"ticketsSold": 300,
333+
"updated_at": ...
334+
}
335+
336+
In the document in which the value of ``performer`` is ``'Angel
337+
Olsen'``, the ``venue`` field value is not updated, as the upsert
338+
specifies that the update applies only to the ``ticketsSold`` field.
339+
340+
Update Method
341+
~~~~~~~~~~~~~
342+
261343
To specify an upsert in an ``update()`` method, set the ``upsert`` option to
262344
``true`` as shown in the following code example:
263345

@@ -278,8 +360,8 @@ following actions:
278360
- If the query matches zero documents, the ``update()`` method inserts a
279361
document that contains the update data and the equality match criteria data.
280362

281-
Upsert Example
282-
~~~~~~~~~~~~~~
363+
Example
364+
^^^^^^^
283365

284366
This example shows how to pass the ``upsert`` option to the ``update()``
285367
method to perform an update or insert in a single operation. Click the
@@ -291,8 +373,8 @@ matching documents exist:
291373
.. input:: /includes/fundamentals/write-operations/WriteOperationsTest.php
292374
:language: php
293375
:dedent:
294-
:start-after: begin model upsert
295-
:end-before: end model upsert
376+
:start-after: begin model update upsert
377+
:end-before: end model update upsert
296378

297379
.. output::
298380
:language: json

‎docs/includes/fundamentals/write-operations/WriteOperationsTest.php

Copy file name to clipboardExpand all lines: docs/includes/fundamentals/write-operations/WriteOperationsTest.php
+36-3Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,55 @@ public function testModelUpdateMultiple(): void
217217
}
218218
}
219219

220+
/**
221+
* @runInSeparateProcess
222+
* @preserveGlobalState disabled
223+
*/
224+
public function testModelUpsert(): void
225+
{
226+
require_once __DIR__ . '/Concert.php';
227+
Concert::truncate();
228+
229+
// Pre-existing sample document
230+
Concert::create([
231+
'performer' => 'Angel Olsen',
232+
'venue' => 'State Theatre',
233+
'genres' => [ 'indie', 'rock' ],
234+
'ticketsSold' => 150,
235+
]);
236+
237+
// begin model upsert
238+
Concert::upsert([
239+
['performer' => 'Angel Olsen', 'venue' => 'Academy of Music', 'ticketsSold' => 275],
240+
['performer' => 'Darondo', 'venue' => 'Cafe du Nord', 'ticketsSold' => 300],
241+
], 'performer', ['ticketsSold']);
242+
// end model upsert
243+
244+
$this->assertSame(2, Concert::count());
245+
246+
$this->assertSame(275, Concert::where('performer', 'Angel Olsen')->first()->ticketsSold);
247+
$this->assertSame('State Theatre', Concert::where('performer', 'Angel Olsen')->first()->venue);
248+
249+
$this->assertSame(300, Concert::where('performer', 'Darondo')->first()->ticketsSold);
250+
$this->assertSame('Cafe du Nord', Concert::where('performer', 'Darondo')->first()->venue);
251+
}
252+
220253
/**
221254
* @runInSeparateProcess
222255
* @preserveGlobalState disabled
223256
*/
224-
public function testModelUpsert(): void
257+
public function testModelUpdateUpsert(): void
225258
{
226259
require_once __DIR__ . '/Concert.php';
227260
Concert::truncate();
228261

229-
// begin model upsert
262+
// begin model update upsert
230263
Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall'])
231264
->update(
232265
['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000],
233266
['upsert' => true],
234267
);
235-
// end model upsert
268+
// end model update upsert
236269

237270
$result = Concert::first();
238271

‎docs/includes/query-builder/QueryBuilderTest.php

Copy file name to clipboardExpand all lines: docs/includes/query-builder/QueryBuilderTest.php
+24-1Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,29 @@ function (Collection $collection) {
506506
public function testUpsert(): void
507507
{
508508
// begin upsert
509+
$result = DB::table('movies')
510+
->upsert(
511+
[
512+
['title' => 'Inspector Maigret', 'recommended' => false, 'runtime' => 128],
513+
['title' => 'Petit Maman', 'recommended' => true, 'runtime' => 72],
514+
],
515+
'title',
516+
'recommended',
517+
);
518+
// end upsert
519+
520+
$this->assertSame(2, $result);
521+
522+
$this->assertSame(119, DB::table('movies')->where('title', 'Inspector Maigret')->first()['runtime']);
523+
$this->assertSame(false, DB::table('movies')->where('title', 'Inspector Maigret')->first()['recommended']);
524+
525+
$this->assertSame(true, DB::table('movies')->where('title', 'Petit Maman')->first()['recommended']);
526+
$this->assertSame(72, DB::table('movies')->where('title', 'Petit Maman')->first()['runtime']);
527+
}
528+
529+
public function testUpdateUpsert(): void
530+
{
531+
// begin update upsert
509532
$result = DB::table('movies')
510533
->where('title', 'Will Hunting')
511534
->update(
@@ -516,7 +539,7 @@ public function testUpsert(): void
516539
],
517540
['upsert' => true],
518541
);
519-
// end upsert
542+
// end update upsert
520543

521544
$this->assertIsInt($result);
522545
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.