Browse Source

Ensure that reciprocal associations have conditions.

Without conditions the reciprocal belongs to many association will find
different records than the original association definition.

Refs #7994
Mark Story 10 years ago
parent
commit
8902ed0f0a

+ 4 - 1
src/ORM/Association/BelongsToMany.php

@@ -227,7 +227,8 @@ class BelongsToMany extends Association
                 'targetTable' => $source,
                 'foreignKey' => $this->targetForeignKey(),
                 'targetForeignKey' => $this->foreignKey(),
-                'through' => $junction
+                'through' => $junction,
+                'conditions' => $this->conditions(),
             ]);
         }
     }
@@ -322,6 +323,8 @@ class BelongsToMany extends Association
             $includeFields = $options['includeFields'];
         }
 
+        // TODO see if this can be removed and replaced with eagerly splitting
+        // up conditions when defining associations.
         $assoc = $this->_targetTable->association($junction->alias());
         $query->removeJoin($assoc->name());
 

+ 45 - 0
tests/TestCase/ORM/Association/BelongsToManyTest.php

@@ -915,6 +915,51 @@ class BelongsToManyTest extends TestCase
     }
 
     /**
+     * Test that the generated associations are correct.
+     *
+     * @return void
+     */
+    public function testGeneratedAssociations()
+    {
+        $articles = TableRegistry::get('Articles');
+        $tags = TableRegistry::get('Tags');
+        $conditions = ['SpecialTags.highlighted' => true];
+        $assoc = $articles->belongsToMany('Tags', [
+            'sourceTable' => $articles,
+            'targetTable' => $tags,
+            'foreignKey' => 'foreign_key',
+            'targetForeignKey' => 'target_foreign_key',
+            'through' => 'SpecialTags',
+            'conditions' => $conditions,
+        ]);
+        // Generate associations
+        $assoc->junction();
+
+        $tagAssoc = $articles->association('Tags');
+        $this->assertNotEmpty($tagAssoc, 'btm should exist');
+        $this->assertEquals($conditions, $tagAssoc->conditions());
+        $this->assertEquals('target_foreign_key', $tagAssoc->targetForeignKey());
+        $this->assertEquals('foreign_key', $tagAssoc->foreignKey());
+
+        $jointAssoc = $articles->association('SpecialTags');
+        $this->assertNotEmpty($jointAssoc, 'has many to junction should exist');
+        $this->assertInstanceOf('Cake\ORM\Association\HasMany', $jointAssoc);
+        $this->assertEquals('foreign_key', $jointAssoc->foreignKey());
+
+        $articleAssoc = $tags->association('Articles');
+        $this->assertNotEmpty($articleAssoc, 'reverse btm should exist');
+        $this->assertInstanceOf('Cake\ORM\Association\BelongsToMany', $articleAssoc);
+        $this->assertEquals($conditions, $articleAssoc->conditions());
+        $this->assertEquals('foreign_key', $articleAssoc->targetForeignKey(), 'keys should swap');
+        $this->assertEquals('target_foreign_key', $articleAssoc->foreignKey(), 'keys should swap');
+
+        $jointAssoc = $tags->association('SpecialTags');
+        $this->assertNotEmpty($jointAssoc, 'has many to junction should exist');
+        $this->assertInstanceOf('Cake\ORM\Association\HasMany', $jointAssoc);
+        $this->assertEquals('target_foreign_key', $jointAssoc->foreignKey());
+    }
+
+    /**
      * Tests that fetching belongsToMany association will not force
      * all fields being returned, but intead will honor the select() clause
      *