Skip to content
Permalink
Browse files

Avoiding bonus UPDATE statements when saving belongsToMny associations

  • Loading branch information...
lorenzo committed Jul 16, 2015
1 parent fc54441 commit 04c71914c99534c222ad68bea9754d678bece983
Showing with 48 additions and 5 deletions.
  1. +11 −5 src/ORM/Association/BelongsToMany.php
  2. +37 −0 tests/TestCase/ORM/TableTest.php
@@ -543,11 +543,17 @@ protected function _saveLinks(EntityInterface $sourceEntity, $targetEntities, $o
$joint = new $entityClass([], ['markNew' => true, 'source' => $junctionAlias]);
}
$joint->set(array_combine(
$foreignKey,
$sourceEntity->extract($bindingKey)
), ['guard' => false]);
$joint->set(array_combine($assocForeignKey, $e->extract($targetPrimaryKey)), ['guard' => false]);
$sourceKeys = array_combine($foreignKey, $sourceEntity->extract($bindingKey));
$targetKeys = array_combine($assocForeignKey, $e->extract($targetPrimaryKey));
if ($sourceKeys !== $joint->extract($foreignKey)) {
$joint->set($sourceKeys, ['guard' => false]);
}
if ($targetKeys !== $joint->extract($assocForeignKey)) {
$joint->set($targetKeys, ['guard' => false]);
}
$saved = $junction->save($joint, $options);
if (!$saved && !empty($options['atomic'])) {
@@ -4382,6 +4382,43 @@ public function testSaveHasManyNoWasteSave()
$this->assertEquals(1, $counter);
}
/**
* Tests that on second save, entities for the belongsToMany relation are not marked
* as dirty unnecessarily. This helps avoid wasteful database statements and makes
* for a cleaner transaction log
*
* @return void
*/
public function testSaveBelongsToManyNoWasteSave()
{
$data = [
'title' => 'foo',
'body' => 'bar',
'tags' => [
'_ids' => [1, 2]
]
];
$table = TableRegistry::get('Articles');
$table->belongsToMany('Tags');
$article = $table->save($table->newEntity($data, ['associated' => ['Tags']]));
$counter = 0;
$table->Tags->junction()
->eventManager()
->on('Model.afterSave', function ($event, $entity) use (&$counter) {
if ($entity->dirty()) {
$counter++;
}
});
$article->tags[] = $table->Tags->get(3);
$this->assertCount(3, $article->tags);
$article->dirty('tags', true);
$table->save($article);
$this->assertEquals(1, $counter);
}
/**
* Tests that after saving then entity contains the right primary
* key casted to the right type

0 comments on commit 04c7191

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