Skip to content
Permalink
Browse files

Don't treat replaceLinks() as working when new entities fail to save.

When persisting new linked entities, we should not treat the operation
as successful if persisting a new linked entity fails.

Refs #9109
  • Loading branch information...
markstory committed Jul 17, 2016
1 parent 0f0e3dd commit 10d69fff2958f9c6a3f662a21b9ae862618993e1
Showing with 46 additions and 4 deletions.
  1. +6 −2 src/ORM/Association/BelongsToMany.php
  2. +40 −2 tests/TestCase/ORM/Association/BelongsToManyTest.php
@@ -606,15 +606,19 @@ protected function _saveTarget(EntityInterface $parentEntity, $entities, $option
$entity = clone $entity;
}
if ($table->save($entity, $options)) {
$saved = $table->save($entity, $options);
if ($saved) {
$entities[$k] = $entity;
$persisted[] = $entity;
continue;
}
// Saving the new linked entity failed, copy errors back into the
// original entity if applicable and abort.
if (!empty($options['atomic'])) {
$original[$k]->errors($entity->errors());
}
if (!$saved) {
return false;
}
}
@@ -635,7 +635,8 @@ public function testReplaceLinkSuccess()
new Entity(['name' => 'net new']),
];
$assoc->replaceLinks($entity, $tagData, ['associated' => false]);
$result = $assoc->replaceLinks($entity, $tagData, ['associated' => false]);
$this->assertTrue($result);
$this->assertSame($tagData, $entity->tags, 'Tags should match replaced objects');
$this->assertFalse($entity->dirty('tags'), 'Should be clean');
@@ -669,7 +670,8 @@ public function testReplaceLinkWithConditions()
]);
$entity = $articles->get(1, ['contain' => 'Tags']);
$assoc->replaceLinks($entity, [], ['associated' => false]);
$result = $assoc->replaceLinks($entity, [], ['associated' => false]);
$this->assertTrue($result);
$this->assertSame([], $entity->tags, 'Tags should match replaced objects');
$this->assertFalse($entity->dirty('tags'), 'Should be clean');
@@ -680,6 +682,42 @@ public function testReplaceLinkWithConditions()
$this->assertSame(1, $jointCount, 'Non matching joint record should remain.');
}
/**
* Tests replaceLinks with failing domain rules and new link targets.
*
* @return void
*/
public function testReplaceLinkFailingDomainRules()
{
$articles = TableRegistry::get('Articles');
$tags = TableRegistry::get('Tags');
$tags->eventManager()->on('Model.buildRules', function ($event, $rules) {
$rules->add(function () {
return false;
}, 'rule', ['errorField' => 'name', 'message' => 'Bad data']);
});
$assoc = $articles->belongsToMany('Tags', [
'sourceTable' => $articles,
'targetTable' => $tags,
'through' => TableRegistry::get('ArticlesTags'),
'joinTable' => 'articles_tags',
]);
$entity = $articles->get(1, ['contain' => 'Tags']);
$originalCount = count($entity->tags);
$tags = [
new Entity(['name' => 'tag99', 'description' => 'Best tag'])
];
$result = $assoc->replaceLinks($entity, $tags);
$this->assertFalse($result, 'replace should have failed.');
$this->assertNotEmpty($tags[0]->errors(), 'Bad entity should have errors.');
$entity = $articles->get(1, ['contain' => 'Tags']);
$this->assertCount($originalCount, $entity->tags, 'Should not have changed.');
$this->assertEquals('tag1', $entity->tags[0]->name);
}
/**
* Provider for empty values
*

0 comments on commit 10d69ff

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