Skip to content

Commit

Permalink
Skip non-entity entries in BelongsToMany associations
Browse files Browse the repository at this point in the history
When saving entities with accessible belongs to many association
properties that were not marshalled, fatal errors would be encountered.
Skipping the obviously bad data is a resonable course of action as the
ORM should not marshall it, as it was either explicitly or implicitly
not marshalled.

Refs #6301
  • Loading branch information
markstory committed Apr 10, 2015
1 parent fcd51e1 commit 51dc9cf
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/ORM/Association/BelongsToMany.php
Expand Up @@ -804,6 +804,9 @@ protected function _diffLinks($existing, $jointEntities, $targetEntities)
$primary = (array)$target->primaryKey();
$jointProperty = $this->_junctionProperty;
foreach ($targetEntities as $k => $entity) {
if (!($entity instanceof EntityInterface)) {
continue;
}
$key = array_values($entity->extract($primary));
foreach ($present as $i => $data) {
if ($key === $data && !$entity->get($jointProperty)) {
Expand Down Expand Up @@ -873,6 +876,9 @@ protected function _collectJointEntities($sourceEntity, $targetEntities)
$missing = [];

foreach ($targetEntities as $entity) {
if (!($entity instanceof EntityInterface)) {
continue;
}
$joint = $entity->get($jointProperty);

if (!$joint || !($joint instanceof EntityInterface)) {
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -912,7 +912,7 @@ public function testSaveAssociatedWithReplaceReturnFalse()
*
* @return void
*/
public function testSaveAssociatedOnlyEntities()
public function testSaveAssociatedOnlyEntitiesAppend()
{
$connection = ConnectionManager::get('test');
$mock = $this->getMock(
Expand Down
16 changes: 16 additions & 0 deletions tests/TestCase/ORM/TableTest.php
Expand Up @@ -3170,6 +3170,22 @@ public function testSaveBelongsToManyDeleteSomeLinks()
$this->assertEquals($tag->id, $entity->tags[0]->id);
}

/**
* Test that belongsToMany ignores non-entity data.
*
* @return void
*/
public function testSaveBelongsToManyIgnoreNonEntityData()
{
$articles = TableRegistry::get('Articles');
$article = $articles->get(1, ['contain' => ['Tags']]);
$article->tags = [
'_ids' => [2, 1]
];
$result = $articles->save($article);
$this->assertSame($result, $article);
}

/**
* Tests that saving a persisted and clean entity will is a no-op
*
Expand Down

0 comments on commit 51dc9cf

Please sign in to comment.