From bf573f412f46414cdf41ac88a52015ec71bc972c Mon Sep 17 00:00:00 2001 From: wakqasahmed Date: Sat, 5 Sep 2026 12:40:31 +0200 Subject: [PATCH] Skip empty-string selected values in lazy Select choice queries Select::lazy() field can end up with an empty string as its selected value (e.g. old('field') after a failed validation on a select left empty). ChoicePayload::selectedItems() ran whereIn() with that blank value anyway, which fails on strict-typed primary key columns like Postgres bigint. Filter out null/empty keys before querying, same as the earlier Matrix field fix in #3040. Fixes #3136. --- src/Screen/Fields/Support/ChoicePayload.php | 6 +++ .../Unit/Screen/Fields/ChoicePayloadTest.php | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/Unit/Screen/Fields/ChoicePayloadTest.php diff --git a/src/Screen/Fields/Support/ChoicePayload.php b/src/Screen/Fields/Support/ChoicePayload.php index a11e328cb..b9f4005d1 100644 --- a/src/Screen/Fields/Support/ChoicePayload.php +++ b/src/Screen/Fields/Support/ChoicePayload.php @@ -266,6 +266,12 @@ private static function normalizeScope(mixed $scope): ?array */ private function selectedItems(iterable $keys): iterable { + $keys = collect($keys)->filter(fn ($key): bool => $key !== null && $key !== '')->values(); + + if ($keys->isEmpty()) { + return []; + } + $query = $this->query(); return $query instanceof Builder diff --git a/tests/Unit/Screen/Fields/ChoicePayloadTest.php b/tests/Unit/Screen/Fields/ChoicePayloadTest.php new file mode 100644 index 000000000..ef479c9e0 --- /dev/null +++ b/tests/Unit/Screen/Fields/ChoicePayloadTest.php @@ -0,0 +1,42 @@ +selectedOptions(''); + + $this->assertSame([], $options); + $this->assertEmpty(DB::getQueryLog()); + + DB::disableQueryLog(); + } + + public function testSelectedOptionsIgnoresNullAmongSelectedValues(): void + { + $role = Role::factory()->create(); + + $payload = new ChoicePayload(model: Role::class, name: 'name', key: 'id'); + + $options = $payload->selectedOptions([$role->id, null, '']); + + $this->assertCount(1, $options); + $this->assertSame($role->id, $options[0]['id']); + } +}