Skip to content

Commit

Permalink
Contain the junction table when proxying finders.
Browse files Browse the repository at this point in the history
When proxying finder methods from a belongstomany association, if that
association has conditions we should contain the junction table as the
conditions very likely use columns on that table.

Refs #7707
  • Loading branch information
markstory committed Dec 3, 2015
1 parent 24718ff commit 88af5c2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/ORM/Association/BelongsToMany.php
Expand Up @@ -771,6 +771,29 @@ function () use ($sourceEntity, $targetEntities, $options) {
$sourceEntity->dirty($property, false);
}

/**
* Proxies the finding operation to the target table's find method
* and modifies the query accordingly based of this association
* configuration.
*
* If your association includes conditions, the junction table will be
* included in the query's contained associations.
*
* @param string|array $type the type of query to perform, if an array is passed,
* it will be interpreted as the `$options` parameter
* @param array $options The options to for the find
* @see \Cake\ORM\Table::find()
* @return \Cake\ORM\Query
*/
public function find($type = null, array $options = [])
{
$query = parent::find($type, $options);
if ($this->conditions()) {
$query->contain([$this->junction()->alias()]);
}
return $query;
}

/**
* Replaces existing association links between the source entity and the target
* with the ones passed. This method does a smart cleanup, links that are already
Expand Down
29 changes: 29 additions & 0 deletions tests/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -854,6 +854,35 @@ public function testReplaceLinkSuccess()
$this->assertFalse($entity->dirty('tags'));
}

/**
* Test that find() applies a contain() when the association uses conditions.
*
* @return void
*/
public function testFindAppliesContainWithConditions()
{
$connection = ConnectionManager::get('test');
$this->article->belongsToMany('Tags', [
'targetTable' => $this->tag,
'conditions' => ['ArticlesTags.favorite' => true]
]);
$query = $this->getMock(
'\Cake\ORM\Query',
[],
[$connection, $this->article]
);
$query->expects($this->once())
->method('where')
->with(['ArticlesTags.favorite' => true])
->will($this->returnSelf());
$query->expects($this->once())
->method('contain')
->with(['ArticlesTags'])
->will($this->returnSelf());
$this->tag->method('find')->will($this->returnValue($query));

$this->article->Tags->find();
}

/**
* Tests that replaceLinks() will contain() the target table when
Expand Down

0 comments on commit 88af5c2

Please sign in to comment.