Skip to content

Commit

Permalink
Merge pull request #7930 from cakephp/fix-7913
Browse files Browse the repository at this point in the history
Avoiding forced all fields in a contained belongsToMany, fixes #7913
  • Loading branch information
markstory committed Dec 31, 2015
2 parents d848af8 + b80777d commit 30ea3a5
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Expand Up @@ -20,6 +20,11 @@ services:
- memcached
- redis-server

cache:
directories:
- vendor
- $HOME/.composer/cache

matrix:
fast_finish: true

Expand All @@ -42,7 +47,9 @@ matrix:
- php: hhvm

before_script:
- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
- composer self-update
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
- composer install --prefer-dist --no-interaction

- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi"
Expand Down
4 changes: 4 additions & 0 deletions appveyor.yml
Expand Up @@ -3,6 +3,10 @@ shallow_clone: false
platform: 'x86'
clone_folder: c:\projects\cakephp

cache:
- '%LOCALAPPDATA%\Composer'
- '%APPDATA%\Composer'

branches:
only:
- master
Expand Down
16 changes: 14 additions & 2 deletions src/ORM/Association/BelongsToMany.php
Expand Up @@ -443,7 +443,7 @@ public function cascadeDelete(EntityInterface $entity, array $options = [])
$table = $this->junction();
$hasMany = $this->source()->association($table->alias());
if ($this->_cascadeCallbacks) {
foreach ($hasMany->find('all')->where($conditions) as $related) {
foreach ($hasMany->find('all')->where($conditions)->toList() as $related) {
$table->delete($related, $options);
}
return true;
Expand Down Expand Up @@ -1095,11 +1095,23 @@ protected function _collectJointEntities($sourceEntity, $targetEntities)
protected function _buildQuery($options)
{
$name = $this->_junctionAssociationName();
$assoc = $this->target()->association($name);
$queryBuilder = false;

if (!empty($options['queryBuilder'])) {
$queryBuilder = $options['queryBuilder'];
unset($options['queryBuilder']);
}

$query = $this->_buildBaseQuery($options);
$query->addDefaultTypes($assoc->target());

if ($queryBuilder) {
$query = $queryBuilder($query);
}

$keys = $this->_linkField($options);
$query = $this->_appendJunctionJoin($query, $keys);
$assoc = $this->target()->association($name);

$query->autoFields($query->clause('select') === [])
->select($query->aliasFields((array)$assoc->foreignKey(), $name));
Expand Down
3 changes: 1 addition & 2 deletions src/ORM/Association/DependentDeleteTrait.php
Expand Up @@ -44,8 +44,7 @@ public function cascadeDelete(EntityInterface $entity, array $options = [])
$conditions = array_combine($foreignKey, $entity->extract($bindingKey));

if ($this->_cascadeCallbacks) {
$query = $this->find('all')->where($conditions);
foreach ($query as $related) {
foreach ($this->find()->where($conditions)->toList() as $related) {
$table->delete($related, $options);
}
return true;
Expand Down
11 changes: 1 addition & 10 deletions src/ORM/Association/SelectableAssociationTrait.php
Expand Up @@ -43,16 +43,7 @@ public function requiresKeys(array $options = [])
public function eagerLoader(array $options)
{
$options += $this->_defaultOptions();
$queryBuilder = false;
if (!empty($options['queryBuilder'])) {
$queryBuilder = $options['queryBuilder'];
unset($options['queryBuilder']);
}

$fetchQuery = $this->_buildQuery($options);
if ($queryBuilder) {
$fetchQuery = $queryBuilder($fetchQuery);
}
$resultMap = $this->_buildResultMap($fetchQuery, $options);
return $this->_resultInjector($fetchQuery, $resultMap, $options);
}
Expand Down Expand Up @@ -123,7 +114,7 @@ protected function _buildQuery($options)
}

if (!empty($options['queryBuilder'])) {
$options['queryBuilder']($fetchQuery);
$fetchQuery = $options['queryBuilder']($fetchQuery);
}

return $fetchQuery;
Expand Down
Expand Up @@ -964,6 +964,8 @@ public function testPaginateQuery()
*/
public function testPaginateQueryWithBindValue()
{
$config = ConnectionManager::config('test');
$this->skipIf(strpos($config['driver'], 'Sqlserver') !== false, 'Test temporarily broken in SQLServer');
$this->loadFixtures('Posts');
$table = TableRegistry::get('PaginatorPosts');
$query = $table->find()
Expand Down
11 changes: 0 additions & 11 deletions tests/TestCase/Database/QueryTest.php
Expand Up @@ -336,17 +336,6 @@ public function testSelectInnerJoin()
->innerJoin(['c' => 'comments'], ['created <' => $time], $types)
->execute();
$this->assertCount(0, $result->fetchAll());

$query = new Query($this->connection);
$result = $query
->select(['title', 'name' => 'c.comment'])
->from('articles')
->leftJoin(['c' => 'comments'], ['created >' => $time], $types)
->execute();
$this->assertEquals(
['title' => 'First Article', 'name' => 'Second Comment for First Article'],
$result->fetch('assoc')
);
}

/**
Expand Down
22 changes: 22 additions & 0 deletions tests/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -913,4 +913,26 @@ public function testPropertyNoPlugin()
$association = new BelongsToMany('Contacts.Tags', $config);
$this->assertEquals('tags', $association->property());
}

/**
* Tests that fetching belongsToMany association will not force
* all fields being returned, but intead will honor the select() clause
*
* @see https://github.com/cakephp/cakephp/issues/7916
* @return void
*/
public function testEagerLoadingBelongsToManyLimitedFields()
{
$table = TableRegistry::get('Articles');
$table->belongsToMany('Tags');
$result = $table
->find()
->contain(['Tags' => function ($q) {
return $q->select(['id']);
}])
->first();

$this->assertNotEmpty($result->tags[0]->id);
$this->assertEmpty($result->tags[0]->name);
}
}

0 comments on commit 30ea3a5

Please sign in to comment.