Skip to content
Permalink
Browse files

Allow associations inline with contain specify their own finder methods

  • Loading branch information...
Patrick Conroy
Patrick Conroy committed Sep 5, 2014
1 parent a2b1d4a commit 58c1f5238de3805cd8488e8d8c429c0ce2bf55dc
@@ -445,7 +445,8 @@ public function attachTo(Query $query, array $options = []) {
'conditions' => [],
'fields' => [],
'type' => empty($options['matching']) ? $this->joinType() : 'INNER',
'table' => $target->table()
'table' => $target->table(),
'finder' => null
];
if (!empty($options['foreignKey'])) {
@@ -455,7 +456,7 @@ public function attachTo(Query $query, array $options = []) {
}
}
$dummy = $this->find()->eagerLoaded(true);
$dummy = $this->find($options['finder'])->eagerLoaded(true);
if (!empty($options['queryBuilder'])) {
$dummy = $options['queryBuilder']($dummy);
if (!($dummy instanceof Query)) {
@@ -86,7 +86,7 @@ protected function _buildQuery($options) {
}
$fetchQuery = $this
->find('all')
->find(isset($options['finder']) ? $options['finder'] : 'all')
->where($options['conditions'])
->eagerLoaded(true)
->hydrate($options['query']->hydrate());
@@ -57,7 +57,8 @@ class EagerLoader {
'fields' => 1,
'sort' => 1,
'matching' => 1,
'queryBuilder' => 1
'queryBuilder' => 1,
'finder' => 1
];
/**
@@ -1440,6 +1440,9 @@ protected function _processDelete($entity, $options) {
* @throws \BadMethodCallException
*/
public function callFinder($type, Query $query, array $options = []) {
if (is_array($type)) {
list($type, $options) = $this->_inferFinderTypeAndOptions($type, $options);
}
$query->applyOptions($options);
$options = $query->getOptions();
$finder = 'find' . ucfirst($type);
@@ -1934,4 +1937,32 @@ public function __debugInfo() {
];
}
/**
* Helper method to infer the requested finder and its options.
*
* Returns the inferred options from the finder $type.
*
* @return array
*/
protected function _inferFinderTypeAndOptions(array $type) {
$options = [];
if (count($type)) {
$v = array_values($type)[0];
$k = array_keys($type)[0];
if (is_array($v)) {
$type = $k;
$options = $v;
} elseif (is_string($v) && !$k) {
$type = $v;
} elseif (is_string($v)) {
$type = $k;
$options = [$v];
}
}
return [
$type,
$options
];
}
}
@@ -150,13 +150,12 @@ public function testPaginateCustomFinderOptions() {
$this->loadFixtures('Post');
$settings = [
'PaginatorPosts' => [
'finder' => 'author',
'author_id' => 1
'finder' => ['author' => ['author_id' => 1]]
]
];
$table = TableRegistry::get('PaginatorPosts');
$expected = $table->find('author', ['conditions' => ['PaginatorPosts.author_id' => $settings['PaginatorPosts']['author_id']]])
$expected = $table->find('author', ['conditions' => ['PaginatorPosts.author_id' => $settings['PaginatorPosts']['finder']['author']['author_id']]])
->count();
$result = $this->Paginator->paginate($table, $settings)->count();
@@ -2111,4 +2111,37 @@ public function testCleanCopy() {
$this->assertNull($copy->clause('order'));
}
/**
* Test that finder options sent through via contain are sent to custom finder.
*
* @return void
*/
public function testContainFinderCanSpecifyOptions() {
$table = TableRegistry::get('Articles');
$table->belongsTo(
'Authors',
['className' => 'TestApp\Model\Table\AuthorsTable']
);
$authorId = 1;
$resultWithoutAuthor = $table->find('all')
->where(['Articles.author_id' => $authorId])
->contain([
'Authors' => [
'finder' => ['byAuthor' => ['author_id' => 2]]
]
]);
$resultWithAuthor = $table->find('all')
->where(['Articles.author_id' => $authorId])
->contain([
'Authors' => [
'finder' => ['byAuthor' => ['author_id' => $authorId]]
]
]);
$this->assertEmpty($resultWithoutAuthor->first()['author']);
$this->assertEquals($authorId, $resultWithAuthor->first()['author']['id']);
}
}
@@ -12,6 +12,7 @@
namespace TestApp\Model\Table;
use Cake\ORM\Table;
use Cake\ORM\Query;
/**
* Author table class
@@ -23,4 +24,11 @@ public function initialize(array $config) {
$this->hasMany('articles');
}
public function findByAuthor(Query $query, array $options = []) {
if (isset($options['author_id'])) {
$query->where(['Articles.id' => $options['author_id']]);
}
return $query;
}
}

0 comments on commit 58c1f52

Please sign in to comment.
You can’t perform that action at this time.