Browse Source

Fix incorrect alias name on joined associations

When loading joined associations but not selecting any columns on the
root table results would have the incorrect property set for
associations. Instead of the association property, the association alias
would be used. By hydrating an empty array for the root table we can
correctly nest data.

This change modifies an existing test added in #6339 which ensured that
the current but broken behavior exists. Reviewing those changes I should
have noticed the association property was wrong. Whilst this change
could break existing applications the current behavior is not expected
and likely more frustrating.

Refs #11580
Mark Story 7 years ago
parent
commit
22f82f53e8

+ 7 - 0
src/ORM/ResultSet.php

@@ -528,6 +528,13 @@ class ResultSet implements ResultSetInterface
             $presentAliases[$table] = true;
         }
 
+        // If the default table is not in the results, set
+        // it to an empty array so that any contained
+        // associations hydrate correctly.
+        if (!isset($results[$defaultAlias])) {
+            $results[$defaultAlias] = [];
+        }
+
         unset($presentAliases[$defaultAlias]);
 
         foreach ($this->_containMap as $assoc) {

+ 22 - 0
tests/TestCase/ORM/Association/BelongsToTest.php

@@ -434,4 +434,26 @@ class BelongsToTest extends TestCase
             return $q->applyOptions(['something' => 'more']);
         }]);
     }
+
+    /**
+     * Test that failing to add the foreignKey to the list of fields will throw an
+     * exception
+     *
+     * @return void
+     */
+    public function testAttachToNoFieldsSelected()
+    {
+        $articles = $this->getTableLocator()->get('Articles');
+        $association = $articles->belongsTo('Authors');
+
+        $query = $articles->find()
+            ->select(['Authors.name'])
+            ->where(['Articles.id' => 1])
+            ->contain('Authors');
+        $result = $query->firstOrFail();
+
+        $this->assertNotEmpty($result->author);
+        $this->assertSame('mariano', $result->author->name);
+        $this->assertSame(['author'], array_keys($result->toArray()), 'No other properties included.');
+    }
 }

+ 1 - 1
tests/TestCase/ORM/QueryTest.php

@@ -2451,7 +2451,7 @@ class QueryTest extends TestCase
             ->contain(['Authors'])
             ->order(['Authors.id' => 'asc'])
             ->select(['Authors.id']);
-        $results = $query->extract('Authors.id')->toList();
+        $results = $query->extract('author.id')->toList();
         $expected = [1, 1, 3];
         $this->assertEquals($expected, $results);
     }