Browse Source

Making option `'unique' => 'keepExisting'` for HABTM association behave consistently with all acceptable data formats.

ADmad 14 years ago
parent
commit
bdddc85946
2 changed files with 106 additions and 2 deletions
  1. 10 2
      lib/Cake/Model/Model.php
  2. 96 0
      lib/Cake/Test/Case/Model/ModelIntegrationTest.php

+ 10 - 2
lib/Cake/Model/Model.php

@@ -1792,8 +1792,14 @@ class Model extends Object implements CakeEventListener {
 						$newValues[$row] = $values;
 						unset($values);
 					} elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+						if (!empty($row[$this->{$join}->primaryKey])) {
+							$newJoins[] = $row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
+						}
 						$newData[] = $row;
 					} elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+						if (!empty($row[$join][$this->{$join}->primaryKey])) {
+							$newJoins[] = $row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
+						}
 						$newData[] = $row[$join];
 					}
 				}
@@ -1827,8 +1833,10 @@ class Model extends Object implements CakeEventListener {
 				if (!empty($newData)) {
 					foreach ($newData as $data) {
 						$data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
-						$this->{$join}->create($data);
-						$this->{$join}->save();
+						if (empty($data[$this->{$join}->primaryKey])) {
+							$this->{$join}->create();
+						}
+						$this->{$join}->save($data);
 					}
 				}
 

+ 96 - 0
lib/Cake/Test/Case/Model/ModelIntegrationTest.php

@@ -711,6 +711,102 @@ class ModelIntegrationTest extends BaseModelTest {
 	}
 
 /**
+ * testHABTMKeepExistingAlternateDataFormat
+ *
+ * @return void
+ */
+	public function testHABTMKeepExistingAlternateDataFormat() {
+		$this->loadFixtures('Site', 'Domain', 'DomainsSite');
+
+		$Site = new Site();
+
+		$expected = array(
+			array(
+				'DomainsSite' => array(
+					'id' => 1,
+					'site_id' => 1,
+					'domain_id' => 1,
+					'active' => true,
+					'created' => '2007-03-17 01:16:23'
+				)
+			),
+			array(
+				'DomainsSite' => array(
+					'id' => 2,
+					'site_id' => 1,
+					'domain_id' => 2,
+					'active' => true,
+					'created' => '2007-03-17 01:16:23'
+				)
+			)
+		);
+		$result = $Site->DomainsSite->find('all', array(
+			'conditions' => array('DomainsSite.site_id' => 1),
+			'fields' => array(
+				'DomainsSite.id',
+				'DomainsSite.site_id',
+				'DomainsSite.domain_id',
+				'DomainsSite.active',
+				'DomainsSite.created'
+			),
+			'order' => 'DomainsSite.id'
+		));
+		$this->assertEquals($expected, $result);
+
+		$time = date('Y-m-d H:i:s');
+		$data = array(
+			'Site' => array(
+				'id' => 1
+			),
+			'Domain' => array(
+				array(
+					'site_id' => 1,
+					'domain_id'	=> 3,
+					'created' => $time,
+				),
+				array(
+					'id' => 2,
+					'site_id' => 1,
+					'domain_id'	=> 2
+				),
+			)
+		);
+		$Site->save($data);
+		$expected = array(
+			array(
+				'DomainsSite' => array(
+					'id' => 2,
+					'site_id' => 1,
+					'domain_id' => 2,
+					'active' => true,
+					'created' => '2007-03-17 01:16:23'
+				)
+			),
+			array(
+				'DomainsSite' => array(
+					'id' => 7,
+					'site_id' => 1,
+					'domain_id' => 3,
+					'active' => false,
+					'created' => $time
+				)
+			)
+		);
+		$result = $Site->DomainsSite->find('all', array(
+			'conditions' => array('DomainsSite.site_id' => 1),
+			'fields' => array(
+				'DomainsSite.id',
+				'DomainsSite.site_id',
+				'DomainsSite.domain_id',
+				'DomainsSite.active',
+				'DomainsSite.created'
+			),
+			'order' => 'DomainsSite.id'
+		));
+		$this->assertEquals($expected, $result);
+	}
+
+/**
  * test HABM operations without clobbering existing records #275
  *
  * @return void