From 2557e9c38fe65c4ee8f4f1d3e103b69c08a9a371 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 16 Apr 2025 16:53:52 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"[12.x]=20Fix=20pivot=20model=20events?= =?UTF-8?q?=20not=20working=20when=20using=20the=20`withPivotVa=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 99e1ceb6044db988b904f2940d9510299cbe9d1d. --- .../Concerns/InteractsWithPivotTable.php | 72 ++++++++----------- .../Database/EloquentPivotEventsTest.php | 35 --------- 2 files changed, 28 insertions(+), 79 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php index 454d79379195..015554ed767a 100644 --- a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php +++ b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php @@ -207,7 +207,10 @@ protected function attachNew(array $records, array $current, $touch = true) */ public function updateExistingPivot($id, array $attributes, $touch = true) { - if ($this->using) { + if ($this->using && + empty($this->pivotWheres) && + empty($this->pivotWhereIns) && + empty($this->pivotWhereNulls)) { return $this->updateExistingPivotUsingCustomClass($id, $attributes, $touch); } @@ -215,7 +218,7 @@ public function updateExistingPivot($id, array $attributes, $touch = true) $attributes = $this->addTimestampsToAttachment($attributes, true); } - $updated = $this->newPivotStatementForId($id)->update( + $updated = $this->newPivotStatementForId($this->parseId($id))->update( $this->castAttributes($attributes) ); @@ -236,7 +239,10 @@ public function updateExistingPivot($id, array $attributes, $touch = true) */ protected function updateExistingPivotUsingCustomClass($id, array $attributes, $touch) { - $pivot = $this->getCurrentlyAttachedPivotsForIds($id)->first(); + $pivot = $this->getCurrentlyAttachedPivots() + ->where($this->foreignPivotKey, $this->parent->{$this->parentKey}) + ->where($this->relatedPivotKey, $this->parseId($id)) + ->first(); $updated = $pivot ? $pivot->fill($attributes)->isDirty() : false; @@ -429,7 +435,11 @@ public function hasPivotColumn($column) */ public function detach($ids = null, $touch = true) { - if ($this->using) { + if ($this->using && + ! empty($ids) && + empty($this->pivotWheres) && + empty($this->pivotWhereIns) && + empty($this->pivotWhereNulls)) { $results = $this->detachUsingCustomClass($ids); } else { $query = $this->newPivotQuery(); @@ -470,21 +480,11 @@ protected function detachUsingCustomClass($ids) { $results = 0; - if (! empty($this->pivotWheres) || - ! empty($this->pivotWhereIns) || - ! empty($this->pivotWhereNulls)) { - $records = $this->getCurrentlyAttachedPivotsForIds($ids); - - foreach ($records as $record) { - $results += $record->delete(); - } - } else { - foreach ($this->parseIds($ids) as $id) { - $results += $this->newPivot([ - $this->foreignPivotKey => $this->parent->{$this->parentKey}, - $this->relatedPivotKey => $id, - ], true)->delete(); - } + foreach ($this->parseIds($ids) as $id) { + $results += $this->newPivot([ + $this->foreignPivotKey => $this->parent->{$this->parentKey}, + $this->relatedPivotKey => $id, + ], true)->delete(); } return $results; @@ -497,31 +497,15 @@ protected function detachUsingCustomClass($ids) */ protected function getCurrentlyAttachedPivots() { - return $this->getCurrentlyAttachedPivotsForIds(); - } + return $this->newPivotQuery()->get()->map(function ($record) { + $class = $this->using ?: Pivot::class; - /** - * Get the pivot models that are currently attached, filtered by related model keys. - * - * @param mixed $ids - * @return \Illuminate\Support\Collection - */ - protected function getCurrentlyAttachedPivotsForIds($ids = null) - { - return $this->newPivotQuery() - ->when(! is_null($ids), fn ($query) => $query->whereIn( - $this->getQualifiedRelatedPivotKeyName(), $this->parseIds($ids) - )) - ->get() - ->map(function ($record) { - $class = $this->using ?: Pivot::class; - - $pivot = $class::fromRawAttributes($this->parent, (array) $record, $this->getTable(), true); - - return $pivot - ->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey) - ->setRelatedModel($this->related); - }); + $pivot = $class::fromRawAttributes($this->parent, (array) $record, $this->getTable(), true); + + return $pivot + ->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey) + ->setRelatedModel($this->related); + }); } /** @@ -573,7 +557,7 @@ public function newPivotStatement() */ public function newPivotStatementForId($id) { - return $this->newPivotQuery()->whereIn($this->getQualifiedRelatedPivotKeyName(), $this->parseIds($id)); + return $this->newPivotQuery()->whereIn($this->relatedPivotKey, $this->parseIds($id)); } /** diff --git a/tests/Integration/Database/EloquentPivotEventsTest.php b/tests/Integration/Database/EloquentPivotEventsTest.php index e94fe5cce005..7a9962982595 100644 --- a/tests/Integration/Database/EloquentPivotEventsTest.php +++ b/tests/Integration/Database/EloquentPivotEventsTest.php @@ -74,34 +74,6 @@ public function testPivotWillTriggerEventsToBeFired() $this->assertEquals(['deleting', 'deleted'], PivotEventsTestCollaborator::$eventsCalled); } - public function testPivotWithPivotValueWillTriggerEventsToBeFired() - { - $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']); - $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']); - $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']); - - $project->managers()->attach($user); - $this->assertEquals(['saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled); - $project->managers()->attach($user2); - - PivotEventsTestCollaborator::$eventsCalled = []; - $project->managers()->updateExistingPivot($user->id, ['permissions' => ['foo', 'bar']]); - $this->assertEquals(['saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled); - $project->managers()->detach($user2); - - PivotEventsTestCollaborator::$eventsCalled = []; - $project->managers()->sync([$user2->id]); - $this->assertEquals(['deleting', 'deleted', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled); - - PivotEventsTestCollaborator::$eventsCalled = []; - $project->managers()->sync([$user->id => ['permissions' => ['foo']], $user2->id => ['permissions' => ['bar']]]); - $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled); - - PivotEventsTestCollaborator::$eventsCalled = []; - $project->managers()->detach($user); - $this->assertEquals(['deleting', 'deleted'], PivotEventsTestCollaborator::$eventsCalled); - } - public function testPivotWithPivotCriteriaTriggerEventsToBeFiredOnCreateUpdateNoneOnDetach() { $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']); @@ -220,13 +192,6 @@ public function contributors() ->wherePivot('role', 'contributor'); } - public function managers() - { - return $this->belongsToMany(PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id') - ->using(PivotEventsTestCollaborator::class) - ->withPivotValue('role', 'manager'); - } - public function equipments() { return $this->morphToMany(PivotEventsTestEquipment::class, 'equipmentable')->using(PivotEventsTestModelEquipment::class);