Browse Source

Merge pull request #6899 from cakephp/btm-conditions

Use association conditions when replacing belongToMany links.
José Lorenzo Rodríguez 10 years ago
parent
commit
b1955eba27

+ 5 - 0
src/ORM/Association/BelongsToMany.php

@@ -733,6 +733,11 @@ class BelongsToMany extends Association
                 $existing = $hasMany->find('all')
                     ->where(array_combine($foreignKey, $primaryValue));
 
+                $associationConditions = $this->conditions();
+                if ($associationConditions) {
+                    $existing->andWhere($associationConditions);
+                }
+
                 $jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
                 $inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities);
 

+ 52 - 0
tests/Fixture/PolymorphicTaggedFixture.php

@@ -0,0 +1,52 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.8
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\Fixture;
+
+use Cake\TestSuite\Fixture\TestFixture;
+
+class PolymorphicTaggedFixture extends TestFixture
+{
+
+    /**
+     * table property
+     *
+     * @var string
+     */
+    public $table = 'polymorphic_tagged';
+
+    /**
+     * fields property
+     *
+     * @var array
+     */
+    public $fields = [
+        'id' => ['type' => 'integer'],
+        'tag_id' => ['type' => 'integer'],
+        'foreign_key' => ['type' => 'integer'],
+        'foreign_model' => ['type' => 'string'],
+        'position' => ['type' => 'integer', 'null' => true],
+        '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]]
+    ];
+
+    /**
+     * records property
+     *
+     * @var array
+     */
+    public $records = [
+        ['tag_id' => 1, 'foreign_key' => 1, 'foreign_model' => 'Posts', 'position' => 1],
+        ['tag_id' => 1, 'foreign_key' => 1, 'foreign_model' => 'Articles', 'position' => 1],
+    ];
+}

+ 75 - 0
tests/TestCase/ORM/TableTest.php

@@ -59,6 +59,7 @@ class TableTest extends TestCase
         'core.members',
         'core.groups',
         'core.groups_members',
+        'core.polymorphic_tagged',
     ];
 
     /**
@@ -3287,6 +3288,80 @@ class TableTest extends TestCase
     }
 
     /**
+     * Test to check that association condition are used when fetching existing
+     * records to decide which records to unlink.
+     *
+     * @return void
+     */
+    public function testPolymorphicBelongsToManySave()
+    {
+        $articles = TableRegistry::get('Articles');
+        $articles->belongsToMany('Tags', [
+            'through' => 'PolymorphicTagged',
+            'foreignKey' => 'foreign_key',
+            'conditions' => [
+                'PolymorphicTagged.foreign_model' => 'Articles'
+            ],
+            'sort' => ['PolymorphicTagged.position' => 'ASC']
+        ]);
+
+        $articles->Tags->junction()->belongsTo('Tags');
+
+        $entity = $articles->get(1, ['contain' => ['Tags']]);
+        $data = [
+            'id' => 1,
+            'tags' => [
+                [
+                    'id' => 1,
+                    '_joinData' => [
+                        'id' => 2,
+                        'foreign_model' => 'Articles',
+                        'position' => 2
+                    ]
+                ],
+                [
+                    'id' => 2,
+                    '_joinData' => [
+                        'foreign_model' => 'Articles',
+                        'position' => 1
+                    ]
+                ]
+            ]
+        ];
+        $entity = $articles->patchEntity($entity, $data, ['associated' => ['Tags._joinData']]);
+        $entity = $articles->save($entity);
+
+        $expected = [
+            [
+                'id' => 1,
+                'tag_id' => 1,
+                'foreign_key' => 1,
+                'foreign_model' => 'Posts',
+                'position' => 1
+            ],
+            [
+                'id' => 2,
+                'tag_id' => 1,
+                'foreign_key' => 1,
+                'foreign_model' => 'Articles',
+                'position' => 2
+            ],
+            [
+                'id' => 3,
+                'tag_id' => 2,
+                'foreign_key' => 1,
+                'foreign_model' => 'Articles',
+                'position' => 1
+            ]
+        ];
+        $result = TableRegistry::get('PolymorphicTagged')
+            ->find('all', ['sort' => ['id' => 'DESC']])
+            ->hydrate(false)
+            ->toArray();
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
      * Tests saving belongsToMany records can delete all links.
      *
      * @group save