ソースを参照

Added fix for the subquery strategy using the wrong alias when comparing.

Previously, the subquery strategy was naively assuming that the alias used for
comparing could be derived from the original query, but the right thing to do was
to use the alias from the association object itself.

Fixes #5769
Jose Lorenzo Rodriguez 11 年 前
コミット
1097eef963

+ 2 - 2
src/ORM/Association/SelectableAssociationTrait.php

@@ -141,7 +141,7 @@ trait SelectableAssociationTrait
     public function _addFilteringJoin($query, $key, $subquery)
     {
         $filter = [];
-        $aliasedTable = $subquery->repository()->alias();
+        $aliasedTable = $this->source()->alias();
 
         foreach ($subquery->clause('select') as $aliasedField => $field) {
             $filter[] = new IdentifierExpression($field);
@@ -239,7 +239,7 @@ trait SelectableAssociationTrait
             $keys = (array)$this->foreignKey();
         }
 
-        $fields = $query->aliasFields($keys);
+        $fields = $query->aliasFields($keys, $this->source()->alias());
         return $filterQuery->select($fields, true);
     }
 

+ 49 - 0
tests/Fixture/AuthorsTagsFixture.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\Fixture;
+
+use Cake\TestSuite\Fixture\TestFixture;
+
+/**
+ * AuthorsTags fixture
+ *
+ */
+class AuthorsTagsFixture extends TestFixture
+{
+
+    /**
+     * fields property
+     *
+     * @var array
+     */
+    public $fields = [
+        'author_id' => ['type' => 'integer', 'null' => false],
+        'tag_id' => ['type' => 'integer', 'null' => false],
+        '_constraints' => [
+            'unique_tag' => ['type' => 'primary', 'columns' => ['author_id', 'tag_id']],
+        ]
+    ];
+
+    /**
+     * records property
+     *
+     * @var array
+     */
+    public $records = [
+        ['author_id' => 3, 'tag_id' => 1],
+        ['author_id' => 3, 'tag_id' => 2],
+        ['author_id' => 2, 'tag_id' => 1],
+        ['author_id' => 2, 'tag_id' => 3]
+    ];
+}

+ 32 - 2
tests/TestCase/ORM/QueryRegressionTest.php

@@ -42,6 +42,7 @@ class QueryRegressionTest extends TestCase
         'core.authors',
         'core.special_tags',
         'core.translates',
+        'core.authors_tags',
     ];
 
     /**
@@ -466,7 +467,7 @@ class QueryRegressionTest extends TestCase
     }
 
     /**
-     * Tests that using the subquery strategy in a deep assotiatin returns the right results
+     * Tests that using the subquery strategy in a deep assotiation returns the right results
      *
      * @see https://github.com/cakephp/cakephp/issues/4484
      * @return void
@@ -478,7 +479,7 @@ class QueryRegressionTest extends TestCase
         $table->Articles->belongsToMany('Tags', [
             'strategy' => 'subquery'
         ]);
-        $table->Articles->Tags->junction();
+
         $result = $table->find()->contain(['Articles.Tags'])->toArray();
         $this->assertEquals(
             ['tag1', 'tag3'],
@@ -487,6 +488,35 @@ class QueryRegressionTest extends TestCase
     }
 
     /**
+     * Tests that using the subquery strategy in a deep assotiation returns the right results
+     *
+     * @see https://github.com/cakephp/cakephp/issues/5769
+     * @return void
+     */
+    public function testDeepBelongsToManySubqueryStrategy2()
+    {
+        $table = TableRegistry::get('Authors');
+        $table->hasMany('Articles');
+        $table->Articles->belongsToMany('Tags', [
+            'strategy' => 'subquery'
+        ]);
+        $table->belongsToMany('Tags', [
+            'strategy' => 'subquery',
+        ]);
+        $table->Articles->belongsTo('Authors');
+
+        $result = $table->Articles->find()
+            ->where(['Authors.id > 1'])
+            ->contain(['Authors.Tags'])
+            ->toArray();
+        $this->assertEquals(
+            ['tag1', 'tag2'],
+            collection($result[0]->author->tags)->extract('name')->toArray()
+        );
+        $this->assertEquals(3, $result[0]->author->id);
+    }
+
+    /**
      * Tests that getting the count of a query having containments return
      * the correct results
      *