Skip to content

Commit 89568c7

Browse files
committed
wip
1 parent 5095c3d commit 89568c7

File tree

2 files changed

+97
-10
lines changed

2 files changed

+97
-10
lines changed

src/Illuminate/Database/Eloquent/Builder.php

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ class Builder implements BuilderContract
6060
*/
6161
public $pendingAttributes = [];
6262

63+
/**
64+
* Indicates if attributes, timestamps, and unique IDs should be merged before insert.
65+
*
66+
* @var bool
67+
*/
68+
public $mergeAttributesBeforeInsert = false;
69+
6370
/**
6471
* The relationships that should be eager loaded.
6572
*
@@ -136,6 +143,19 @@ class Builder implements BuilderContract
136143
'torawsql',
137144
];
138145

146+
/**
147+
* The pass-thru methods that can have attributes merged before insert.
148+
*
149+
* @var string[]
150+
*/
151+
protected $mergeBeforeInsertPassThru = [
152+
'insert',
153+
'insertgetid',
154+
'insertorignore',
155+
'insertusing',
156+
'insertorignoreusing',
157+
];
158+
139159
/**
140160
* Applied global scopes.
141161
*
@@ -588,17 +608,47 @@ public function findOr($id, $columns = ['*'], ?Closure $callback = null)
588608
return $callback();
589609
}
590610

611+
/*
612+
* 'insert',
613+
'insertgetid',
614+
'insertorignore',
615+
'insertusing',
616+
'insertorignoreusing',
617+
*/
618+
public function insert(array $values)
619+
{
620+
if ($this->mergeAttributesBeforeInsert) {
621+
$values = $this->castBeforeInsert($values);
622+
}
623+
624+
return $this->forwardCallTo($this->query, 'insert', [$values]);
625+
}
626+
627+
/**
628+
* @param array $values
629+
* @param $sequence
630+
* @return int|mixed
631+
*/
632+
public function insertGetId(array $values, $sequence = null)
633+
{
634+
if ($this->mergeAttributesBeforeInsert) {
635+
$values = $this->castBeforeInsert([$values])[0];
636+
}
637+
638+
return $this->forwardCallTo($this->query, 'insertGetId', [$values, $sequence]);
639+
}
640+
591641
/**
592642
* Insert a number of records, merging in default attributes,
593643
* adding timestamps, and converting casts to raw values.
594644
*
595645
* @param list<array<string, mixed>> $values
596-
* @return bool
646+
* @return array
597647
*/
598-
public function insertWithCasts($values)
648+
public function castBeforeInsert($values)
599649
{
600650
if (empty($values)) {
601-
return true;
651+
[];
602652
}
603653

604654
if (! is_array(reset($values))) {
@@ -629,7 +679,7 @@ public function insertWithCasts($values)
629679
}
630680
});
631681

632-
return $this->toBase()->insert($values);
682+
return $values;
633683
}
634684

635685
/**
@@ -1880,6 +1930,20 @@ public function withAttributes(Expression|array|string $attributes, $value = nul
18801930
return $this;
18811931
}
18821932

1933+
/**
1934+
* Indicate if insert methods should merge in default attributes,
1935+
* add timestamps, and converting casts to raw values.
1936+
*
1937+
* @param bool $merge
1938+
* @return $this|Builder
1939+
*/
1940+
public function mergeAttributesBeforeInsert($merge = true)
1941+
{
1942+
$this->mergeAttributesBeforeInsert = $merge;
1943+
1944+
return $this;
1945+
}
1946+
18831947
/**
18841948
* Apply query-time casts to the model instance.
18851949
*
@@ -2180,7 +2244,10 @@ public function __call($method, $parameters)
21802244
return $this->callNamedScope($method, $parameters);
21812245
}
21822246

2183-
if (in_array(strtolower($method), $this->passthru)) {
2247+
if (in_array($lowerCaseMethod = strtolower($method), $this->passthru)) {
2248+
if ($this->mergeAttributesBeforeInsert && in_array($lowerCaseMethod, $this->mergeBeforeInsertPassThru)) {
2249+
$parameters[0] = $this->castBeforeInsert($parameters[0])[0];
2250+
}
21842251
return $this->toBase()->{$method}(...$parameters);
21852252
}
21862253

tests/Database/DatabaseEloquentIntegrationTest.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ protected function createSchema()
8383
$table->timestamps();
8484
});
8585

86-
$this->schema()->create('users_with_uuid', function (Blueprint $table) {
86+
$this->schema()->create('users_having_uuids', function (Blueprint $table) {
8787
$table->id();
8888
$table->uuid();
8989
$table->string('name');
@@ -2477,7 +2477,7 @@ public function testCanInsertWithCasts()
24772477
DB::enableQueryLog();
24782478
Carbon::setTestNow('2025-03-15T07:32:00Z');
24792479

2480-
$this->assertTrue(EloquentTestUser::insertWithCasts([
2480+
$this->assertTrue(EloquentTestUser::mergeAttributesBeforeInsert()->insert([
24812481
['email' => '[email protected]', 'birthday' => null],
24822482
['email' => '[email protected]', 'birthday' => new Carbon('1980-01-01')],
24832483
['email' => '[email protected]', 'birthday' => '1987-11-01', 'created_at' => '2025-01-02T02:00:55', 'updated_at' => Carbon::parse('2025-02-19T11:41:13')],
@@ -2503,7 +2503,7 @@ public function testCanInsertWithCasts()
25032503

25042504
DB::flushQueryLog();
25052505

2506-
$this->assertTrue(EloquentTestWithJSON::insertWithCasts([
2506+
$this->assertTrue(EloquentTestWithJSON::mergeAttributesBeforeInsert()->insert([
25072507
['id' => 1, 'json' => ['album' => 'Keep It Like a Secret', 'release_date' => '1999-02-02']],
25082508
['id' => 2, 'json' => (object) ['album' => 'You In Reverse', 'release_date' => '2006-04-11']],
25092509
]));
@@ -2526,7 +2526,7 @@ public function testCanInsertWithCastsWithUniqueStringIds()
25262526
'22222222-0000-7000-0000-000000000000',
25272527
]);
25282528

2529-
$this->assertTrue(ModelWithUniqueStringIds::insertWithCasts([
2529+
$this->assertTrue(ModelWithUniqueStringIds::mergeAttributesBeforeInsert()->insert([
25302530
[
25312531
'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin,
25322532
],
@@ -2565,6 +2565,26 @@ public function testCanInsertWithCastsWithUniqueStringIds()
25652565
$this->assertSame('22222222-0000-7000-0000-000000000000', $chris->uuid);
25662566
}
25672567

2568+
public function testMergeBeforeInsertGetId()
2569+
{
2570+
Str::createUuidsUsingSequence([
2571+
'00000000-0000-7000-0000-000000000000',
2572+
]);
2573+
2574+
DB::enableQueryLog();
2575+
try {
2576+
$this->assertSame(1, ModelWithUniqueStringIds::mergeAttributesBeforeInsert()->insertGetId([
2577+
'name' => 'Taylor',
2578+
'role' => IntBackedRole::Admin,
2579+
'role_string' => StringBackedRole::Admin,
2580+
]));
2581+
} catch (\Throwable $t) {
2582+
dd($t);
2583+
echo "error";
2584+
}
2585+
//dd(DB::getRawQueryLog());
2586+
}
2587+
25682588
/**
25692589
* Helpers...
25702590
*/
@@ -2897,7 +2917,7 @@ class ModelWithUniqueStringIds extends Eloquent
28972917

28982918
public $timestamps = false;
28992919

2900-
protected $table = 'users_with_uuid';
2920+
protected $table = 'users_having_uuids';
29012921

29022922
protected function casts()
29032923
{

0 commit comments

Comments
 (0)