Skip to content

Commit

Permalink
Unset _id: null to let it be autogenerated (#2969)
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN authored May 28, 2024
1 parent a017a0a commit 3f84373
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
## [4.4.0] - unreleased

* Support collection name prefix by @GromNaN in [#2930](https://github.com/mongodb/laravel-mongodb/pull/2930)
* Ignore `_id: null` to let MongoDB generate an `ObjectId` by @GromNaN in [#2969](https://github.com/mongodb/laravel-mongodb/pull/2969)
* Add `mongodb` driver for Batching by @GromNaN in [#2904](https://github.com/mongodb/laravel-mongodb/pull/2904)
* Rename queue option `table` to `collection`
* Replace queue option `expire` with `retry_after`
Expand Down
5 changes: 3 additions & 2 deletions src/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use function collect;
use function is_array;
use function iterator_to_array;
use function json_encode;

/** @method \MongoDB\Laravel\Query\Builder toBase() */
class Builder extends EloquentBuilder
Expand Down Expand Up @@ -210,8 +211,8 @@ public function raw($value = null)
*/
public function createOrFirst(array $attributes = [], array $values = []): Model
{
if ($attributes === []) {
throw new InvalidArgumentException('You must provide attributes to check for duplicates');
if ($attributes === [] || $attributes === ['_id' => null]) {
throw new InvalidArgumentException('You must provide attributes to check for duplicates. Got ' . json_encode($attributes));
}

// Apply casting and default values to the attributes
Expand Down
6 changes: 6 additions & 0 deletions src/Eloquent/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,12 @@ protected function isBSON(mixed $value): bool
*/
public function save(array $options = [])
{
// SQL databases would use autoincrement the id field if set to null.
// Apply the same behavior to MongoDB with _id only, otherwise null would be stored.
if (array_key_exists('_id', $this->attributes) && $this->attributes['_id'] === null) {
unset($this->attributes['_id']);
}

$saved = parent::save($options);

// Clear list of unset fields
Expand Down
17 changes: 17 additions & 0 deletions tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1151,4 +1151,21 @@ public function testUpdateOrCreate(array $criteria)
$this->assertEquals($createdAt, $checkUser->created_at->getTimestamp());
$this->assertEquals($updatedAt, $checkUser->updated_at->getTimestamp());
}

public function testCreateWithNullId()
{
$user = User::create(['_id' => null, 'email' => 'foo@bar']);
$this->assertNotNull(ObjectId::class, $user->id);
$this->assertSame(1, User::count());
}

public function testUpdateOrCreateWithNullId()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('You must provide attributes to check for duplicates');
User::updateOrCreate(
['_id' => null],
['email' => 'jane.doe@example.com'],
);
}
}

0 comments on commit 3f84373

Please sign in to comment.