Permalink
Browse files

Enabling th emarshaller to load many to many associations with composite

keys
  • Loading branch information...
1 parent ac2d28b commit 6c98383c9d9f78dc642716f9764a4e97c89e6e6c @lorenzo lorenzo committed Jan 15, 2014
Showing with 65 additions and 5 deletions.
  1. +10 −5 Cake/ORM/Marshaller.php
  2. +55 −0 Test/TestCase/ORM/CompositeKeysTest.php
View
@@ -14,6 +14,7 @@
*/
namespace Cake\ORM;
+use Cake\Database\Expression\TupleComparison;
use Cake\ORM\Association;
use Cake\ORM\Table;
@@ -189,14 +190,18 @@ protected function _belongsToMany(Association $assoc, array $data, $include = []
protected function _loadBelongsToMany($assoc, $ids) {
$target = $assoc->target();
$primaryKey = (array)$target->primaryKey();
+ $multi = count($primaryKey) > 1;
- if (count($primaryKey) > 1) {
- return [];
+ if ($multi) {
+ if (count(current($ids)) !== count($primaryKey)) {
+ return [];
+ }
+ $filter = new TupleComparison($primaryKey, $ids, [], 'IN');
+ } else {
+ $filter = [$primaryKey[0] . 'IN' => $ids];
}
- return $assoc->find('all')
- ->where([$primaryKey[0] . ' IN' => $ids])
- ->toArray();
+ return $assoc->find()->where($filter)->toArray();
}
}
@@ -15,12 +15,25 @@
namespace Cake\Test\TestCase\ORM;
use Cake\Database\ConnectionManager;
+use Cake\ORM\Entity;
+use Cake\ORM\Marshaller;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
/**
+ * Test entity for mass assignment.
+ */
+class OpenEntity extends Entity {
+
+ protected $_accessible = [
+ '*' => true
+ ];
+
+}
+
+/**
* Integration tetss for table operations involving composite keys
*/
class CompositeKeyTest extends TestCase {
@@ -276,4 +289,46 @@ public function testDeleteDependent() {
]);
$this->assertNull($query->all()->first(), 'Should not find any rows.');
}
+
+/**
+ * Test generating a list of entities from a list of composite ids
+ *
+ * @return void
+ */
+ public function testOneGenerateBelongsToManyEntitiesFromIds() {
+ $articles = TableRegistry::get('SiteArticles');
+ $articles->entityClass(__NAMESPACE__ . '\OpenEntity');
+ $tags = TableRegistry::get('SiteTags');
+ $junction = TableRegistry::get('SiteArticlesTags');
+ $articles->belongsToMany('SiteTags', [
+ 'targetTable' => $tags,
+ 'propertyName' => 'tags',
+ 'through' => 'SiteArticlesTags',
+ 'foreignKey' => ['article_id', 'site_id'],
+ 'targetForeignKey' => ['tag_id', 'site_id']
+ ]);
+
+ $data = [
+ 'title' => 'Haz tags',
+ 'body' => 'Some content here',
+ 'tags' => ['_ids' => [[1,1], [2, 2], [3, 1]]]
+ ];
+ $marshall = new Marshaller($articles);
+ $result = $marshall->one($data, ['SiteTags']);
+
+ $this->assertCount(3, $result->tags);
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[0]);
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[1]);
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[2]);
+
+ $data = [
+ 'title' => 'Haz tags',
+ 'body' => 'Some content here',
+ 'tags' => ['_ids' => [1, 2, 3]]
+ ];
+ $marshall = new Marshaller($articles);
+ $result = $marshall->one($data, ['SiteTags']);
+ $this->assertEmpty($result->tags);
+ }
+
}

0 comments on commit 6c98383

Please sign in to comment.