Skip to content

Commit 05aaa09

Browse files
authored
fix: remove pivot from context when removing element from many-to-many relation (#177)
1 parent 11d2491 commit 05aaa09

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/Relation/ManyToMany.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ class ManyToMany extends Relation\AbstractRelation
3636

3737
/**
3838
* @param ORMInterface $orm
39-
* @param string $name
40-
* @param string $target
41-
* @param array $schema
39+
* @param string $name
40+
* @param string $target
41+
* @param array $schema
4242
*/
4343
public function __construct(ORMInterface $orm, string $name, string $target, array $schema)
4444
{
@@ -144,6 +144,8 @@ public function queue(CC $store, $entity, Node $node, $related, $original): Comm
144144
if (!$related->has($item)) {
145145
// todo: add support for nullable pivot entities
146146
$sequence->addCommand($this->orm->queueDelete($original->get($item)));
147+
$sequence->addCommand($this->orm->queueStore($item));
148+
$original->getContext()->offsetUnset($item);
147149
}
148150
}
149151

@@ -153,9 +155,9 @@ public function queue(CC $store, $entity, Node $node, $related, $original): Comm
153155
/**
154156
* Link two entities together and create/update pivot context.
155157
*
156-
* @param Node $node
157-
* @param object $related
158-
* @param object $pivot
158+
* @param Node $node
159+
* @param object $related
160+
* @param object $pivot
159161
* @param Pivoted\PivotedStorage $storage
160162
* @return CommandInterface
161163
*/
@@ -205,9 +207,9 @@ protected function link(Node $node, $related, $pivot, Pivoted\PivotedStorage $st
205207
* Since many to many relation can overlap from two directions we have to properly resolve the pivot entity upon
206208
* it's generation. This is achieved using temporary mapping associated with each of the entity states.
207209
*
208-
* @param Node $node
210+
* @param Node $node
209211
* @param object $related
210-
* @param mixed $pivot
212+
* @param mixed $pivot
211213
* @return mixed|object|null
212214
*/
213215
protected function initPivot(Node $node, $related, $pivot)

tests/ORM/ManyToManySingleEntityTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Cycle\ORM\Mapper\Mapper;
99
use Cycle\ORM\Mapper\StdMapper;
1010
use Cycle\ORM\Relation;
11+
use Cycle\ORM\Relation\Pivoted\PivotedCollection;
1112
use Cycle\ORM\Schema;
1213
use Cycle\ORM\Select;
1314
use Cycle\ORM\Tests\Fixtures\RbacItemAbstract;
@@ -117,4 +118,43 @@ public function testStore(): void
117118
self::assertInstanceOf(RbacPermission::class, $fetchedRole->children->first());
118119
self::assertSame('writeUser', $fetchedRole->children->first()->name);
119120
}
121+
122+
public function testClearAndFillRelation(): void
123+
{
124+
$role = new RbacRole('superAdmin');
125+
126+
$permission = new RbacPermission('writeUser');
127+
128+
$role->children->add($permission);
129+
$permission->parents->add($role);
130+
131+
$tr = new Transaction($this->orm);
132+
$tr->persist($role);
133+
$tr->run();
134+
135+
unset($role, $permission);
136+
137+
$this->orm = $this->orm->withHeap(new Heap());
138+
139+
/** @var RbacRole $fetchedRole */
140+
$fetchedRole = (new Select($this->orm, 'rbac_item'))->wherePK('superAdmin')->fetchOne();
141+
/** @var RbacPermission $fetchedPermission */
142+
$fetchedPermission = (new Select($this->orm, 'rbac_item'))->wherePK('writeUser')->fetchOne();
143+
144+
$fetchedRole->children->removeElement($fetchedPermission);
145+
$fetchedPermission->parents->removeElement($fetchedRole);
146+
147+
$tr = new Transaction($this->orm);
148+
$tr->persist($fetchedRole);
149+
$tr->run();
150+
151+
$fetchedRole->children->add($fetchedPermission);
152+
$fetchedPermission->parents->add($fetchedRole);
153+
154+
$tr = new Transaction($this->orm);
155+
$tr->persist($fetchedRole);
156+
$tr->run();
157+
158+
self::assertTrue(true);
159+
}
120160
}

0 commit comments

Comments
 (0)