Skip to content

Commit

Permalink
Ensure that reciprocal associations have conditions.
Browse files Browse the repository at this point in the history
Without conditions the reciprocal belongs to many association will find
different records than the original association definition.

Refs #7994
  • Loading branch information
markstory committed Jan 10, 2016
1 parent c3a0355 commit 8902ed0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/ORM/Association/BelongsToMany.php
Expand Up @@ -227,7 +227,8 @@ protected function _generateTargetAssociations($junction, $source, $target)
'targetTable' => $source,
'foreignKey' => $this->targetForeignKey(),
'targetForeignKey' => $this->foreignKey(),
'through' => $junction
'through' => $junction,
'conditions' => $this->conditions(),
]);
}
}
Expand Down Expand Up @@ -322,6 +323,8 @@ public function attachTo(Query $query, array $options = [])
$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());

Expand Down
45 changes: 45 additions & 0 deletions tests/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -914,6 +914,51 @@ public function testPropertyNoPlugin()
$this->assertEquals('tags', $association->property());
}

/**
* 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
Expand Down

0 comments on commit 8902ed0

Please sign in to comment.