Skip to content

Commit 97a34fc

Browse files
authored
Merge pull request #42 from swisnl/issue/36
Make sure dissociating a related item results in valid JSON
2 parents 318ca68 + 57fb5bc commit 97a34fc

File tree

7 files changed

+264
-65
lines changed

7 files changed

+264
-65
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616
N.B. This is a breaking change if you implement the interface yourself or extend the `DocumentClient`. [#34](https://github.com/swisnl/json-api-client/pull/34)
1717
* `Repository` doesn't throw exceptions anymore. [#41](https://github.com/swisnl/json-api-client/pull/41)
1818
N.B. This is a breaking change if you catch `DocumentNotFoundException` or `DocumentTypeException`. If you would like the old behaviour, you can simply extend the `Repository` and implement it yourself.
19+
* A HasOne or MorphTo relation do not set a `[relationship]_id` field on the parent when associating a related item.
1920

2021
### Removed
2122

@@ -27,6 +28,7 @@ N.B. This is a breaking change if you catch these exceptions.
2728
### Fixed
2829

2930
* Do not fail on, but skip relationships without data [#38](https://github.com/swisnl/json-api-client/pull/38)
31+
* Dissociating a related item now produces valid JSON
3032

3133
## [0.11.0] - 2018-12-21
3234

src/Item.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,16 @@ public function getRelationships(): array
138138
/** @var \Swis\JsonApi\Client\Interfaces\RelationInterface $relationship */
139139
foreach ($this->relationships as $name => $relationship) {
140140
if ($relationship instanceof HasOneRelation) {
141-
$relationships[$name] = [
142-
'data' => [
143-
'type' => $relationship->getType(),
144-
'id' => $relationship->getId(),
145-
],
146-
];
141+
$relationships[$name] = ['data' => null];
142+
143+
if ($relationship->getIncluded() !== null) {
144+
$relationships[$name] = [
145+
'data' => [
146+
'type' => $relationship->getType(),
147+
'id' => $relationship->getId(),
148+
],
149+
];
150+
}
147151
} elseif ($relationship instanceof HasManyRelation) {
148152
$relationships[$name]['data'] = [];
149153

@@ -155,12 +159,16 @@ public function getRelationships(): array
155159
];
156160
}
157161
} elseif ($relationship instanceof MorphToRelation) {
158-
$relationships[$name] = [
159-
'data' => [
160-
'type' => $relationship->getIncluded()->getType(),
161-
'id' => $relationship->getIncluded()->getId(),
162-
],
163-
];
162+
$relationships[$name] = ['data' => null];
163+
164+
if ($relationship->getIncluded() !== null) {
165+
$relationships[$name] = [
166+
'data' => [
167+
'type' => $relationship->getIncluded()->getType(),
168+
'id' => $relationship->getIncluded()->getId(),
169+
],
170+
];
171+
}
164172
} elseif ($relationship instanceof MorphToManyRelation) {
165173
$relationships[$name]['data'] = [];
166174

@@ -302,6 +310,18 @@ public function hasRelationship(string $name): bool
302310
return array_key_exists($name, $this->relationships);
303311
}
304312

313+
/**
314+
* @param $name
315+
*
316+
* @return static
317+
*/
318+
public function removeRelationship(string $name)
319+
{
320+
unset($this->relationships[$name]);
321+
322+
return $this;
323+
}
324+
305325
/**
306326
* Create a singular relation to another item.
307327
*
@@ -316,7 +336,7 @@ public function hasOne(string $class, string $relationName = null)
316336
$itemType = (new $class())->getType();
317337

318338
if (!array_key_exists($relationName, $this->relationships)) {
319-
$this->relationships[$relationName] = new HasOneRelation($itemType, $this);
339+
$this->relationships[$relationName] = new HasOneRelation($itemType);
320340
}
321341

322342
return $this->relationships[$relationName];
@@ -354,7 +374,7 @@ public function morphTo(string $relationName = null)
354374
$relationName = $relationName ?: snake_case(debug_backtrace()[1]['function']);
355375

356376
if (!array_key_exists($relationName, $this->relationships)) {
357-
$this->relationships[$relationName] = new MorphToRelation($this);
377+
$this->relationships[$relationName] = new MorphToRelation();
358378
}
359379

360380
return $this->relationships[$relationName];

src/Relations/AbstractOneRelation.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
abstract class AbstractOneRelation extends AbstractRelation
99
{
1010
/**
11-
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
11+
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface|null
1212
*/
1313
protected $included;
1414

@@ -33,7 +33,6 @@ public function associate(DataInterface $included)
3333
}
3434

3535
$this->setId($included->getId());
36-
$this->setType($included->getType());
3736

3837
$this->included = $included;
3938

@@ -45,6 +44,8 @@ public function associate(DataInterface $included)
4544
*/
4645
public function dissociate()
4746
{
47+
$this->setId(null);
48+
4849
$this->included = null;
4950

5051
return $this;

src/Relations/AbstractRelation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function setType(string $type)
2929
}
3030

3131
/**
32-
* @return string|null
32+
* @return string
3333
*/
3434
public function getType(): string
3535
{

src/Relations/HasOneRelation.php

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,13 @@
22

33
namespace Swis\JsonApi\Client\Relations;
44

5-
use Swis\JsonApi\Client\Interfaces\DataInterface;
6-
use Swis\JsonApi\Client\Interfaces\ItemInterface;
7-
85
class HasOneRelation extends AbstractOneRelation
96
{
107
/**
11-
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
8+
* @param string $type
129
*/
13-
protected $parentItem;
14-
15-
/**
16-
* @param string $type
17-
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
18-
*/
19-
public function __construct(string $type, ItemInterface $item)
10+
public function __construct(string $type)
2011
{
2112
$this->type = $type;
22-
$this->parentItem = $item;
23-
}
24-
25-
/**
26-
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $included
27-
*
28-
* @throws \InvalidArgumentException
29-
*
30-
* @return $this
31-
*/
32-
public function associate(DataInterface $included)
33-
{
34-
$result = parent::associate($included);
35-
36-
// Set the $relation.'_id' on the parent
37-
$this->parentItem->setAttribute($this->type.'_id', $this->getId());
38-
39-
return $result;
40-
}
41-
42-
/**
43-
* @return $this
44-
*/
45-
public function dissociate()
46-
{
47-
$result = parent::dissociate();
48-
49-
// Remove the $relation.'_id' on the parent
50-
$this->parentItem->setAttribute($this->type.'_id', null);
51-
52-
return $result;
5313
}
5414
}

src/Relations/MorphToRelation.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,33 @@
22

33
namespace Swis\JsonApi\Client\Relations;
44

5-
use Swis\JsonApi\Client\Interfaces\ItemInterface;
5+
use Swis\JsonApi\Client\Interfaces\DataInterface;
66

77
class MorphToRelation extends AbstractOneRelation
88
{
99
/**
10-
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
10+
* {@inheritdoc}
1111
*/
12-
protected $parentItem;
12+
public function associate(DataInterface $included)
13+
{
14+
parent::associate($included);
15+
16+
/* @var \Swis\JsonApi\Client\Interfaces\ItemInterface $included */
17+
18+
$this->type = $included->getType();
19+
20+
return $this;
21+
}
1322

1423
/**
15-
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
24+
* {@inheritdoc}
1625
*/
17-
public function __construct(ItemInterface $item)
26+
public function dissociate()
1827
{
19-
$this->parentItem = $item;
28+
parent::dissociate();
29+
30+
$this->type = null;
31+
32+
return $this;
2033
}
2134
}

0 commit comments

Comments
 (0)