Skip to content

Commit cf01407

Browse files
authored
Merge pull request #120 from phenixphp/bugfix/save-model-with-string-id
Improve saving models
2 parents 516463c + c7c2dc6 commit cf01407

3 files changed

Lines changed: 67 additions & 12 deletions

File tree

src/Database/Models/DatabaseModel.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,17 @@ public function save(TransactionManager|null $transactionManager = null): bool
177177
$result = $queryBuilder
178178
->insertGetId($data, $this->getModelKeyColumnName());
179179

180-
if ($result) {
181-
if (! $this->keyIsInitialized()) {
182-
$this->{$this->getModelKeyName()} = $result;
183-
}
184-
185-
$this->setAsExisting();
180+
if ($result === false) {
181+
return false;
182+
}
186183

187-
return true;
184+
if (! $this->keyIsInitialized() && $result !== null) {
185+
$this->{$this->getModelKeyName()} = $result;
188186
}
189187

190-
return false;
188+
$this->setAsExisting();
189+
190+
return true;
191191
}
192192

193193
public function delete(TransactionManager|null $transactionManager = null): bool

src/Database/Models/QueryBuilders/DatabaseQueryBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,12 @@ public function create(array $attributes): DatabaseModel
204204

205205
$queryBuilder = clone $this;
206206
$queryBuilder->setModel($model);
207+
$modelKeyName = $model->getModelKeyName();
208+
$keyWasInitialized = isset($model->{$modelKeyName});
207209
$result = $queryBuilder->insertGetId($data, $model->getModelKeyColumnName());
208210

209-
if ($result) {
210-
$modelKeyName = $model->getModelKeyName();
211-
212-
if (! isset($model->{$modelKeyName})) {
211+
if ($result !== false && ($keyWasInitialized || $result !== null)) {
212+
if (! $keyWasInitialized) {
213213
$model->{$modelKeyName} = $result;
214214
}
215215

tests/Feature/Database/DatabaseModelTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,34 @@
783783
expect($model->createdAt)->toBeInstanceOf(Date::class);
784784
});
785785

786+
it('creates model with manually assigned string ID when insertGetId returns zero', function () {
787+
$insertResult = new Result([['Query OK']]);
788+
$insertResult->setLastInsertedId(0);
789+
790+
$connection = $this->getMockBuilder(MysqlConnectionPool::class)->getMock();
791+
792+
$connection->expects($this->exactly(1))
793+
->method('prepare')
794+
->willReturnOnConsecutiveCalls(
795+
new Statement($insertResult),
796+
);
797+
798+
$this->app->swap(Connection::default(), $connection);
799+
800+
$uuid = Str::uuid()->toString();
801+
802+
$model = UserWithUuid::create([
803+
'id' => $uuid,
804+
'name' => 'John Doe',
805+
'email' => faker()->email(),
806+
'created_at' => Date::now(),
807+
]);
808+
809+
expect($model->isExisting())->toBeTrue();
810+
expect($model->id)->toBe($uuid);
811+
expect($model->createdAt)->toBeInstanceOf(Date::class);
812+
});
813+
786814
it('throws an exception when column in invalid on create instance', function () {
787815
expect(function () {
788816
$connection = $this->getMockBuilder(MysqlConnectionPool::class)->getMock();
@@ -895,6 +923,33 @@
895923
expect($model->createdAt)->toBeInstanceOf(Date::class);
896924
});
897925

926+
it('saves a new model with manually assigned string ID when insertGetId returns zero', function () {
927+
$insertResult = new Result([['Query OK']]);
928+
$insertResult->setLastInsertedId(0);
929+
930+
$connection = $this->getMockBuilder(MysqlConnectionPool::class)->getMock();
931+
932+
$connection->expects($this->exactly(1))
933+
->method('prepare')
934+
->willReturnOnConsecutiveCalls(
935+
new Statement($insertResult),
936+
);
937+
938+
$this->app->swap(Connection::default(), $connection);
939+
940+
$uuid = Str::uuid()->toString();
941+
$model = new UserWithUuid();
942+
$model->id = $uuid;
943+
$model->name = 'John Doe';
944+
$model->email = faker()->email();
945+
946+
expect($model->isExisting())->toBeFalse();
947+
expect($model->save())->toBeTrue();
948+
expect($model->isExisting())->toBeTrue();
949+
expect($model->id)->toBe($uuid);
950+
expect($model->createdAt)->toBeInstanceOf(Date::class);
951+
});
952+
898953
it('updates an existing model with string ID correctly', function () {
899954
$uuid = Str::uuid()->toString();
900955
$data = [

0 commit comments

Comments
 (0)