Browse Source

Minimal changes to make the tests pass again

Jose Lorenzo Rodriguez 9 years ago
parent
commit
78a2306dc0

+ 3 - 2
src/ORM/Association.php

@@ -643,12 +643,13 @@ abstract class Association
      *   with this association
      * @return array
      */
-    public function transformRow($row, $nestKey, $joined)
+    public function transformRow($row, $nestKey, $joined, $targetProperty = null)
     {
         $sourceAlias = $this->source()->alias();
         $nestKey = $nestKey ?: $this->_name;
+        $targetProperty = $targetProperty ?: $this->property();
         if (isset($row[$sourceAlias])) {
-            $row[$sourceAlias][$this->property()] = $row[$nestKey];
+            $row[$sourceAlias][$targetProperty] = $row[$nestKey];
             unset($row[$nestKey]);
         }
 

+ 17 - 27
src/ORM/Association/BelongsToMany.php

@@ -411,20 +411,6 @@ class BelongsToMany extends Association
     }
 
     /**
-     * {@inheritDoc}
-     */
-    public function transformRow($row, $nestKey, $joined)
-    {
-        $alias = $this->junction()->alias();
-        if ($joined) {
-            $row[$this->target()->alias()][$this->_junctionProperty] = $row[$alias];
-            unset($row[$alias]);
-        }
-
-        return parent::transformRow($row, $nestKey, $joined);
-    }
-
-    /**
      * Get the relationship type.
      *
      * @return string
@@ -458,22 +444,15 @@ class BelongsToMany extends Association
     {
         $resultMap = [];
         $key = (array)$options['foreignKey'];
-        $property = $this->target()->association($this->junction()->alias())->property();
         $hydrated = $fetchQuery->hydrate();
 
         foreach ($fetchQuery->all() as $result) {
-            if (!isset($result[$property])) {
+            if (!isset($result[$this->_junctionProperty])) {
                 throw new RuntimeException(sprintf(
                     '"%s" is missing from the belongsToMany results. Results cannot be created.',
                     $property
                 ));
             }
-            $result[$this->_junctionProperty] = $result[$property];
-
-
-            if ($hydrated) {
-                $result->dirty($this->_junctionProperty, false);
-            }
 
             $values = [];
             foreach ($key as $k) {
@@ -966,7 +945,7 @@ class BelongsToMany extends Association
      * @param string|array $conditions The query conditions to use.
      * @return \Cake\ORM\Query The modified query.
      */
-    protected function _appendJunctionJoin($query, $conditions)
+    protected function _appendJunctionJoin($query, $conditions, $options = [])
     {
         $name = $this->_junctionAssociationName();
         $joins = $query->join();
@@ -982,7 +961,9 @@ class BelongsToMany extends Association
         $query
             ->addDefaultTypes($assoc->target())
             ->join($matching + $joins, [], true);
-        $query->eagerLoader()->addToJoinsMap($name, $assoc);
+
+        $targetProperty = empty($options['targetProperty']) ? null : $options['targetProperty'];
+        $query->eagerLoader()->addToJoinsMap($this->_name . '_Cjoin', $assoc, false, $targetProperty);
 
         return $query;
     }
@@ -1270,7 +1251,7 @@ class BelongsToMany extends Association
             $query = $queryBuilder($query);
         }
 
-        $query = $this->_appendJunctionJoin($query, []);
+        $query = $this->_appendJunctionJoin($query, [], ['targetProperty' => $this->_junctionProperty]);
 
         if ($query->autoFields() === null) {
             $query->autoFields($query->clause('select') === []);
@@ -1278,11 +1259,20 @@ class BelongsToMany extends Association
 
         // Ensure that association conditions are applied
         // and that the required keys are in the selected columns.
+
+        $tempName = $this->name();
+        $fields = $query->autoFields() ? $assoc->schema()->columns() : (array)$assoc->foreignKey();
+        $joinFields = [];
+        foreach ($fields as $f ) {
+            $joinFields[$tempName . '_Cjoin__' . $f] = "$name.$f";
+        }
+
+        $fields = array_combine(array_keys($joinFields), $fields);
         $query
             ->where($this->junctionConditions())
-            ->select($query->aliasFields((array)$assoc->foreignKey(), $name));
+            ->select($joinFields);
 
-        $assoc->attachTo($query);
+        $assoc->attachTo($query, ['aliasPath' => $assoc->alias(), 'includeFields' => false]);
         return $query;
     }
 

+ 21 - 1
src/ORM/EagerLoadable.php

@@ -86,6 +86,14 @@ class EagerLoadable
     protected $_forMatching;
 
     /**
+     * The property name where the association result should be nested
+     * in the result.
+     *
+     * @var string
+     */
+    protected $_targetProperty;
+
+    /**
      * Constructor. The $config parameter accepts the following array
      * keys:
      *
@@ -96,6 +104,7 @@ class EagerLoadable
      * - aliasPath
      * - propertyPath
      * - forMatching
+     * - targetProperty
      *
      * The keys maps to the settable properties in this class.
      *
@@ -107,7 +116,7 @@ class EagerLoadable
         $this->_name = $name;
         $allowed = [
             'associations', 'instance', 'config', 'canBeJoined',
-            'aliasPath', 'propertyPath', 'forMatching'
+            'aliasPath', 'propertyPath', 'forMatching', 'targetProperty'
         ];
         foreach ($allowed as $property) {
             if (isset($config[$property])) {
@@ -216,6 +225,17 @@ class EagerLoadable
     }
 
     /**
+     * The property name where the result of this association
+     * should be nested at the end.
+     *
+     * @return string
+     */
+    public function targetProperty()
+    {
+        return $this->_targetProperty;
+    }
+
+    /**
      * Returns a representation of this object that can be passed to
      * Cake\ORM\EagerLoader::contain()
      *

+ 6 - 3
src/ORM/EagerLoader.php

@@ -447,7 +447,8 @@ class EagerLoader
             'instance' => $instance,
             'config' => array_diff_key($options, $extra),
             'aliasPath' => trim($paths['aliasPath'], '.'),
-            'propertyPath' => trim($paths['propertyPath'], '.')
+            'propertyPath' => trim($paths['propertyPath'], '.'),
+            'targetProperty' => $instance->property()
         ];
         $config['canBeJoined'] = $instance->canBeJoined($config['config']);
         $eagerLoadable = new EagerLoadable($alias, $config);
@@ -631,7 +632,8 @@ class EagerLoader
                     'canBeJoined' => $canBeJoined,
                     'entityClass' => $instance->target()->entityClass(),
                     'nestKey' => $canBeJoined ? $assoc : $meta->aliasPath(),
-                    'matching' => $forMatching !== null ? $forMatching : $matching
+                    'matching' => $forMatching !== null ? $forMatching : $matching,
+                    'targetProperty' => $meta->targetProperty()
                 ];
                 if ($canBeJoined && $associations) {
                     $visitor($associations, $matching);
@@ -657,13 +659,14 @@ class EagerLoader
      * 'matching' association.
      * @return void
      */
-    public function addToJoinsMap($alias, Association $assoc, $asMatching = false)
+    public function addToJoinsMap($alias, Association $assoc, $asMatching = false, $targetProperty = null)
     {
         $this->_joinsMap[$alias] = new EagerLoadable($alias, [
             'aliasPath' => $alias,
             'instance' => $assoc,
             'canBeJoined' => true,
             'forMatching' => $asMatching,
+            'targetProperty' => $targetProperty ?: $assoc->property()
         ]);
     }
 

+ 7 - 5
src/ORM/ResultSet.php

@@ -380,12 +380,14 @@ class ResultSet implements ResultSetInterface
         $map = [];
         foreach ($query->clause('select') as $key => $field) {
             $key = trim($key, '"`[]');
-            if (strpos($key, '__') > 0) {
-                $parts = explode('__', $key, 2);
-                $map[$parts[0]][$key] = $parts[1];
-            } else {
+
+            if (strpos($key, '__') <= 0) {
                 $map[$this->_defaultAlias][$key] = $key;
+                continue;
             }
+
+            $parts = explode('__', $key, 2);
+            $map[$parts[0]][$key] = $parts[1];
         }
 
         foreach ($this->_matchingMap as $alias => $assoc) {
@@ -544,7 +546,7 @@ class ResultSet implements ResultSetInterface
                 $results[$alias] = $entity;
             }
 
-            $results = $instance->transformRow($results, $alias, $assoc['canBeJoined']);
+            $results = $instance->transformRow($results, $alias, $assoc['canBeJoined'], $assoc['targetProperty']);
         }
 
         foreach ($presentAliases as $alias => $present) {

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

@@ -1191,6 +1191,7 @@ class QueryRegressionTest extends TestCase
      */
     public function testBelongsToManyJoinDataAssociation()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Tags', 'SpecialTags');
         $articles = TableRegistry::get('Articles');
 
         $tags = TableRegistry::get('Tags');
@@ -1211,7 +1212,7 @@ class QueryRegressionTest extends TestCase
         $this->assertNotEmpty($result->tags, 'Missing tags');
         $this->assertNotEmpty($result->tags[0], 'Missing first tag');
         $this->assertNotEmpty($result->tags[0]->_joinData, 'Missing _joinData');
-        $this->assertNotEmpty($result->tags[0]->_joinData->author, 'Missing author on _joinData');
+        $this->assertNotEmpty($result->tags[0]->special_tags[0]->author, 'Missing author on _joinData');
     }
 
     /**