From 9b2842b41a15cae90d82ed7baeb1a37a5ce2b18b Mon Sep 17 00:00:00 2001 From: hn-seoai Date: Wed, 8 May 2024 13:23:33 +0200 Subject: [PATCH] Support passing default as named parameter in whenLoaded, whenAggregated, whenCounted --- .../ConditionallyLoadsAttributes.php | 12 +++++ ...tionalRelationshipUsingNamedParameters.php | 16 ++++++ tests/Integration/Http/ResourceTest.php | 49 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipUsingNamedParameters.php diff --git a/src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php b/src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php index 252fa8ba4e59..26046b9c565a 100644 --- a/src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php +++ b/src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php @@ -276,6 +276,10 @@ protected function whenLoaded($relationship, $value = null, $default = null) return; } + if ($value === null) { + $value = value(...); + } + return value($value, $loadedValue); } @@ -307,6 +311,10 @@ public function whenCounted($relationship, $value = null, $default = null) return; } + if ($value === null) { + $value = value(...); + } + return value($value, $this->resource->{$attribute}); } @@ -340,6 +348,10 @@ public function whenAggregated($relationship, $column, $aggregate, $value = null return; } + if ($value === null) { + $value = value(...); + } + return value($value, $this->resource->{$attribute}); } diff --git a/tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipUsingNamedParameters.php b/tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipUsingNamedParameters.php new file mode 100644 index 000000000000..8b2a4ba30c03 --- /dev/null +++ b/tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipUsingNamedParameters.php @@ -0,0 +1,16 @@ + $this->id, + 'author' => new AuthorResource($this->whenLoaded('author')), + 'author_defaulting_to_null' => new AuthorResource($this->whenLoaded('author', default: null)), + 'author_name' => $this->whenLoaded('author', fn ($author) => $author->name, 'Anonymous'), + ]; + } +} diff --git a/tests/Integration/Http/ResourceTest.php b/tests/Integration/Http/ResourceTest.php index 56cee847887c..35d7a9b01f17 100644 --- a/tests/Integration/Http/ResourceTest.php +++ b/tests/Integration/Http/ResourceTest.php @@ -37,6 +37,7 @@ use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationship; use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationshipAggregates; use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationshipCounts; +use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationshipUsingNamedParameters; use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithoutWrap; use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithUnlessOptionalData; use Illuminate\Tests\Integration\Http\Fixtures\ReallyEmptyPostResource; @@ -610,6 +611,54 @@ public function testResourceDoesNotThrowErrorWhenUsingEloquentStrictModeAndCheck ]); } + public function testWhenLoadedUsingNamedDefaultParameterOnMissingRelation() + { + Route::get('/', function () { + $post = new Post(['id' => 1]); + + return new PostResourceWithOptionalRelationshipUsingNamedParameters($post); + }); + + $response = $this->withoutExceptionHandling()->get( + '/', ['Accept' => 'application/json'] + ); + + $response->assertStatus(200); + + $response->assertExactJson([ + 'data' => [ + 'id' => 1, + 'author_defaulting_to_null' => null, + 'author_name' => 'Anonymous', + ], + ]); + } + + public function testWhenLoadedUsingNamedDefaultParameterOnLoadedRelation() + { + Route::get('/', function () { + $post = new Post(['id' => 1]); + $post->setRelation('author', new Author(['name' => 'jrrmartin'])); + + return new PostResourceWithOptionalRelationshipUsingNamedParameters($post); + }); + + $response = $this->withoutExceptionHandling()->get( + '/', ['Accept' => 'application/json'] + ); + + $response->assertStatus(200); + + $response->assertExactJson([ + 'data' => [ + 'id' => 1, + 'author' => ['name' => 'jrrmartin'], + 'author_defaulting_to_null' => ['name' => 'jrrmartin'], + 'author_name' => 'jrrmartin', + ], + ]); + } + public function testResourcesMayHaveOptionalPivotRelationshipsWithCustomAccessor() { Route::get('/', function () {