updating habtm save handling, fixes #5579

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7795 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
gwoo 2008-10-29 07:19:26 +00:00
parent 318c2b4952
commit 6624d41ecd
2 changed files with 79 additions and 44 deletions

View file

@ -1216,47 +1216,55 @@ class Model extends Overloadable {
function __saveMulti($joined, $id) {
$db =& ConnectionManager::getDataSource($this->useDbConfig);
foreach ($joined as $assoc => $value) {
$newValues = array();
if (empty($value)) {
$value = array();
}
foreach ($joined as $assoc => $data) {
if (isset($this->hasAndBelongsToMany[$assoc])) {
list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']);
$conditions = array($join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id);
$links = array();
if ($this->hasAndBelongsToMany[$assoc]['unique']) {
$this->{$join}->deleteAll($conditions);
} else {
list($recursive, $fields) = array(-1, $this->hasAndBelongsToMany[$assoc]['associationForeignKey']);
$links = Set::extract(
$this->{$join}->find('all', compact('conditions', 'recursive', 'fields')),
"{n}.{$join}." . $this->hasAndBelongsToMany[$assoc]['associationForeignKey']
);
}
$conditions = array($join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id);
$links = $this->{$join}->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => $this->hasAndBelongsToMany[$assoc]['associationForeignKey']
));
$isUUID = !empty($this->{$join}->primaryKey) && (($this->{$join}->_schema[$this->{$join}->primaryKey]['type'] === 'string' && $this->{$join}->_schema[$this->{$join}->primaryKey]['length'] === 36)
|| ($this->{$join}->_schema[$this->{$join}->primaryKey]['type'] === 'binary' && $this->{$join}->_schema[$this->{$join}->primaryKey]['length'] === 16));
foreach ($value as $update) {
if (!empty($update)) {
if (is_array($update)) {
$update[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
$this->{$join}->create($update);
$this->{$join}->save();
} elseif (!in_array($update, $links)) {
$values = array(
$db->value($id, $this->getColumnType($this->primaryKey)),
$db->value($update)
);
if ($isUUID) {
$values[] = $db->value(String::uuid());
}
$values = join(',', $values);
$newValues[] = "({$values})";
unset($values);
$newData = $newValues = array();
foreach ($data as $row) {
if (($isUUID && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
$values = array(
$db->value($id, $this->getColumnType($this->primaryKey)),
$db->value($row)
);
if ($isUUID) {
$values[] = $db->value(String::uuid());
}
$values = join(',', $values);
$newValues[] = "({$values})";
unset($values);
} else if (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
$newData[] = $row;
}
}
if (!empty($newData)) {
foreach ($newData as $data) {
$data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
$this->{$join}->create($data);
$this->{$join}->save();
}
}
if (empty($newData) && $this->hasAndBelongsToMany[$assoc]['unique']) {
$associationForeignKey = "{$join}." . $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
$oldLinks = Set::extract($links, "{n}.{$associationForeignKey}");
if (!empty($oldLinks)) {
$conditions[$associationForeignKey] = $oldLinks;
$db->delete($this->{$join}, $conditions);
}
}
@ -1265,7 +1273,6 @@ class Model extends Overloadable {
$db->name($this->hasAndBelongsToMany[$assoc]['foreignKey']),
$db->name($this->hasAndBelongsToMany[$assoc]['associationForeignKey'])
);
if ($isUUID) {
$fields[] = $db->name($this->{$join}->primaryKey);
}

View file

@ -2882,9 +2882,38 @@ class ModelTest extends CakeTestCase {
function testHabtmSaveKeyResolution() {
$this->loadFixtures('Apple', 'Device', 'ThePaperMonkies');
$ThePaper =& new ThePaper();
$ThePaper->id = 1;
$ThePaper->id = 1;
$ThePaper->save(array('Monkey' => array(2, 3)));
$result = $ThePaper->findById(1);
$expected = array(
array('id' => '2', 'device_type_id' => '1', 'name' => 'Device 2', 'typ' => '1'),
array('id' => '3', 'device_type_id' => '1', 'name' => 'Device 3', 'typ' => '2')
);
$this->assertEqual($result['Monkey'], $expected);
$ThePaper->id = 2;
$ThePaper->save(array('Monkey' => array(1, 2, 3)));
$result = $ThePaper->findById(2);
$expected = array(
array('id' => '1', 'device_type_id' => '1', 'name' => 'Device 1', 'typ' => '1'),
array('id' => '2', 'device_type_id' => '1', 'name' => 'Device 2', 'typ' => '1'),
array('id' => '3', 'device_type_id' => '1', 'name' => 'Device 3', 'typ' => '2'),
);
$this->assertEqual($result['Monkey'], $expected);
$ThePaper->id = 2;
$ThePaper->save(array('Monkey' => array(1, 3)));
$result = $ThePaper->findById(2);
$expected = array(
array('id' => '3', 'device_type_id' => '1', 'name' => 'Device 3', 'typ' => '2'),
array('id' => '1', 'device_type_id' => '1', 'name' => 'Device 1', 'typ' => '1'),
);
$this->assertEqual($result['Monkey'], $expected);
$result = $ThePaper->findById(1);
$expected = array(
array('id' => '2', 'device_type_id' => '1', 'name' => 'Device 2', 'typ' => '1'),
@ -2892,7 +2921,6 @@ class ModelTest extends CakeTestCase {
);
$this->assertEqual($result['Monkey'], $expected);
}
/**
* test that Caches are getting cleared on save().
* ensure that both inflections of controller names are getting cleared
@ -2907,26 +2935,26 @@ class ModelTest extends CakeTestCase {
);
Configure::write('Cache.check', true);
Configure::write('Cache.disable', false);
$this->loadFixtures('OverallFavorite');
$OverallFavorite =& new OverallFavorite();
touch(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php');
touch(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php');
$data = array(
'OverallFavorite' => array(
'model_type' => '8-track',
'model_type' => '8-track',
'model_id' => '3',
'priority' => '1'
)
);
$OverallFavorite->create($data);
$OverallFavorite->save();
$this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php'));
$this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php'));
Configure::write('Cache.check', $_back['check']);
Configure::write('Cache.disable', $_back['disable']);
}
@ -2996,7 +3024,7 @@ class ModelTest extends CakeTestCase {
$expected = array('id' => '2', 'comment_id' => '7', 'attachment' => 'some_file.tgz', 'created' => $ts, 'updated' => $ts);
$this->assertEqual($result[6]['Attachment'], $expected);
}
/**
* Test SaveAll with Habtm relations
*
@ -3020,7 +3048,7 @@ class ModelTest extends CakeTestCase {
$Article =& new Article();
$result = $Article->saveAll($data);
$this->assertTrue($result);
$result = $Article->read();
$this->assertEqual(count($result['Tag']), 2);
$this->assertEqual($result['Tag'][0]['tag'], 'tag1');