Skip to content

Commit

Permalink
Implementing handling of non atomic saves for BelongsToMany
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Nov 28, 2013
1 parent 526c7b9 commit 96e994d
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 9 deletions.
33 changes: 24 additions & 9 deletions Cake/ORM/Association/BelongsToMany.php
Expand Up @@ -285,19 +285,33 @@ protected function _saveTarget($parentEntity, $entities, $options) {
}

$table = $this->target();
$persited = [];
foreach ($entities as $entity) {
$saved = $table->save($entity, $options);
if (!$saved && !empty($options['atomic'])) {
return false;
$original = $entities;
$persisted = [];

foreach ($entities as $k => $entity) {
if (!empty($options['atomic'])) {
$entity = clone $entity;
}
if ($saved) {
$persited[] = $saved;

if ($table->save($entity, $options)) {
$entities[$k] = $entity;
$persisted[] = $entity;
continue;
}

if (!empty($options['atomic'])) {
$original[$k]->errors($entity->errors());
return false;
}
}

$this->_saveLinks($parentEntity, $persited, $options);
$success = $this->_saveLinks($parentEntity, $persisted, $options);
if (!$success && !empty($options['atomic'])) {
$parentEntity->set($this->property(), $original);
return false;
}

$parentEntity->set($this->property(), $entities);
return $parentEntity;
}

Expand All @@ -314,7 +328,7 @@ protected function _saveLinks($sourceEntity, $targetEntities, $options) {
$sourcePrimaryKey = (array)$source->primaryKey();
$jointProperty = $target->association($pivot->alias())->property();

foreach ($targetEntities as $e) {
foreach ($targetEntities as $k => $e) {
$joint = $e->get($property);
if (!$joint) {
$joint = new $entityClass;
Expand All @@ -334,6 +348,7 @@ protected function _saveLinks($sourceEntity, $targetEntities, $options) {

if ($saved) {
$e->set($jointProperty, $joint);
$savedEntities[$k] = $e;
}
}

Expand Down
75 changes: 75 additions & 0 deletions Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -2265,4 +2265,79 @@ public function testSaveBelongsToMany() {
$this->assertEquals(5, $entity->tags[1]->extraInfo->tag_id);
}

/**
* Tests saving belongsToMany records with a validation error and atomic set
* to true
*
* @group save
* @return void
*/
public function testSaveBelongsToWithValidationErrorAtomic() {
$entity = new \Cake\ORM\Entity([
'title' => 'A Title',
'body' => 'A body'
]);
$entity->tags = [
new \Cake\ORM\Entity([
'name' => '100'
]),
new \Cake\ORM\Entity([
'name' => 'Something New'
])
];
$table = TableRegistry::get('articles');
$table->belongsToMany('tags');
$tags = $table->association('tags')
->target()
->validator()
->add('name', 'num', ['rule' => 'numeric']);

$this->assertFalse($table->save($entity));
$this->assertTrue($entity->isNew());
$this->assertNull($entity->tags[0]->isNew());
$this->assertNull($entity->tags[1]->isNew());
$this->assertNull($entity->tags[0]->id);
$this->assertNull($entity->tags[1]->id);
$this->assertNull($entity->tags[0]->extraInfo);
$this->assertNull($entity->tags[1]->extraInfo);
}

/**
* Tests saving belongsToMany records with a validation error and atomic set
* to false
*
* @group save
* @return void
*/
public function testSaveBelongsToWithValidationErrorNonAtomic() {
$entity = new \Cake\ORM\Entity([
'title' => 'A Title',
'body' => 'A body'
]);
$entity->tags = [
new \Cake\ORM\Entity([
'name' => 'Something New'
]),
new \Cake\ORM\Entity([
'name' => '100'
])
];
$table = TableRegistry::get('articles');
$table->belongsToMany('tags');
$tags = $table->association('tags')
->target()
->validator()
->add('name', 'num', ['rule' => 'numeric']);

$this->assertSame($entity, $table->save($entity, ['atomic' => false]));
$this->assertFalse($entity->isNew());
$this->assertTrue($entity->tags[0]->isNew());
$this->assertFalse($entity->tags[1]->isNew());
$this->assertNull($entity->tags[0]->id);
$this->assertEquals(4, $entity->tags[1]->id);
$this->assertNull($entity->tags[0]->extraInfo);
$this->assertEquals(4, $entity->tags[1]->extraInfo->article_id);
$this->assertEquals(4, $entity->tags[1]->extraInfo->tag_id);
}

}

0 comments on commit 96e994d

Please sign in to comment.