Skip to content

Commit

Permalink
- fixes loss of pivot context on pivoted collection clone
Browse files Browse the repository at this point in the history
- adds test for cloned pivoted collections
  • Loading branch information
wolfy-j committed Nov 2, 2020
1 parent 59744a3 commit ef8e28f
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 3 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# CHANGELOG

v1.2.15 (02.11.2020)
--------------------
- fixes loss of pivot context on pivoted collection clone

v1.2.14 (30.10.2020)
--------------------
- improved UUID serialization in Heap by @thenotsoft
- improved UUID serialization in Heap by @thenotsoft

v1.2.13 (23.10.2020)
--------------------
Expand Down
12 changes: 12 additions & 0 deletions src/Relation/Pivoted/PivotedCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,16 @@ public function getPivotContext(): \SplObjectStorage
{
return $this->pivotContext;
}

/**
* @param array $elements
* @return PivotedCollection
*/
protected function createFrom(array $elements)
{
$new = parent::createFrom($elements);
$new->pivotContext = $this->pivotContext;

return $new;
}
}
4 changes: 2 additions & 2 deletions tests/ORM/Fixtures/UuidPrimaryKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public function __construct(string $id)
$this->id = $id;
}

public function getId(): string
public function __toString(): string
{
return $this->id;
}

public function __toString(): string
public function getId(): string
{
return $this->id;
}
Expand Down
57 changes: 57 additions & 0 deletions tests/ORM/ManyToManyPromiseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Cycle\ORM\Heap\Heap;
use Cycle\ORM\Mapper\Mapper;
use Cycle\ORM\Promise\Collection\CollectionPromiseInterface;
use Cycle\ORM\Relation;
use Cycle\ORM\Schema;
use Cycle\ORM\Select;
Expand All @@ -22,6 +23,7 @@
use Cycle\ORM\Tests\Fixtures\User;
use Cycle\ORM\Tests\Traits\TableTrait;
use Cycle\ORM\Transaction;
use Doctrine\Common\Collections\Collection;

abstract class ManyToManyPromiseTest extends BaseTest
{
Expand Down Expand Up @@ -51,6 +53,7 @@ public function setUp(): void

$this->makeFK('tag_user_map', 'user_id', 'user', 'id');
$this->makeFK('tag_user_map', 'tag_id', 'tags', 'id');
$this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true);

$this->getDatabase()->table('user')->insertMultiple(
['email', 'balance'],
Expand Down Expand Up @@ -300,6 +303,60 @@ public function testUnlinkManyToManyAndReplaceSome(): void
$this->assertSame('super', $b->tags->getPivot($b->tags[0])->as);
}

public function testReassign(): void
{
$tagSelect = new Select($this->orm, Tag::class);
$userSelect = new Select($this->orm, User::class);

/**
* @var User $user
*/
$user = $userSelect->load('tags')->fetchOne(['id' => 1]);

$this->assertInstanceOf(Collection::class, $user->tags);

$this->captureWriteQueries();
$tr = new Transaction($this->orm);
$tr->persist($user);
$tr->run();
$this->assertNumWrites(0);

$wantTags = ['tag a', 'tag c'];

foreach ($wantTags as $wantTag) {
$found = false;

foreach ($user->tags as $tag) {
if ($tag->name === $wantTag) {
$found = true;
break;
}
}

if (!$found) {
$newTag = $tagSelect->fetchOne(['name' => $wantTag]);
$user->tags->add($newTag);
}
}

$user->tags = $user->tags->filter(function ($t) use ($wantTags) {
return in_array($t->name, $wantTags);
});

$this->captureWriteQueries();
$tr = new Transaction($this->orm);
$tr->persist($user);
$tr->run();
$this->assertNumWrites(2);

$this->orm = $this->orm->withHeap(new Heap());

$user = (new Select($this->orm, User::class))->fetchOne(['id' => 1]);
$this->assertCount(2, $user->tags);
$this->assertSame('tag a', $user->tags[0]->name);
$this->assertSame('tag c', $user->tags[1]->name);
}

public function testResolvePromise(): void
{
/** @var User $u */
Expand Down
57 changes: 57 additions & 0 deletions tests/ORM/ManyToManyRelationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Cycle\ORM\Heap\Heap;
use Cycle\ORM\Mapper\Mapper;
use Cycle\ORM\Promise\Collection\CollectionPromiseInterface;
use Cycle\ORM\Relation;
use Cycle\ORM\Schema;
use Cycle\ORM\Select;
Expand All @@ -21,6 +22,7 @@
use Cycle\ORM\Tests\Fixtures\User;
use Cycle\ORM\Tests\Traits\TableTrait;
use Cycle\ORM\Transaction;
use Doctrine\Common\Collections\Collection;

abstract class ManyToManyRelationTest extends BaseTest
{
Expand Down Expand Up @@ -50,6 +52,7 @@ public function setUp(): void

$this->makeFK('tag_user_map', 'user_id', 'user', 'id');
$this->makeFK('tag_user_map', 'tag_id', 'tag', 'id');
$this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true);

$this->getDatabase()->table('user')->insertMultiple(
['email', 'balance'],
Expand Down Expand Up @@ -453,4 +456,58 @@ public function testUnlinkManyToManyAndReplaceSome(): void
$this->assertSame('new tag', $b->tags[0]->name);
$this->assertSame('super', $b->tags->getPivot($b->tags[0])->as);
}

public function testReassign(): void
{
$tagSelect = new Select($this->orm, Tag::class);
$userSelect = new Select($this->orm, User::class);

/**
* @var User $user
*/
$user = $userSelect->load('tags')->fetchOne(['id' => 1]);

$this->assertInstanceOf(Collection::class, $user->tags);

$this->captureWriteQueries();
$tr = new Transaction($this->orm);
$tr->persist($user);
$tr->run();
$this->assertNumWrites(0);

$wantTags = ['tag a', 'tag c'];

foreach ($wantTags as $wantTag) {
$found = false;

foreach ($user->tags as $tag) {
if ($tag->name === $wantTag) {
$found = true;
break;
}
}

if (!$found) {
$newTag = $tagSelect->fetchOne(['name' => $wantTag]);
$user->tags->add($newTag);
}
}

$user->tags = $user->tags->filter(function ($t) use ($wantTags) {
return in_array($t->name, $wantTags);
});

$this->captureWriteQueries();
$tr = new Transaction($this->orm);
$tr->persist($user);
$tr->run();
$this->assertNumWrites(2);

$this->orm = $this->orm->withHeap(new Heap());

$user = (new Select($this->orm, User::class))->fetchOne(['id' => 1]);
$this->assertCount(2, $user->tags);
$this->assertSame('tag a', $user->tags[0]->name);
$this->assertSame('tag c', $user->tags[1]->name);
}
}

0 comments on commit ef8e28f

Please sign in to comment.