Skip to content

Unset relation when null (singular) or empty array (plural) #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,10 @@ $attributes = [
'name' => 'Björn Brala',
'homepage' => 'https://github.com/bbrala',
],
'co-author' => null,
'date' => '2018-12-02 15:26:32',
'content' => 'JSON:API was originally drafted in May 2013 by Yehuda Katz...',
'media' => [],
'tags' => [
1,
15,
Expand All @@ -399,6 +401,12 @@ echo json_encode($itemDocument, JSON_PRETTY_PRINT);
"id": "f1a775ef-9407-40ba-93ff-7bd737888dc6"
}
},
"co-author": {
"data": null
},
"media": {
"data": []
},
"tags": {
"data": [{
"type": "tag",
Expand Down Expand Up @@ -426,6 +434,7 @@ echo json_encode($itemDocument, JSON_PRETTY_PRINT);

As you can see in this example, relations can be hydrated by id, or by an associative array with an id and more attributes.
If the item is hydrated using an associative array, it will be included in the resulting json unless `setOmitIncluded(true)` is called on the relation.
You can unset a relation by passing `null` for singular relations or an empty array for plural relations.

N.B. Morph relations require a 'type' attribute to be present in the data in order to know which type of item should be created.

Expand Down
12 changes: 12 additions & 0 deletions src/ItemHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use Illuminate\Support\Str;
use Swis\JsonApi\Client\Exceptions\HydrationException;
use Swis\JsonApi\Client\Interfaces\ItemInterface;
use Swis\JsonApi\Client\Interfaces\ManyRelationInterface;
use Swis\JsonApi\Client\Interfaces\OneRelationInterface;
use Swis\JsonApi\Client\Interfaces\TypeMapperInterface;
use Swis\JsonApi\Client\Relations\HasManyRelation;
use Swis\JsonApi\Client\Relations\HasOneRelation;
Expand Down Expand Up @@ -76,6 +78,16 @@ protected function fillRelations(ItemInterface $item, array $attributes): void

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

// The relation should be unset
if (
($relation instanceof OneRelationInterface && $attributes[$availableRelation] === null) ||
($relation instanceof ManyRelationInterface && $attributes[$availableRelation] === [])
) {
$relation->dissociate();

return;
}

// It is a valid relation
if ($relation instanceof HasOneRelation) {
$this->hydrateHasOneRelation($relation, $attributes[$availableRelation]);
Expand Down
88 changes: 88 additions & 0 deletions tests/ItemHydratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,28 @@ public function it_hydrates_hasone_relationships_with_attributes()
$this->assertArrayHasKey('hasone_relation', $item->toJsonApiArray()['relationships']);
}

/**
* @test
*/
public function it_dissociates_hasone_relationships_when_null()
{
$data = [
'hasone_relation' => null,
];

$item = new WithRelationshipItem();
$item = $this->getItemHydrator()->hydrate($item, $data);

/** @var \Swis\JsonApi\Client\Relations\HasOneRelation $hasOne */
$hasOne = $item->getRelation('hasone_relation');
$this->assertInstanceOf(HasOneRelation::class, $hasOne);

$this->assertNull($hasOne->getIncluded());

$this->assertArrayHasKey('hasone_relation', $item->toJsonApiArray()['relationships']);
$this->assertNull($item->toJsonApiArray()['relationships']['hasone_relation']['data']);
}

/**
* @test
*/
Expand Down Expand Up @@ -174,6 +196,28 @@ public function it_hydrates_hasmany_relationships_with_attributes()
$this->assertArrayHasKey('hasmany_relation', $item->toJsonApiArray()['relationships']);
}

/**
* @test
*/
public function it_dissociates_hasmany_relationships_when_empty_array()
{
$data = [
'hasmany_relation' => [],
];

$item = new WithRelationshipItem();
$item = $this->getItemHydrator()->hydrate($item, $data);

/** @var \Swis\JsonApi\Client\Relations\HasManyRelation $hasMany */
$hasMany = $item->getRelation('hasmany_relation');
$this->assertInstanceOf(HasManyRelation::class, $hasMany);

$this->assertTrue($hasMany->getIncluded()->isEmpty());

$this->assertArrayHasKey('hasmany_relation', $item->toJsonApiArray()['relationships']);
$this->assertSame([], $item->toJsonApiArray()['relationships']['hasmany_relation']['data']);
}

/**
* @test
*/
Expand Down Expand Up @@ -228,6 +272,28 @@ public function it_hydrates_morphto_relationships_with_attributes()
$this->assertArrayHasKey('morphto_relation', $item->toJsonApiArray()['relationships']);
}

/**
* @test
*/
public function it_dissociates_morphto_relationships_when_null()
{
$data = [
'morphto_relation' => null,
];

$item = new WithRelationshipItem();
$item = $this->getItemHydrator()->hydrate($item, $data);

/** @var \Swis\JsonApi\Client\Relations\MorphToRelation $morphTo */
$morphTo = $item->getRelation('morphto_relation');
$this->assertInstanceOf(MorphToRelation::class, $morphTo);

$this->assertNull($morphTo->getIncluded());

$this->assertArrayHasKey('morphto_relation', $item->toJsonApiArray()['relationships']);
$this->assertNull($item->toJsonApiArray()['relationships']['morphto_relation']['data']);
}

/**
* @test
*/
Expand Down Expand Up @@ -350,6 +416,28 @@ public function it_hydrates_morphtomany_relationships_with_attributes()
$this->assertArrayHasKey('morphtomany_relation', $item->toJsonApiArray()['relationships']);
}

/**
* @test
*/
public function it_dissociates_morphtomany_relationships_when_empty_array()
{
$data = [
'morphtomany_relation' => [],
];

$item = new WithRelationshipItem();
$item = $this->getItemHydrator()->hydrate($item, $data);

/** @var \Swis\JsonApi\Client\Relations\MorphToManyRelation $morphToMany */
$morphToMany = $item->getRelation('morphtomany_relation');
$this->assertInstanceOf(MorphToManyRelation::class, $morphToMany);

$this->assertTrue($morphToMany->getIncluded()->isEmpty());

$this->assertArrayHasKey('morphtomany_relation', $item->toJsonApiArray()['relationships']);
$this->assertSame([], $item->toJsonApiArray()['relationships']['morphtomany_relation']['data']);
}

/**
* @test
*/
Expand Down