Making habtm join conditions used by __saveMulti when finding link records to remove. It should be noted that having conditions on non-joinTable tables, and not having a model on the joinTable can cause SQL issues. Fixes #304

This commit is contained in:
mark_story 2009-11-22 17:56:46 -05:00
parent 6c3bcdd7e6
commit 2e0acbf505
2 changed files with 59 additions and 9 deletions

View file

@ -1302,14 +1302,6 @@ class Model extends Overloadable {
if (isset($this->hasAndBelongsToMany[$assoc])) {
list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']);
$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]['length'] == 36 && (
$this->{$join}->_schema[$this->{$join}->primaryKey]['type'] === 'string' ||
@ -1351,6 +1343,16 @@ class Model extends Overloadable {
}
if ($this->hasAndBelongsToMany[$assoc]['unique']) {
$conditions = array_merge(
array($join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id),
(array)$this->hasAndBelongsToMany[$assoc]['conditions']
);
$links = $this->{$join}->find('all', array(
'conditions' => $conditions,
'recursive' => empty($this->hasAndBelongsToMany[$assoc]['conditions']) ? -1 : 0,
'fields' => $this->hasAndBelongsToMany[$assoc]['associationForeignKey']
));
$associationForeignKey = "{$join}." . $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
$oldLinks = Set::extract($links, "{n}.{$associationForeignKey}");
if (!empty($oldLinks)) {

View file

@ -609,7 +609,7 @@ class ModelWriteTest extends BaseModelTest {
function testBeforeValidateSaveAbortion() {
$Model =& new CallbackPostTestModel();
$Model->beforeValidateReturn = false;
$data = array(
'title' => 'new article',
'body' => 'this is some text.'
@ -1992,6 +1992,54 @@ class ModelWriteTest extends BaseModelTest {
));
$this->assertEqual($result, $expected);
}
/**
* test that saving habtm records respects conditions set in the the 'conditions' key
* for the association.
*
* @return void
*/
function testHabtmSaveWithConditionsInAssociation() {
$this->loadFixtures('JoinThing', 'Something', 'SomethingElse');
$Something =& new Something();
$Something->unbindModel(array('hasAndBelongsToMany' => array('SomethingElse')), false);
$Something->bindModel(array(
'hasAndBelongsToMany' => array(
'DoomedSomethingElse' => array(
'className' => 'SomethingElse',
'joinTable' => 'join_things',
'conditions' => 'JoinThing.doomed = 1',
'unique' => true
),
'NotDoomedSomethingElse' => array(
'className' => 'SomethingElse',
'joinTable' => 'join_things',
'conditions' => array('JoinThing.doomed' => 0),
'unique' => true
)
)
), false);
$result = $Something->read(null, 1);
$this->assertTrue(empty($result['NotDoomedSomethingElse']));
$this->assertEqual(count($result['DoomedSomethingElse']), 1);
$data = array(
'Something' => array('id' => 1),
'NotDoomedSomethingElse' => array(
'NotDoomedSomethingElse' => array(
array('something_else_id' => 2, 'doomed' => 0),
array('something_else_id' => 3, 'doomed' => 0)
)
)
);
$Something->create($data);
$result = $Something->save();
$this->assertTrue($result);
$result = $Something->read(null, 1);
$this->assertEqual(count($result['NotDoomedSomethingElse']), 2);
$this->assertEqual(count($result['DoomedSomethingElse']), 1);
}
/**
* testHabtmSaveKeyResolution method
*