Skip to content

Commit b720570

Browse files
committed
Unset relation when null (singular) or empty array (plural)
Closes: #66
1 parent de431b5 commit b720570

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/ItemHydrator.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Illuminate\Support\Str;
77
use Swis\JsonApi\Client\Exceptions\HydrationException;
88
use Swis\JsonApi\Client\Interfaces\ItemInterface;
9+
use Swis\JsonApi\Client\Interfaces\ManyRelationInterface;
10+
use Swis\JsonApi\Client\Interfaces\OneRelationInterface;
911
use Swis\JsonApi\Client\Interfaces\TypeMapperInterface;
1012
use Swis\JsonApi\Client\Relations\HasManyRelation;
1113
use Swis\JsonApi\Client\Relations\HasOneRelation;
@@ -76,6 +78,16 @@ protected function fillRelations(ItemInterface $item, array $attributes): void
7678

7779
$relation = $this->getRelationFromItem($item, $availableRelation);
7880

81+
// The relation should be unset
82+
if (
83+
($relation instanceof OneRelationInterface && $attributes[$availableRelation] === null) ||
84+
($relation instanceof ManyRelationInterface && $attributes[$availableRelation] === [])
85+
) {
86+
$relation->dissociate();
87+
88+
return;
89+
}
90+
7991
// It is a valid relation
8092
if ($relation instanceof HasOneRelation) {
8193
$this->hydrateHasOneRelation($relation, $attributes[$availableRelation]);

tests/ItemHydratorTest.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,28 @@ public function it_hydrates_hasone_relationships_with_attributes()
102102
$this->assertArrayHasKey('hasone_relation', $item->toJsonApiArray()['relationships']);
103103
}
104104

105+
/**
106+
* @test
107+
*/
108+
public function it_dissociates_hasone_relationships_when_null()
109+
{
110+
$data = [
111+
'hasone_relation' => null,
112+
];
113+
114+
$item = new WithRelationshipItem();
115+
$item = $this->getItemHydrator()->hydrate($item, $data);
116+
117+
/** @var \Swis\JsonApi\Client\Relations\HasOneRelation $hasOne */
118+
$hasOne = $item->getRelation('hasone_relation');
119+
$this->assertInstanceOf(HasOneRelation::class, $hasOne);
120+
121+
$this->assertNull($hasOne->getIncluded());
122+
123+
$this->assertArrayHasKey('hasone_relation', $item->toJsonApiArray()['relationships']);
124+
$this->assertNull($item->toJsonApiArray()['relationships']['hasone_relation']['data']);
125+
}
126+
105127
/**
106128
* @test
107129
*/
@@ -174,6 +196,28 @@ public function it_hydrates_hasmany_relationships_with_attributes()
174196
$this->assertArrayHasKey('hasmany_relation', $item->toJsonApiArray()['relationships']);
175197
}
176198

199+
/**
200+
* @test
201+
*/
202+
public function it_dissociates_hasmany_relationships_when_empty_array()
203+
{
204+
$data = [
205+
'hasmany_relation' => [],
206+
];
207+
208+
$item = new WithRelationshipItem();
209+
$item = $this->getItemHydrator()->hydrate($item, $data);
210+
211+
/** @var \Swis\JsonApi\Client\Relations\HasManyRelation $hasMany */
212+
$hasMany = $item->getRelation('hasmany_relation');
213+
$this->assertInstanceOf(HasManyRelation::class, $hasMany);
214+
215+
$this->assertTrue($hasMany->getIncluded()->isEmpty());
216+
217+
$this->assertArrayHasKey('hasmany_relation', $item->toJsonApiArray()['relationships']);
218+
$this->assertSame([], $item->toJsonApiArray()['relationships']['hasmany_relation']['data']);
219+
}
220+
177221
/**
178222
* @test
179223
*/
@@ -228,6 +272,28 @@ public function it_hydrates_morphto_relationships_with_attributes()
228272
$this->assertArrayHasKey('morphto_relation', $item->toJsonApiArray()['relationships']);
229273
}
230274

275+
/**
276+
* @test
277+
*/
278+
public function it_dissociates_morphto_relationships_when_null()
279+
{
280+
$data = [
281+
'morphto_relation' => null,
282+
];
283+
284+
$item = new WithRelationshipItem();
285+
$item = $this->getItemHydrator()->hydrate($item, $data);
286+
287+
/** @var \Swis\JsonApi\Client\Relations\MorphToRelation $morphTo */
288+
$morphTo = $item->getRelation('morphto_relation');
289+
$this->assertInstanceOf(MorphToRelation::class, $morphTo);
290+
291+
$this->assertNull($morphTo->getIncluded());
292+
293+
$this->assertArrayHasKey('morphto_relation', $item->toJsonApiArray()['relationships']);
294+
$this->assertNull($item->toJsonApiArray()['relationships']['morphto_relation']['data']);
295+
}
296+
231297
/**
232298
* @test
233299
*/
@@ -350,6 +416,28 @@ public function it_hydrates_morphtomany_relationships_with_attributes()
350416
$this->assertArrayHasKey('morphtomany_relation', $item->toJsonApiArray()['relationships']);
351417
}
352418

419+
/**
420+
* @test
421+
*/
422+
public function it_dissociates_morphtomany_relationships_when_empty_array()
423+
{
424+
$data = [
425+
'morphtomany_relation' => [],
426+
];
427+
428+
$item = new WithRelationshipItem();
429+
$item = $this->getItemHydrator()->hydrate($item, $data);
430+
431+
/** @var \Swis\JsonApi\Client\Relations\MorphToManyRelation $morphToMany */
432+
$morphToMany = $item->getRelation('morphtomany_relation');
433+
$this->assertInstanceOf(MorphToManyRelation::class, $morphToMany);
434+
435+
$this->assertTrue($morphToMany->getIncluded()->isEmpty());
436+
437+
$this->assertArrayHasKey('morphtomany_relation', $item->toJsonApiArray()['relationships']);
438+
$this->assertSame([], $item->toJsonApiArray()['relationships']['morphtomany_relation']['data']);
439+
}
440+
353441
/**
354442
* @test
355443
*/

0 commit comments

Comments
 (0)