Permalink
Browse files

Working towards supporting contain() on beforeFind for attachable

associations
  • Loading branch information...
1 parent a8c6f99 commit 8db3d690ab1b7399b112757816833f4239e0a78b @lorenzo lorenzo committed Feb 2, 2014
Showing with 39 additions and 108 deletions.
  1. +13 −8 src/ORM/Association.php
  2. +26 −100 tests/TestCase/ORM/Association/BelongsToManyTest.php
View
@@ -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)]);
@@ -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);
}
/**
@@ -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
@@ -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']]
+ ]
+ ]
+ ]);
}
/**
@@ -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' => [
@@ -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' => [
@@ -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' => [
@@ -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]);
@@ -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'];
@@ -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'];
@@ -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'];
@@ -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' => []]])
@@ -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(
@@ -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]];
@@ -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);
}
@@ -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']);

0 comments on commit 8db3d69

Please sign in to comment.