Browse Source

Allow joint table records to be not deleted.

Re-use the dependent option to allow people to disable cascaded deletes
onto the joint table. This is useful when you have constraints with
`cascade delete`

Refs #6063
Mark Story 11 years ago
parent
commit
688e40852f

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

@@ -122,6 +122,16 @@ class BelongsToMany extends Association
     protected $_validStrategies = [self::STRATEGY_SELECT, self::STRATEGY_SUBQUERY];
 
     /**
+     * Whether the records on the joint table should be removed when a record
+     * on the source table is deleted.
+     *
+     * Defaults to true for backwards compatibility.
+     *
+     * @var bool
+     */
+    protected $_dependent = true;
+
+    /**
      * Sets the name of the field representing the foreign key to the target table.
      * If no parameters are passed current field is returned
      *
@@ -332,6 +342,9 @@ class BelongsToMany extends Association
      */
     public function cascadeDelete(EntityInterface $entity, array $options = [])
     {
+        if (!$this->dependent()) {
+            return true;
+        }
         $foreignKey = (array)$this->foreignKey();
         $primaryKey = (array)$this->source()->primaryKey();
         $conditions = [];

+ 29 - 0
tests/TestCase/ORM/Association/BelongsToManyTest.php

@@ -278,6 +278,35 @@ class BelongsToManyTest extends TestCase
     }
 
     /**
+     * Test cascading deletes with dependent=false
+     *
+     * @return void
+     */
+    public function testCascadeDeleteDependent()
+    {
+        $articleTag = $this->getMock('Cake\ORM\Table', ['delete', 'deleteAll'], []);
+        $config = [
+            'sourceTable' => $this->article,
+            'targetTable' => $this->tag,
+            'dependent' => false,
+            'sort' => ['id' => 'ASC'],
+        ];
+        $association = new BelongsToMany('Tags', $config);
+        $association->junction($articleTag);
+        $this->article
+            ->association($articleTag->alias())
+            ->conditions(['click_count' => 3]);
+
+        $articleTag->expects($this->never())
+            ->method('deleteAll');
+        $articleTag->expects($this->never())
+            ->method('delete');
+
+        $entity = new Entity(['id' => 1, 'name' => 'PHP']);
+        $association->cascadeDelete($entity);
+    }
+
+    /**
      * Test cascading deletes with callbacks.
      *
      * @return void