Skip to content

Commit

Permalink
Working towards supporting contain() on beforeFind for attachable
Browse files Browse the repository at this point in the history
associations
  • Loading branch information
lorenzo committed Feb 9, 2014
1 parent a8c6f99 commit 8db3d69
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 108 deletions.
21 changes: 13 additions & 8 deletions src/ORM/Association.php
Expand Up @@ -410,14 +410,14 @@ public function attachTo(Query $query, array $options = []) {

$options['conditions'] = $query->newExpr()->add($options['conditions']);
$extraOptions = [];
$dummy = $target->query();

if (!empty($options['queryBuilder'])) {
$newQuery = $options['queryBuilder']($target->query());
$options['fields'] = $newQuery->clause('select') ?: $options['fields'];
$options['conditions']->add($newQuery->clause('where') ?: []);
$extraOptions = $newQuery->getOptions();
$dummy = $options['queryBuilder']($dummy);
}

$this->_dispatchBeforeFind($dummy);
$options = $this->_copyAttributes($dummy, $options);
$joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1];
$query->join([$target->alias() => array_intersect_key($options, $joinOptions)]);

Expand All @@ -431,8 +431,6 @@ public function attachTo(Query $query, array $options = []) {
if (!empty($options['fields'])) {
$query->select($query->aliasFields($options['fields'], $target->alias()));
}

$this->_dispatchBeforeFind($query, $extraOptions);
}

/**
Expand Down Expand Up @@ -482,15 +480,22 @@ public function find($type = 'all', $options = []) {
* attaching to
*
* @param \Cake\ORM\Query $query the query this association is attaching itself to
* @param array $options extra options to passed to the association
* @return void
*/
protected function _dispatchBeforeFind($query, $options) {
protected function _dispatchBeforeFind($query) {
$table = $this->target();
$options = $query->getOptions();
$event = new Event('Model.beforeFind', $table, [$query, $options, false]);
$table->getEventManager()->dispatch($event);
}

protected function _copyAttributes($query, $options) {
debug($query->contain());
$options['fields'] = $query->clause('select') ?: $options['fields'];
$options['conditions']->add($query->clause('where') ?: []);
return $options;
}

/**
* Returns a single or multiple condition(s) to be appended to the generated join
* clause for getting the results on the target table. If false is returned then
Expand Down
126 changes: 26 additions & 100 deletions tests/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -60,6 +60,16 @@ public function setUp() {
]
]);
TableRegistry::set('Articles', $this->article);
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['article_id', 'tag_id']]
]
]
]);
}

/**
Expand Down Expand Up @@ -210,16 +220,6 @@ public function testAttachTo() {
'targetTable' => $this->tag,
'conditions' => ['Tags.name' => 'cake']
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['article_id', 'tag_id']]
]
]
]);
$association = new BelongsToMany('Tags', $config);
$query->expects($this->at(0))->method('join')->with([
'Tags' => [
Expand Down Expand Up @@ -267,13 +267,6 @@ public function testAttachToNoFields() {
'targetTable' => $this->tag,
'conditions' => ['Tags.name' => 'cake']
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$query->expects($this->at(0))->method('join')->with([
'Tags' => [
Expand Down Expand Up @@ -315,13 +308,6 @@ public function testAttachToWithQueryBuilder() {
'targetTable' => $this->tag,
'conditions' => ['Tags.name' => 'cake']
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$query->expects($this->at(0))->method('join')->with([
'Tags' => [
Expand Down Expand Up @@ -419,13 +405,6 @@ public function testEagerLoader() {
'sourceTable' => $this->article,
'targetTable' => $this->tag,
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$keys = [1, 2, 3, 4];
$query = $this->getMock('Cake\ORM\Query', ['all', 'matching'], [null, null]);
Expand Down Expand Up @@ -486,13 +465,6 @@ public function testEagerLoaderWithDefaults() {
'conditions' => ['Tags.name' => 'foo'],
'sort' => ['id' => 'ASC'],
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$keys = [1, 2, 3, 4];
$methods = ['all', 'matching', 'where', 'order'];
Expand Down Expand Up @@ -550,13 +522,6 @@ public function testEagerLoaderWithOverrides() {
'conditions' => ['Tags.name' => 'foo'],
'sort' => ['id' => 'ASC'],
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$keys = [1, 2, 3, 4];
$methods = ['all', 'matching', 'where', 'order', 'select'];
Expand Down Expand Up @@ -627,13 +592,6 @@ public function testEagerLoaderFieldsException() {
'conditions' => ['Tags.name' => 'foo'],
'sort' => ['id' => 'ASC'],
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$keys = [1, 2, 3, 4];
$methods = ['all', 'contain', 'where', 'order', 'select'];
Expand Down Expand Up @@ -665,16 +623,6 @@ public function testEagerLoaderSubquery() {
'conditions' => ['Tags.name' => 'foo'],
'sort' => ['id' => 'ASC'],
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'_constraints' => [
'PK' => ['type' => 'primary', 'columns' => ['article_id', 'tag_id']]
]
]
]);
$association = new BelongsToMany('Tags', $config);
$parent = (new Query(null, $this->article))
->join(['foo' => ['table' => 'foo', 'type' => 'inner', 'conditions' => []]])
Expand Down Expand Up @@ -760,13 +708,6 @@ public function testEagerLoaderWithQueryBuilder() {
'sourceTable' => $this->article,
'targetTable' => $this->tag,
];
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer']
]
]);
$association = new BelongsToMany('Tags', $config);
$keys = [1, 2, 3, 4];
$query = $this->getMock(
Expand Down Expand Up @@ -833,13 +774,12 @@ public function testEagerLoaderMultipleKeys() {
];
$this->article->primaryKey(['id', 'site_id']);
$this->tag->primaryKey(['id', 'site_id']);
TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'site_id' => ['type' => 'integer'],
]

$table= TableRegistry::get('ArticlesTags');
$table->schema([
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'site_id' => ['type' => 'integer'],
]);
$association = new BelongsToMany('Tags', $config);
$keys = [[1, 10], [2, 20], [3, 30], [4, 40]];
Expand Down Expand Up @@ -1535,26 +1475,19 @@ public function testAttachToBeforeFind() {
'sourceTable' => $this->article,
'targetTable' => $this->tag,
];
$table = TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['article_id', 'tag_id']]
]
]
]);
$table = TableRegistry::get('ArticlesTags');
$association = new BelongsToMany('Tags', $config);
$listener = $this->getMock('stdClass', ['__invoke']);
$this->tag->getEventManager()->attach($listener, 'Model.beforeFind');
$newQuery = $this->tag->query();
$listener->expects($this->once())->method('__invoke')
->with($this->isInstanceOf('\Cake\Event\Event'), $query, [], false);
->with($this->isInstanceOf('\Cake\Event\Event'), $newQuery, [], false);

$listener2 = $this->getMock('stdClass', ['__invoke']);
$table->getEventManager()->attach($listener2, 'Model.beforeFind');
$newQuery2 = $table->query();
$listener2->expects($this->once())->method('__invoke')
->with($this->isInstanceOf('\Cake\Event\Event'), $query, [], false);
->with($this->isInstanceOf('\Cake\Event\Event'), $newQuery2, [], false);

$association->attachTo($query);
}
Expand All @@ -1571,27 +1504,20 @@ public function testAttachToBeforeFindExtraOptions() {
'sourceTable' => $this->article,
'targetTable' => $this->tag,
];
$table = TableRegistry::get('ArticlesTags', [
'table' => 'articles_tags',
'schema' => [
'article_id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['article_id', 'tag_id']]
]
]
]);
$table = TableRegistry::get('ArticlesTags');
$association = new BelongsToMany('Tags', $config);
$listener = $this->getMock('stdClass', ['__invoke']);
$this->tag->getEventManager()->attach($listener, 'Model.beforeFind');
$opts = ['somthing' => 'more'];
$newQuery = $this->tag->query()->applyOptions($opts);
$listener->expects($this->once())->method('__invoke')
->with($this->isInstanceOf('\Cake\Event\Event'), $query, $opts, false);
->with($this->isInstanceOf('\Cake\Event\Event'), $newQuery, $opts, false);

$listener2 = $this->getMock('stdClass', ['__invoke']);
$table->getEventManager()->attach($listener2, 'Model.beforeFind');
$newQuery2 = $table->query();
$listener2->expects($this->once())->method('__invoke')
->with($this->isInstanceOf('\Cake\Event\Event'), $query, [], false);
->with($this->isInstanceOf('\Cake\Event\Event'), $newQuery2, [], false);

$association->attachTo($query, ['queryBuilder' => function($q) {
return $q->applyOptions(['somthing' => 'more']);
Expand Down

0 comments on commit 8db3d69

Please sign in to comment.