From b5c4b85601fdae23a89ddd2c52c97c7969d6a29f Mon Sep 17 00:00:00 2001 From: Ceeram Date: Wed, 30 Nov 2011 20:02:36 +0100 Subject: [PATCH] Fixing cascading delete, when using foreignKey false and setting condition on hasOne. --- lib/Cake/Model/Model.php | 14 +++- lib/Cake/Test/Case/Model/ModelDeleteTest.php | 79 +++++++++++++++++++ lib/Cake/Test/Case/Model/ModelTestBase.php | 3 +- lib/Cake/Test/Case/Model/models.php | 63 +++++++++++++++ lib/Cake/Test/Fixture/BiddingFixture.php | 56 +++++++++++++ .../Test/Fixture/BiddingMessageFixture.php | 55 +++++++++++++ 6 files changed, 265 insertions(+), 5 deletions(-) create mode 100644 lib/Cake/Test/Fixture/BiddingFixture.php create mode 100644 lib/Cake/Test/Fixture/BiddingMessageFixture.php diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 9149d6e0d17..e3ac175ad6a 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -2249,11 +2249,17 @@ protected function _deleteDependent($id, $cascade) { if ($data['dependent'] === true) { $model = $this->{$assoc}; - $conditions = array($model->escapeField($data['foreignKey']) => $id); - if ($data['conditions']) { - $conditions = array_merge((array)$data['conditions'], $conditions); + + if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $model->getAssociated('belongsTo'))) { + $model->recursive = 0; + $conditions = array($this->escapeField(null, $this->name) => $id); + } else { + $model->recursive = -1; + $conditions = array($model->escapeField($data['foreignKey']) => $id); + if ($data['conditions']) { + $conditions = array_merge((array)$data['conditions'], $conditions); + } } - $model->recursive = -1; if (isset($data['exclusive']) && $data['exclusive']) { $model->deleteAll($conditions); diff --git a/lib/Cake/Test/Case/Model/ModelDeleteTest.php b/lib/Cake/Test/Case/Model/ModelDeleteTest.php index cf2b35286d9..ed6473164d6 100644 --- a/lib/Cake/Test/Case/Model/ModelDeleteTest.php +++ b/lib/Cake/Test/Case/Model/ModelDeleteTest.php @@ -549,6 +549,85 @@ public function testDeleteLinksWithPLuginJoinModel() { $this->assertTrue($Article->delete(1)); } +/** + * testDeleteDependent method + * + * @return void + */ + public function testDeleteDependent() { + $this->loadFixtures('Bidding', 'BiddingMessage'); + $Bidding = new Bidding(); + $result = $Bidding->find('all'); + $expected = array( + array( + 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'), + 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'), + ), + array( + 'Bidding' => array('id' => 2, 'bid' => 'Two', 'name' => 'Bid 2'), + 'BiddingMessage' => array('bidding' => 'Two', 'name' => 'Message 2'), + ), + array( + 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'), + 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'), + ), + array( + 'Bidding' => array('id' => 4, 'bid' => 'Five', 'name' => 'Bid 5'), + 'BiddingMessage' => array('bidding' => '', 'name' => ''), + ), + ); + $this->assertEquals($expected, $result); + + $Bidding->delete(4, true); + $result = $Bidding->find('all'); + $expected = array( + array( + 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'), + 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'), + ), + array( + 'Bidding' => array('id' => 2, 'bid' => 'Two', 'name' => 'Bid 2'), + 'BiddingMessage' => array('bidding' => 'Two', 'name' => 'Message 2'), + ), + array( + 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'), + 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'), + ), + ); + $this->assertEquals($expected, $result); + + $Bidding->delete(2, true); + $result = $Bidding->find('all'); + $expected = array( + array( + 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'), + 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'), + ), + array( + 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'), + 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'), + ), + ); + $this->assertEquals($expected, $result); + + $result = $Bidding->BiddingMessage->find('all', array('order' => array('BiddingMessage.name' => 'ASC'))); + $expected = array( + array( + 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'), + 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'), + ), + array( + 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'), + 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'), + ), + array( + 'BiddingMessage' => array('bidding' => 'Four', 'name' => 'Message 4'), + 'Bidding' => array('id' => '', 'bid' => '', 'name' => ''), + ), + ); + $this->assertEquals($expected, $result); + } + /** * test deleteLinks with Multiple habtm associations * diff --git a/lib/Cake/Test/Case/Model/ModelTestBase.php b/lib/Cake/Test/Case/Model/ModelTestBase.php index 7124118a52c..be8159299fa 100644 --- a/lib/Cake/Test/Case/Model/ModelTestBase.php +++ b/lib/Cake/Test/Case/Model/ModelTestBase.php @@ -67,7 +67,8 @@ abstract class BaseModelTest extends CakeTestCase { 'core.counter_cache_user_nonstandard_primary_key', 'core.counter_cache_post_nonstandard_primary_key', 'core.uuidportfolio', 'core.uuiditems_uuidportfolio', 'core.uuiditems_uuidportfolio_numericid', 'core.fruit', - 'core.fruits_uuid_tag', 'core.uuid_tag', 'core.product_update_all', 'core.group_update_all' + 'core.fruits_uuid_tag', 'core.uuid_tag', 'core.product_update_all', 'core.group_update_all', + 'core.bidding', 'core.bidding_message' ); /** diff --git a/lib/Cake/Test/Case/Model/models.php b/lib/Cake/Test/Case/Model/models.php index 157495c238f..13ee2e2cda3 100644 --- a/lib/Cake/Test/Case/Model/models.php +++ b/lib/Cake/Test/Case/Model/models.php @@ -1001,6 +1001,69 @@ class Bid extends CakeTestModel { public $belongsTo = array('Message'); } +/** + * BiddingMessage class + * + * @package Cake.Test.Case.Model + */ +class BiddingMessage extends CakeTestModel { + +/** + * name property + * + * @var string 'BiddingMessage' + */ + public $name = 'BiddingMessage'; + +/** + * primaryKey property + * + * @var string 'bidding' + */ + public $primaryKey = 'bidding'; + + +/** + * belongsTo property + * + * @var array + */ + public $belongsTo = array( + 'Bidding' => array( + 'foreignKey' => false, + 'conditions' => array('BiddingMessage.bidding = Bidding.bid') + ) + ); +} + +/** + * Bidding class + * + * @package Cake.Test.Case.Model + */ +class Bidding extends CakeTestModel { + +/** + * name property + * + * @var string 'Bidding' + */ + public $name = 'Bidding'; + +/** + * hasOne property + * + * @var array + */ + public $hasOne = array( + 'BiddingMessage' => array( + 'foreignKey' => false, + 'conditions' => array('BiddingMessage.bidding = Bidding.bid'), + 'dependent' => true + ) + ); +} + /** * NodeAfterFind class * diff --git a/lib/Cake/Test/Fixture/BiddingFixture.php b/lib/Cake/Test/Fixture/BiddingFixture.php new file mode 100644 index 00000000000..ec763c68d94 --- /dev/null +++ b/lib/Cake/Test/Fixture/BiddingFixture.php @@ -0,0 +1,56 @@ + + * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package Cake.Test.Fixture + * @since CakePHP(tm) v 1.3.14 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ + +/** + * Short description for class. + * + * @package Cake.Test.Fixture + */ +class BiddingFixture extends CakeTestFixture { + +/** + * name property + * + * @var string 'Bidding' + */ + public $name = 'Bidding'; + +/** + * fields property + * + * @var array + */ + public $fields = array( + 'id' => array('type' => 'integer', 'key' => 'primary'), + 'bid' => array('type' => 'string', 'null' => false), + 'name' => array('type' => 'string', 'null' => false) + ); + +/** + * records property + * + * @var array + */ + public $records = array( + array('bid' => 'One', 'name' => 'Bid 1'), + array('bid' => 'Two', 'name' => 'Bid 2'), + array('bid' => 'Three', 'name' => 'Bid 3'), + array('bid' => 'Five', 'name' => 'Bid 5') + ); +} diff --git a/lib/Cake/Test/Fixture/BiddingMessageFixture.php b/lib/Cake/Test/Fixture/BiddingMessageFixture.php new file mode 100644 index 00000000000..253645fa290 --- /dev/null +++ b/lib/Cake/Test/Fixture/BiddingMessageFixture.php @@ -0,0 +1,55 @@ + + * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package Cake.Test.Fixture + * @since CakePHP(tm) v 1.3.14 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ + +/** + * Short description for class. + * + * @package Cake.Test.Fixture + */ +class BiddingMessageFixture extends CakeTestFixture { + +/** + * name property + * + * @var string 'BiddingMessage' + */ + public $name = 'BiddingMessage'; + +/** + * fields property + * + * @var array + */ + public $fields = array( + 'bidding' => array('type' => 'string', 'null' => false, 'key' => 'primary'), + 'name' => array('type' => 'string', 'null' => false) + ); + +/** + * records property + * + * @var array + */ + public $records = array( + array('bidding' => 'One', 'name' => 'Message 1'), + array('bidding' => 'Two', 'name' => 'Message 2'), + array('bidding' => 'Three', 'name' => 'Message 3'), + array('bidding' => 'Four', 'name' => 'Message 4') + ); +}