Skip to content

Commit

Permalink
Added second signature for contain that matches the signature for mat…
Browse files Browse the repository at this point in the history
…ching
  • Loading branch information
jeremyharris committed May 15, 2017
1 parent 0c5c24c commit c0764c8
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
11 changes: 10 additions & 1 deletion src/ORM/EagerLoader.php
Expand Up @@ -126,14 +126,23 @@ class EagerLoader
* @param array|string $associations list of table aliases to be queried.
* When this method is called multiple times it will merge previous list with
* the new one.
* @param callable|null $queryBuilder The query builder callable
* @return array Containments.
*/
public function contain($associations = [])
public function contain($associations = [], callable $queryBuilder = null)
{
if (empty($associations)) {
return $this->_containments;
}

if ($queryBuilder) {
$associations = [
$associations => [
'queryBuilder' => $queryBuilder
]
];
}

$associations = (array)$associations;
$associations = $this->_reformatContain($associations, $this->_containments);
$this->_normalized = null;
Expand Down
22 changes: 18 additions & 4 deletions src/ORM/Query.php
Expand Up @@ -352,14 +352,21 @@ public function eagerLoader(EagerLoader $instance = null)
* Failing to do so will trigger exceptions.
*
* ```
* // Use special join conditions for getting an Articles's belongsTo 'authors'
* // Use a query builder to add conditions to the containment
* $query->contain('Authors', function ($q) {
* return $q->where(...); // add conditions
* });
* // Use special join conditions for multiple containments in the same method call
* $query->contain([
* 'Authors' => [
* 'foreignKey' => false,
* 'queryBuilder' => function ($q) {
* return $q->where(...); // Add full filtering conditions
* }
* ]
* ],
* 'Tags' => function ($q) {
* return $q->where(...); // add conditions
* }
* ]);
* ```
*
Expand All @@ -371,7 +378,9 @@ public function eagerLoader(EagerLoader $instance = null)
* previous list will be emptied.
*
* @param array|string|null $associations List of table aliases to be queried.
* @param bool $override Whether override previous list with the one passed
* @param callable|bool $override The query builder for the association, or
* if associations is an array, a bool on whether to override previous list
* with the one passed
* defaults to merging previous list with the new one.
* @return array|$this
*/
Expand All @@ -386,7 +395,12 @@ public function contain($associations = null, $override = false)
return $loader->contain();
}

$result = $loader->contain($associations);
$queryBuilder = null;
if (is_callable($override)) {
$queryBuilder = $override;
}

$result = $loader->contain($associations, $queryBuilder);
$this->_addAssociationsToTypeMap($this->repository(), $this->getTypeMap(), $result);

return $this;
Expand Down
20 changes: 20 additions & 0 deletions tests/TestCase/ORM/EagerLoaderTest.php
Expand Up @@ -332,6 +332,26 @@ public function testContainClosure()
$this->assertEquals($expected, $loader->contain());
}

/**
* Tests using the same signature as matching with contain
*
* @return void
*/
public function testContainSecondSignature()
{
$builder = function ($query) {
};
$loader = new EagerLoader;
$loader->contain('clients', $builder);

$expected = [
'clients' => [
'queryBuilder' => $builder
]
];
$this->assertEquals($expected, $loader->contain());
}

/**
* Tests that query builders are stacked
*
Expand Down
26 changes: 26 additions & 0 deletions tests/TestCase/ORM/QueryTest.php
Expand Up @@ -2018,6 +2018,32 @@ public function testContainWithClosure()
$this->assertEquals([1], array_unique($ids));
}

/**
* Integration test that uses the contain signature that is the same as the
* matching signature
*
* @return void
*/
public function testContainSecondSignature()
{
$table = TableRegistry::get('authors');
$table->hasMany('articles');
$query = new Query($this->connection, $table);
$query
->select()
->contain('articles', function ($q) {
return $q->where(['articles.id' => 1]);
});

$ids = [];
foreach ($query as $entity) {
foreach ((array)$entity->articles as $article) {
$ids[] = $article->id;
}
}
$this->assertEquals([1], array_unique($ids));
}

/**
* Integration test to ensure that filtering associations with the queryBuilder
* option works.
Expand Down

0 comments on commit c0764c8

Please sign in to comment.