Skip to content
Permalink
Browse files

Fix BelongsToMany saving incorrectly when _joinData is used.

When the `_joinData` has not been fully marshalled, BelongsToMany
associations will not save the joinData correctly. This can cause data
to go 'missing' when associations with conditions are involved.

Refs #7808
  • Loading branch information...
markstory committed Jan 7, 2016
1 parent 5a9ba35 commit b5a906817c2131d2e703adcecaa0022539c712f6
Showing with 36 additions and 2 deletions.
  1. +4 −2 src/ORM/Association/BelongsToMany.php
  2. +32 −0 tests/TestCase/ORM/Association/BelongsToManyTest.php
@@ -622,11 +622,13 @@ protected function _saveLinks(EntityInterface $sourceEntity, $targetEntities, $o
$junctionAlias = $junction->alias();
foreach ($targetEntities as $e) {
$joint = $e->get($jointProperty);
$joint = $jointVal = $e->get($jointProperty);
if (!$joint || !($joint instanceof EntityInterface)) {
$joint = new $entityClass([], ['markNew' => true, 'source' => $junctionAlias]);
if (is_array($jointVal)) {
$joint->set($jointVal);
}
}
$sourceKeys = array_combine($foreignKey, $sourceEntity->extract($bindingKey));
$targetKeys = array_combine($assocForeignKey, $e->extract($targetPrimaryKey));
@@ -656,6 +656,38 @@ public function testReplaceLinkWithConditions()
$this->assertSame(1, $jointCount, 'Non matching joint record should remain.');
}
/**
* Tests that replaceLinks will apply _joinData when it has not been converted
* to an entity if that data is an array.
*
* @return void
*/
public function testReplaceLinkJoinDataHandling()
{
$joint = TableRegistry::get('SpecialTags');
$articles = TableRegistry::get('Articles');
$assoc = $articles->belongsToMany('Tags', [
'through' => 'SpecialTags',
'conditions' => ['SpecialTags.highlighted' => true]
]);
$id = 2;
$entity = $articles->get($id, ['contain' => 'Tags']);
// New tag
$tagData = [
new Entity(['id' => 2, '_joinData' => ['highlighted' => true]]),
];
$assoc->replaceLinks($entity, $tagData);
$this->assertSame($tagData, $entity->tags, 'Tags should match replaced objects');
$this->assertFalse($entity->dirty('tags'), 'Should be clean');
$jointRecords = $joint->find()->where(['article_id' => $id])->toArray();
$this->assertCount(1, $jointRecords);
$this->assertTrue($jointRecords[0]->highlighted, 'joinData should be set.');
}
/**
* Provider for empty values
*

0 comments on commit b5a9068

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.