浏览代码

Merge pull request #5817 from cakephp/3.0-fix-query-regression

3.0 fix query regression
José Lorenzo Rodríguez 11 年之前
父节点
当前提交
e06e89d5c3

+ 2 - 1
src/Database/QueryCompiler.php

@@ -299,7 +299,8 @@ class QueryCompiler
         $result = [];
         foreach ($expressions as $k => $expression) {
             if ($expression instanceof ExpressionInterface) {
-                $expression = '(' . $expression->sql($generator) . ')';
+                $value = $expression->sql($generator);
+                $expression = '(' . $value . ')';
             }
             $result[$k] = $expression;
         }

+ 3 - 1
src/ORM/Association/SelectableAssociationTrait.php

@@ -14,6 +14,7 @@
  */
 namespace Cake\ORM\Association;
 
+use Cake\Database\ExpressionInterface;
 use Cake\Database\Expression\IdentifierExpression;
 use Cake\Database\Expression\TupleComparison;
 
@@ -240,7 +241,8 @@ trait SelectableAssociationTrait
         }
 
         $fields = $query->aliasFields($keys, $this->source()->alias());
-        return $filterQuery->select($fields, true)->distinct();
+        $filterQuery->select($fields, true)->group(array_values($fields));
+        return $filterQuery;
     }
 
     /**

+ 8 - 12
src/ORM/EagerLoader.php

@@ -497,13 +497,14 @@ class EagerLoader
             $instance = $meta->instance();
             $config = $meta->config();
             $alias = $instance->source()->alias();
+            $path = $meta->aliasPath();
 
             $requiresKeys = $instance->requiresKeys($config);
-            if ($requiresKeys && empty($collected[$alias])) {
+            if ($requiresKeys && empty($collected[$path][$alias])) {
                 continue;
             }
-            $keys = isset($collected[$alias]) ? $collected[$alias] : null;
 
+            $keys = isset($collected[$path][$alias]) ? $collected[$path][$alias] : null;
             $f = $instance->eagerLoader(
                 $config + [
                     'query' => $query,
@@ -615,7 +616,7 @@ class EagerLoader
             foreach ($keys as $key) {
                 $pkFields[] = key($query->aliasField($key, $alias));
             }
-            $collectKeys[$alias] = [$alias, $pkFields, count($pkFields) === 1];
+            $collectKeys[$meta->aliasPath()] = [$alias, $pkFields, count($pkFields) === 1];
         }
 
         if (empty($collectKeys)) {
@@ -641,13 +642,14 @@ class EagerLoader
     {
         $keys = [];
         while ($result = $statement->fetch('assoc')) {
-            foreach ($collectKeys as $parts) {
+            foreach ($collectKeys as $nestKey => $parts) {
                 // Missed joins will have null in the results.
                 if ($parts[2] === true && !isset($result[$parts[1][0]])) {
                     continue;
                 }
                 if ($parts[2] === true) {
-                    $keys[$parts[0]][] = $result[$parts[1][0]];
+                    $value = $result[$parts[1][0]];
+                    $keys[$nestKey][$parts[0]][$value] = $value;
                     continue;
                 }
 
@@ -656,13 +658,7 @@ class EagerLoader
                 foreach ($parts[1] as $key) {
                     $collected[] = $result[$key];
                 }
-                $keys[$parts[0]][] = $collected;
-            }
-        }
-
-        foreach ($collectKeys as $parts) {
-            if ($parts[2] === true && isset($keys[$parts[0]])) {
-                $keys[$parts[0]] = array_unique($keys[$parts[0]]);
+                $keys[$nestKey][$parts[0]][implode(';', $collected)] = $collected;
             }
         }
 

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

@@ -461,7 +461,10 @@ class QueryRegressionTest extends TestCase
         $table = TableRegistry::get('Articles');
         $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
         $table->locale('eng');
-        $query = $table->find('translations')->limit(10)->offset(1);
+        $query = $table->find('translations')
+            ->order(['Articles.id' => 'ASC'])
+            ->limit(10)
+            ->offset(1);
         $result = $query->toArray();
         $this->assertCount(2, $result);
     }
@@ -727,7 +730,6 @@ class QueryRegressionTest extends TestCase
         $this->assertNotNull($result->article->author);
     }
 
-
     /**
      * Tests that trying to contain an inexistent association
      * throws an exception and not a fatal error.
@@ -742,6 +744,35 @@ class QueryRegressionTest extends TestCase
     }
 
     /**
+     * Tests that using matching and contain on belongsTo associations
+     * works correctly.
+     *
+     * @see https://github.com/cakephp/cakephp/issues/5721
+     * @return void
+     */
+    public function testFindMatchingWithContain()
+    {
+        $comments = TableRegistry::get('Comments');
+        $comments->belongsTo('Articles');
+        $comments->belongsTo('Users');
+
+        $result = $comments->find()
+            ->contain(['Articles', 'Users'])
+            ->matching('Articles', function ($q) {
+                return $q->where(['Articles.id >=' => 1]);
+            })
+            ->matching('Users', function ($q) {
+                return $q->where(['Users.id >=' => 1]);
+            })
+            ->order(['Comments.id' => 'ASC'])
+            ->first();
+        $this->assertInstanceOf('Cake\ORM\Entity', $result->article);
+        $this->assertInstanceOf('Cake\ORM\Entity', $result->user);
+        $this->assertEquals(2, $result->user->id);
+        $this->assertEquals(1, $result->article->id);
+    }
+
+    /**
      * Tests that HasMany associations don't use duplicate PK values.
      *
      * @return void