Skip to content

Commit

Permalink
Only marking an association property as dirty if it changed
Browse files Browse the repository at this point in the history
Fixes #6050
  • Loading branch information
lorenzo committed Mar 14, 2015
1 parent 29a6445 commit 9382a06
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/ORM/Marshaller.php
Expand Up @@ -355,7 +355,7 @@ public function merge(EntityInterface $entity, array $data, array $options = [])

$errors = $this->_validate($data + $keys, $options, $isNew);
$schema = $this->_table->schema();
$properties = [];
$properties = $marshalledAssocs = [];
foreach ($data as $key => $value) {
if (!empty($errors[$key])) {
continue;
Expand All @@ -367,6 +367,7 @@ public function merge(EntityInterface $entity, array $data, array $options = [])
if (isset($propertyMap[$key])) {
$assoc = $propertyMap[$key]['association'];
$value = $this->_mergeAssociation($original, $assoc, $value, $propertyMap[$key]);
$marshalledAssocs[$key] = true;
} elseif ($columnType) {
$converter = Type::build($columnType);
$value = $converter->marshal($value);
Expand All @@ -384,12 +385,22 @@ public function merge(EntityInterface $entity, array $data, array $options = [])
if (!isset($options['fieldList'])) {
$entity->set($properties);
$entity->errors($errors);

foreach (array_keys($marshalledAssocs) as $field) {
if ($properties[$field] instanceof EntityInterface) {
$entity->dirty($field, $properties[$field]->dirty());
}
}
return $entity;
}

foreach ((array)$options['fieldList'] as $field) {
if (array_key_exists($field, $properties)) {
$entity->set($field, $properties[$field]);
if ($properties[$field] instanceof EntityInterface &&
isset($marshalledAssocs[$field])) {
$entity->dirty($assoc, $properties[$field]->dirty());
}
}
}

Expand Down
34 changes: 34 additions & 0 deletions tests/TestCase/ORM/MarshallerTest.php
Expand Up @@ -1970,4 +1970,38 @@ public function testBeforeMarshalEventOnAssociations()
$this->assertEquals(1, $entity->tags[0]->_joinData->modified_by);
$this->assertEquals(1, $entity->tags[1]->_joinData->modified_by);
}

/**
* Tests that patching an association resulting in no changes, will
* not mark the parent entity as dirty
*
* @return void
*/
public function testAssociationNoChanges()
{
$options = ['markClean' => true, 'isNew' => false];
$entity = new Entity([
'tile' => 'My Title',
'user' => new Entity([
'username' => 'mark',
'password' => 'not a secret'
], $options)
], $options);

$data = [
'body' => 'My Content',
'user' => [
'username' => 'mark',
'password' => 'not a secret'
]
];
$marshall = new Marshaller($this->articles);
$marshall->merge($entity, $data, ['associated' => ['Users']]);
$this->assertEquals('My Content', $entity->body);
$this->assertInstanceOf('Cake\ORM\Entity', $entity->user);
$this->assertEquals('mark', $entity->user->username);
$this->assertEquals('not a secret', $entity->user->password);
$this->assertFalse($entity->dirty('user'));
$this->assertTrue($entity->user->isNew());
}
}

0 comments on commit 9382a06

Please sign in to comment.