|
|
@@ -21,6 +21,7 @@ use Cake\Database\Expression\QueryExpression;
|
|
|
use Cake\Datasource\ConnectionManager;
|
|
|
use Cake\Datasource\EntityInterface;
|
|
|
use Cake\Event\EventInterface;
|
|
|
+use Cake\I18n\FrozenTime;
|
|
|
use Cake\ORM\Association\BelongsTo;
|
|
|
use Cake\ORM\Association\BelongsToMany;
|
|
|
use Cake\ORM\Association\HasMany;
|
|
|
@@ -54,6 +55,8 @@ class BelongsToManyTest extends TestCase
|
|
|
'core.BinaryUuidItems',
|
|
|
'core.BinaryUuidTags',
|
|
|
'core.BinaryUuidItemsBinaryUuidTags',
|
|
|
+ 'core.CompositeKeyArticles',
|
|
|
+ 'core.CompositeKeyArticlesTags',
|
|
|
];
|
|
|
|
|
|
/**
|
|
|
@@ -1071,6 +1074,61 @@ class BelongsToManyTest extends TestCase
|
|
|
$this->assertCount(1, $refresh->binary_uuid_tags, 'One tag should remain');
|
|
|
}
|
|
|
|
|
|
+ public function testReplaceLinksComplexTypeForeignKey()
|
|
|
+ {
|
|
|
+ $articles = $this->fetchTable('CompositeKeyArticles');
|
|
|
+ $tags = $this->fetchTable('Tags');
|
|
|
+
|
|
|
+ $articles->belongsToMany('Tags', [
|
|
|
+ 'foreignKey' => ['author_id', 'created'],
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $article = $articles->newEntity([
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'body' => 'First post',
|
|
|
+ 'created' => new FrozenTime(),
|
|
|
+ ]);
|
|
|
+ $articles->saveOrFail($article);
|
|
|
+ $tag1 = $tags->find()->where(['Tags.name' => 'tag1'])->firstOrFail();
|
|
|
+ $tag2 = $tags->find()->where(['Tags.name' => 'tag2'])->firstOrFail();
|
|
|
+
|
|
|
+ $findArticle = function ($article) use ($articles) {
|
|
|
+ return $articles->find()
|
|
|
+ ->where(['CompositeKeyArticles.author_id' => $article->author_id])
|
|
|
+ ->contain('Tags')
|
|
|
+ ->firstOrFail();
|
|
|
+ };
|
|
|
+
|
|
|
+ $article = $findArticle($article);
|
|
|
+ $this->assertEmpty($article->tags);
|
|
|
+
|
|
|
+ // Create the first link
|
|
|
+ $article = $articles->patchEntity($article, ['tags' => ['_ids' => [$tag1->id]]]);
|
|
|
+ $result = $articles->save($article, ['associated' => 'Tags']);
|
|
|
+ $this->assertNotEmpty($result);
|
|
|
+ $this->assertCount(1, $result->tags);
|
|
|
+ $this->assertEquals($tag1->id, $result->tags[0]->id);
|
|
|
+
|
|
|
+ // Add second tag. Reload tag objects so created fields have different
|
|
|
+ // instances.
|
|
|
+ $article = $findArticle($article);
|
|
|
+ $article = $articles->patchEntity($article, ['tags' => ['_ids' => [$tag1->id, $tag2->id]]]);
|
|
|
+ $result = $articles->save($article, ['associated' => 'Tags']);
|
|
|
+
|
|
|
+ // Check in memory entity.
|
|
|
+ $this->assertNotEmpty($result);
|
|
|
+ $this->assertCount(2, $result->tags);
|
|
|
+ $this->assertEquals('tag1', $result->tags[0]->name);
|
|
|
+ $this->assertEquals('tag2', $result->tags[1]->name);
|
|
|
+
|
|
|
+ // Reload to check persisted state.
|
|
|
+ $result = $findArticle($article);
|
|
|
+ $this->assertNotEmpty($result);
|
|
|
+ $this->assertCount(2, $result->tags);
|
|
|
+ $this->assertEquals('tag1', $result->tags[0]->name);
|
|
|
+ $this->assertEquals('tag2', $result->tags[1]->name);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Provider for empty values
|
|
|
*
|