Skip to content
Permalink
Browse files

Use association conditions when replacing belongToMany links.

This is necessary especially for polymorphic belongsToMany to ensure links for
other models are not deleted.
  • Loading branch information...
ADmad committed Jun 27, 2015
1 parent d658891 commit d245beaa65838a976e1324e217dfb97c6c81a8a8
@@ -733,6 +733,11 @@ function () use ($sourceEntity, $targetEntities, $primaryValue, $options) {
$existing = $hasMany->find('all')
->where(array_combine($foreignKey, $primaryValue));
$associationConditions = $this->conditions();
if ($associationConditions) {
$existing->andWhere($associationConditions);
}
$jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
$inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities);
@@ -0,0 +1,52 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.8
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Test\Fixture;
use Cake\TestSuite\Fixture\TestFixture;
class PolymorphicTaggedFixture extends TestFixture
{
/**
* table property
*
* @var string
*/
public $table = 'polymorphic_tagged';
/**
* fields property
*
* @var array
*/
public $fields = [
'id' => ['type' => 'integer'],
'tag_id' => ['type' => 'integer'],
'foreign_key' => ['type' => 'integer'],
'foreign_model' => ['type' => 'string'],
'position' => ['type' => 'integer', 'null' => true],
'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]]
];
/**
* records property
*
* @var array
*/
public $records = [
['tag_id' => 1, 'foreign_key' => 1, 'foreign_model' => 'Posts', 'position' => 1],
['tag_id' => 1, 'foreign_key' => 1, 'foreign_model' => 'Articles', 'position' => 1],
];
}
@@ -59,6 +59,7 @@ class TableTest extends TestCase
'core.members',
'core.groups',
'core.groups_members',
'core.polymorphic_tagged',
];
/**
@@ -3286,6 +3287,80 @@ public function testSaveBelongsToManyJoinData()
$this->assertSame($result, $article);
}
/**
* Test to check that association condition are used when fetching existing
* records to decide which records to unlink.
*
* @return void
*/
public function testPolymorphicBelongsToManySave()
{
$articles = TableRegistry::get('Articles');
$articles->belongsToMany('Tags', [
'through' => 'PolymorphicTagged',
'foreignKey' => 'foreign_key',
'conditions' => [
'PolymorphicTagged.foreign_model' => 'Articles'
],
'sort' => ['PolymorphicTagged.position' => 'ASC']
]);
$articles->Tags->junction()->belongsTo('Tags');
$entity = $articles->get(1, ['contain' => ['Tags']]);
$data = [
'id' => 1,
'tags' => [
[
'id' => 1,
'_joinData' => [
'id' => 2,
'foreign_model' => 'Articles',
'position' => 2
]
],
[
'id' => 2,
'_joinData' => [
'foreign_model' => 'Articles',
'position' => 1
]
]
]
];
$entity = $articles->patchEntity($entity, $data, ['associated' => ['Tags._joinData']]);
$entity = $articles->save($entity);
$expected = [
[
'id' => 1,
'tag_id' => 1,
'foreign_key' => 1,
'foreign_model' => 'Posts',
'position' => 1
],
[
'id' => 2,
'tag_id' => 1,
'foreign_key' => 1,
'foreign_model' => 'Articles',
'position' => 2
],
[
'id' => 3,
'tag_id' => 2,
'foreign_key' => 1,
'foreign_model' => 'Articles',
'position' => 1
]
];
$result = TableRegistry::get('PolymorphicTagged')
->find('all', ['sort' => ['id' => 'DESC']])
->hydrate(false)
->toArray();
$this->assertEquals($expected, $result);
}
/**
* Tests saving belongsToMany records can delete all links.
*

0 comments on commit d245bea

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