From 540ddcaf56d9e0636135a1d8948e34535a54aec6 Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Mon, 12 Oct 2026 15:43:18 +0800 Subject: [PATCH 1/2] fix(comments): publish unguards only for its own insert, so a failed insert no longer leaves every model unguarded in a long-lived worker --- src/Models/Comment.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Models/Comment.php b/src/Models/Comment.php index c04ede11..f6f9c333 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -119,8 +119,6 @@ public function replies() */ public static function publish(array $attributes): Comment { - static::unguard(); - // If replies or parent is set somehow unset it unset($attributes['replies'], $attributes['parent']); @@ -139,9 +137,10 @@ public static function publish(array $attributes): Comment $attributes['created_at'] = now(); $attributes['updated_at'] = now(); - $comment = static::create($attributes); - static::reguard(); - - return $comment; + // Unguard only for this insert: `unguarded()` restores the guard even when the insert + // throws. A bare unguard() left every model in a long-lived (Octane) worker unguarded + // after a failed insert, so request params became where clauses and stray payload keys + // became insert columns on unrelated models. + return static::unguarded(fn () => static::create($attributes)); } } From f3fe0b13094360087d8bc01ea669ffe70770ab3c Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Mon, 12 Oct 2026 17:00:37 +0800 Subject: [PATCH 2/2] test(comments): a failed publish leaves models guarded --- tests/Unit/Models/OperationalModelsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Unit/Models/OperationalModelsTest.php b/tests/Unit/Models/OperationalModelsTest.php index 4978d81d..af164fe8 100644 --- a/tests/Unit/Models/OperationalModelsTest.php +++ b/tests/Unit/Models/OperationalModelsTest.php @@ -636,6 +636,21 @@ public function clear(): bool Carbon::setTestNow(); }); +it('leaves models guarded when publishing a comment fails', function () { + operational_models_database(); + session([ + 'user' => 'user-1', + 'company' => 'company-1', + ]); + + // A duplicate primary key makes the insert throw. + Comment::publish(['uuid' => 'comment-dup', 'content' => 'First', 'subject_uuid' => 'order-1', 'subject_type' => User::class]); + + expect(fn () => Comment::publish(['uuid' => 'comment-dup', 'content' => 'Second', 'subject_uuid' => 'order-1', 'subject_type' => User::class])) + ->toThrow(Exception::class) + ->and(Comment::isUnguarded())->toBeFalse(); +}); + it('defines comment company parent and replies relationship contracts', function () { operational_models_database();