From ac3710d467df3fc9753d47f484ccd30cbdfa87c0 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 14 Jan 2014 12:56:31 +0100 Subject: [PATCH] Improving eager loading tet for BelongsToMany when using composite keys --- .../Association/ExternalAssociationTrait.php | 4 +- .../ORM/Association/BelongsToManyTest.php | 100 ++++++++++++++++++ Test/TestCase/ORM/CompositeKeysTest.php | 9 +- 3 files changed, 104 insertions(+), 9 deletions(-) diff --git a/Cake/ORM/Association/ExternalAssociationTrait.php b/Cake/ORM/Association/ExternalAssociationTrait.php index c50a9b112c3..54974da6370 100644 --- a/Cake/ORM/Association/ExternalAssociationTrait.php +++ b/Cake/ORM/Association/ExternalAssociationTrait.php @@ -273,9 +273,9 @@ protected function _addFilteringCondition($query, $key, $filter) { $types[] = $defaults[$k]; } } - $query->andWhere(new TupleComparison($key, $filter, $types, 'IN')); - return $query; + return $query->andWhere(new TupleComparison($key, $filter, $types, 'IN')); } + return $query->andWhere([$key . ' IN' => $filter]); } diff --git a/Test/TestCase/ORM/Association/BelongsToManyTest.php b/Test/TestCase/ORM/Association/BelongsToManyTest.php index 86b190b3547..a5a9aeba664 100644 --- a/Test/TestCase/ORM/Association/BelongsToManyTest.php +++ b/Test/TestCase/ORM/Association/BelongsToManyTest.php @@ -18,6 +18,7 @@ use Cake\Database\Expression\IdentifierExpression; use Cake\Database\Expression\QueryExpression; +use Cake\Database\Expression\TupleComparison; use Cake\ORM\Association\BelongsToMany; use Cake\ORM\Entity; use Cake\ORM\Query; @@ -795,6 +796,105 @@ public function testEagerLoaderWithQueryBuilder() { $association->eagerLoader(compact('keys', 'query', 'queryBuilder')); } +/** + * Test the eager loader method with no extra options + * + * @return void + */ + public function testEagerLoaderMultipleKeys() { + $config = [ + 'sourceTable' => $this->article, + 'targetTable' => $this->tag, + 'foreignKey' => ['article_id', 'site_id'], + 'targetForeignKey' => ['tag_id', 'site_id'] + ]; + $this->article->primaryKey(['id', 'site_id']); + $this->tag->primaryKey(['id', 'site_id']); + TableRegistry::get('ArticlesTags', [ + 'table' => 'articles_tags', + 'schema' => [ + 'article_id' => ['type' => 'integer'], + 'tag_id' => ['type' => 'integer'], + 'site_id' => ['type' => 'integer'], + ] + ]); + $association = new BelongsToMany('Tags', $config); + $keys = [[1, 10], [2, 20], [3, 30], [4, 40]]; + $query = $this->getMock('Cake\ORM\Query', ['all', 'matching'], [null, null]); + + $this->tag->expects($this->once()) + ->method('find') + ->with('all') + ->will($this->returnValue($query)); + + $results = [ + [ + 'id' => 1, + 'name' => 'foo', + 'site_id' => 1, + 'articles_tags' => [ + 'article_id' => 1, + 'site_id' => 1 + ] + ], + [ + 'id' => 2, + 'name' => 'bar', + 'site_id' => 2, + 'articles_tags' => [ + 'article_id' => 2, + 'site_id' => 2 + ] + ] + ]; + $query->expects($this->once()) + ->method('all') + ->will($this->returnValue($results)); + + $tuple = new TupleComparison( + ['ArticlesTags.article_id', 'ArticlesTags.site_id'], $keys, [], 'IN' + ); + $query->expects($this->once())->method('matching') + ->will($this->returnCallback(function($alias, $callable) use ($query, $tuple) { + $this->assertEquals('ArticlesTags', $alias); + $q = $this->getMock('Cake\ORM\Query', [], [null, null]); + + $q->expects($this->once())->method('andWhere') + ->with($tuple) + ->will($this->returnSelf()); + + $this->assertSame($q, $callable($q)); + return $query; + })); + + $query->hydrate(false); + + $callable = $association->eagerLoader(compact('keys', 'query')); + $row = ['Articles__id' => 1, 'title' => 'article 1', 'Articles__site_id' => 1]; + $result = $callable($row); + $row['Tags__Tags'] = [ + [ + 'id' => 1, + 'name' => 'foo', + 'site_id' => 1, + '_joinData' => ['article_id' => 1, 'site_id' => 1] + ] + ]; + $this->assertEquals($row, $result); + + $row = ['Articles__id' => 2, 'title' => 'article 2', 'Articles__site_id' => 2]; + $result = $callable($row); + $row['Tags__Tags'] = [ + [ + 'id' => 2, + 'name' => 'bar', + 'site_id' => 2, + '_joinData' => ['article_id' => 2, 'site_id' => 2] + ] + ]; + $this->assertEquals($row, $result); + } + /** * Test cascading deletes. * diff --git a/Test/TestCase/ORM/CompositeKeysTest.php b/Test/TestCase/ORM/CompositeKeysTest.php index 21a151684e1..364a8181e28 100644 --- a/Test/TestCase/ORM/CompositeKeysTest.php +++ b/Test/TestCase/ORM/CompositeKeysTest.php @@ -15,11 +15,7 @@ namespace Cake\Test\TestCase\ORM; use Cake\Database\ConnectionManager; -use Cake\Database\Expression\IdentifierExpression; -use Cake\Database\Expression\OrderByExpression; -use Cake\Database\Expression\QueryExpression; use Cake\ORM\Query; -use Cake\ORM\ResultSet; use Cake\ORM\Table; use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; @@ -133,9 +129,8 @@ public function testHasManyEager($strategy) { } /** - * Tests that BelongsToMany associations are correctly eager loaded. - * Also that the query object passes the correct parent model keys to the - * association objects in order to perform eager loading with select strategy + * Tests that BelongsToMany associations are correctly eager loaded when multiple + * foreignKeys are used * * @dataProvider strategiesProvider * @return void