Skip to content

Commit

Permalink
[9.x] Add whenCounted to JsonResource (#43101)
Browse files Browse the repository at this point in the history
* Add ability to conditionally include a relation's count

* Pass count into value callback and allow specifying count in relation name

* Add tests

* CS fix

* CS fix

* Remove `hasAttribute` method from `Model`

* Change comparison order to follow suit with other methods
  • Loading branch information
stevebauman authored Jul 14, 2022
1 parent a105ae5 commit 1b09251
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Http\Resources;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

trait ConditionallyLoadsAttributes
{
Expand Down Expand Up @@ -204,6 +205,37 @@ protected function whenLoaded($relationship, $value = null, $default = null)
return value($value);
}

/**
* Retrieve a relationship count if it exists.
*
* @param string $relationship
* @param mixed $value
* @param mixed $default
* @return \Illuminate\Http\Resources\MissingValue|mixed
*/
public function whenCounted($relationship, $value = null, $default = null)
{
if (func_num_args() < 3) {
$default = new MissingValue();
}

$attribute = Str::finish($relationship, '_count');

if (! isset($this->resource->getAttributes()[$attribute])) {
return value($default);
}

if (func_num_args() === 1) {
return $this->resource->{$attribute};
}

if ($this->resource->{$attribute} === null) {
return;
}

return value($value, $this->resource->{$attribute});
}

/**
* Execute a callback if the given pivot table has been loaded.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Illuminate\Tests\Integration\Http\Fixtures;

class PostResourceWithOptionalRelationshipCounts extends PostResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'authors' => $this->whenCounted('authors_count'),
'comments' => $this->whenCounted('comments', function ($count) {
return "$count comments";
}, 'None'),
];
}
}
54 changes: 54 additions & 0 deletions tests/Integration/Http/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalMerging;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalPivotRelationship;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationship;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalRelationshipCounts;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithoutWrap;
use Illuminate\Tests\Integration\Http\Fixtures\ReallyEmptyPostResource;
use Illuminate\Tests\Integration\Http\Fixtures\ResourceWithPreservedKeys;
Expand Down Expand Up @@ -283,6 +284,59 @@ public function testResourcesMayHaveOptionalRelationships()
]);
}

public function testResourcesMayHaveOptionalRelationshipCounts()
{
Route::get('/', function () {
$post = new Post([
'id' => 5,
'title' => 'Test Title',
]);

return new PostResourceWithOptionalRelationshipCounts($post);
});

$response = $this->withoutExceptionHandling()->get(
'/', ['Accept' => 'application/json']
);

$response->assertStatus(200);

$response->assertExactJson([
'data' => [
'id' => 5,
'comments' => 'None',
],
]);
}

public function testResourcesMayLoadOptionalRelationshipCounts()
{
Route::get('/', function () {
$post = new Post([
'id' => 5,
'title' => 'Test Title',
'authors_count' => 2,
'comments_count' => 5,
]);

return new PostResourceWithOptionalRelationshipCounts($post);
});

$response = $this->withoutExceptionHandling()->get(
'/', ['Accept' => 'application/json']
);

$response->assertStatus(200);

$response->assertExactJson([
'data' => [
'id' => 5,
'authors' => 2,
'comments' => '5 comments',
],
]);
}

public function testResourcesMayLoadOptionalRelationships()
{
Route::get('/', function () {
Expand Down

0 comments on commit 1b09251

Please sign in to comment.