From 8902ed0f0a2113278dc04230b8c66421054cecbc Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 10 Jan 2016 16:25:34 -0500 Subject: [PATCH] Ensure that reciprocal associations have conditions. Without conditions the reciprocal belongs to many association will find different records than the original association definition. Refs #7994 --- src/ORM/Association/BelongsToMany.php | 5 ++- .../ORM/Association/BelongsToManyTest.php | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/ORM/Association/BelongsToMany.php b/src/ORM/Association/BelongsToMany.php index e449be805e3..6c2324f05c5 100644 --- a/src/ORM/Association/BelongsToMany.php +++ b/src/ORM/Association/BelongsToMany.php @@ -227,7 +227,8 @@ protected function _generateTargetAssociations($junction, $source, $target) 'targetTable' => $source, 'foreignKey' => $this->targetForeignKey(), 'targetForeignKey' => $this->foreignKey(), - 'through' => $junction + 'through' => $junction, + 'conditions' => $this->conditions(), ]); } } @@ -322,6 +323,8 @@ public function attachTo(Query $query, array $options = []) $includeFields = $options['includeFields']; } + // TODO see if this can be removed and replaced with eagerly splitting + // up conditions when defining associations. $assoc = $this->_targetTable->association($junction->alias()); $query->removeJoin($assoc->name()); diff --git a/tests/TestCase/ORM/Association/BelongsToManyTest.php b/tests/TestCase/ORM/Association/BelongsToManyTest.php index 00544b6281b..d2e09ee7c71 100644 --- a/tests/TestCase/ORM/Association/BelongsToManyTest.php +++ b/tests/TestCase/ORM/Association/BelongsToManyTest.php @@ -914,6 +914,51 @@ public function testPropertyNoPlugin() $this->assertEquals('tags', $association->property()); } + /** + * Test that the generated associations are correct. + * + * @return void + */ + public function testGeneratedAssociations() + { + $articles = TableRegistry::get('Articles'); + $tags = TableRegistry::get('Tags'); + $conditions = ['SpecialTags.highlighted' => true]; + $assoc = $articles->belongsToMany('Tags', [ + 'sourceTable' => $articles, + 'targetTable' => $tags, + 'foreignKey' => 'foreign_key', + 'targetForeignKey' => 'target_foreign_key', + 'through' => 'SpecialTags', + 'conditions' => $conditions, + ]); + // Generate associations + $assoc->junction(); + + $tagAssoc = $articles->association('Tags'); + $this->assertNotEmpty($tagAssoc, 'btm should exist'); + $this->assertEquals($conditions, $tagAssoc->conditions()); + $this->assertEquals('target_foreign_key', $tagAssoc->targetForeignKey()); + $this->assertEquals('foreign_key', $tagAssoc->foreignKey()); + + $jointAssoc = $articles->association('SpecialTags'); + $this->assertNotEmpty($jointAssoc, 'has many to junction should exist'); + $this->assertInstanceOf('Cake\ORM\Association\HasMany', $jointAssoc); + $this->assertEquals('foreign_key', $jointAssoc->foreignKey()); + + $articleAssoc = $tags->association('Articles'); + $this->assertNotEmpty($articleAssoc, 'reverse btm should exist'); + $this->assertInstanceOf('Cake\ORM\Association\BelongsToMany', $articleAssoc); + $this->assertEquals($conditions, $articleAssoc->conditions()); + $this->assertEquals('foreign_key', $articleAssoc->targetForeignKey(), 'keys should swap'); + $this->assertEquals('target_foreign_key', $articleAssoc->foreignKey(), 'keys should swap'); + + $jointAssoc = $tags->association('SpecialTags'); + $this->assertNotEmpty($jointAssoc, 'has many to junction should exist'); + $this->assertInstanceOf('Cake\ORM\Association\HasMany', $jointAssoc); + $this->assertEquals('target_foreign_key', $jointAssoc->foreignKey()); + } + /** * Tests that fetching belongsToMany association will not force * all fields being returned, but intead will honor the select() clause