make sure model data is moved to alias, even when first key in data is assoc model

add extra tests for saveAll and validate first
ensure db values dont get reset to default values
This commit is contained in:
Ceeram 2012-05-15 16:57:42 +02:00 committed by Jose Lorenzo Rodriguez
parent 7107cd6631
commit 7dbd6bc3a2
5 changed files with 98 additions and 26 deletions

View file

@ -1129,9 +1129,7 @@ class Model extends Object implements CakeEventListener {
if (is_array($one)) { if (is_array($one)) {
$data = $one; $data = $one;
if (empty($one[$this->alias])) { if (empty($one[$this->alias])) {
if ($this->getAssociated(key($one)) === null) { $data = $this->_setAliasData($one);
$data = array($this->alias => $one);
}
} }
} else { } else {
$data = array($this->alias => array($one => $two)); $data = array($this->alias => array($one => $two));
@ -1160,6 +1158,24 @@ class Model extends Object implements CakeEventListener {
return $data; return $data;
} }
/**
* Move values to alias
*
* @param array $data
* @return array
*/
protected function _setAliasData($data) {
$models = array_keys($this->getAssociated());
$schema = array_keys($this->schema());
foreach ($data as $field => $value) {
if (in_array($field, $schema) || !in_array($field, $models)) {
$data[$this->alias][$field] = $value;
unset($data[$field]);
}
}
return $data;
}
/** /**
* Normalize Xml::toArray() to use in Model::save() * Normalize Xml::toArray() to use in Model::save()
* *
@ -2118,7 +2134,8 @@ class Model extends Object implements CakeEventListener {
if ($options['deep']) { if ($options['deep']) {
$validates = $this->validateAssociated($record, $options); $validates = $this->validateAssociated($record, $options);
} else { } else {
$validates = $this->create($record) && $this->validates($options); $this->create(null);
$validates = $this->set($record) && $this->validates($options);
$data[$key] = $this->data; $data[$key] = $this->data;
} }
if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) { if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) {
@ -2318,21 +2335,14 @@ class Model extends Object implements CakeEventListener {
public function validateAssociated(&$data, $options = array()) { public function validateAssociated(&$data, $options = array()) {
$options = array_merge(array('atomic' => true, 'deep' => false), $options); $options = array_merge(array('atomic' => true, 'deep' => false), $options);
$this->validationErrors = $validationErrors = $return = array(); $this->validationErrors = $validationErrors = $return = array();
if (!($this->create($data) && $this->validates($options))) { $this->create(null);
if (!($this->set($data) && $this->validates($options))) {
$validationErrors[$this->alias] = $this->validationErrors; $validationErrors[$this->alias] = $this->validationErrors;
$return[$this->alias] = false; $return[$this->alias] = false;
} else { } else {
$return[$this->alias] = true; $return[$this->alias] = true;
} }
$data = $this->data;
if (empty($options['deep'])) {
$data = $this->data;
} else {
$modelData = $this->data;
$recordData = $modelData[$this->alias];
unset($modelData[$this->alias]);
$data = $modelData + array_merge($data, $recordData);
}
$associations = $this->getAssociated(); $associations = $this->getAssociated();
foreach ($data as $association => &$values) { foreach ($data as $association => &$values) {

View file

@ -7868,7 +7868,7 @@ class ModelReadTest extends BaseModelTest {
$Article = new CustomArticle(); $Article = new CustomArticle();
$data = array('user_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N'); $data = array('user_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
$Article->create($data); $Article->create($data);
$Article->save(); $Article->save(null, false);
$this->assertEquals(4, $Article->id); $this->assertEquals(4, $Article->id);
$result = $Article->find('published'); $result = $Article->find('published');

View file

@ -1016,22 +1016,34 @@ class ModelValidationTest extends BaseModelTest {
); );
$result = $model->saveAll($data, array('validate' => 'first')); $result = $model->saveAll($data, array('validate' => 'first'));
$this->assertTrue($result); $this->assertTrue($result);
$this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
$title = $model->field('title', array('body' => 'foo0')); $model->findMethods['unPublished'] = true;
$data = array(
'CustomArticle' => array(
'body' => 'foo1'
)
);
$result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
$this->assertTrue($result);
$title = $model->field('title', array('body' => 'foo1'));
$this->assertEquals('foo', $title); $this->assertEquals('foo', $title);
$this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
$data = array( $data = array(
array('body' => 'foo1'),
array('body' => 'foo2'), array('body' => 'foo2'),
array('body' => 'foo3') array('body' => 'foo3'),
array('body' => 'foo4')
); );
$result = $model->saveAll($data, array('validate' => 'first')); $result = $model->saveAll($data, array('validate' => 'first'));
$this->assertTrue($result); $this->assertTrue($result);
$result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
$this->assertTrue($result);
$this->assertEquals('foo', $model->field('title', array('body' => 'foo1')));
$this->assertEquals('foo', $model->field('title', array('body' => 'foo2'))); $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
$this->assertEquals('foo', $model->field('title', array('body' => 'foo3'))); $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
$this->assertEquals('foo', $model->field('title', array('body' => 'foo4')));
} }
/** /**
@ -1040,7 +1052,7 @@ class ModelValidationTest extends BaseModelTest {
* *
* @return void * @return void
*/ */
public function testValidateAssociatedWithBeforeValidate() { public function testValidateFirstAssociatedWithBeforeValidate() {
$this->loadFixtures('Article', 'User'); $this->loadFixtures('Article', 'User');
$model = new CustomArticle(); $model = new CustomArticle();
$model->validate = array( $model->validate = array(
@ -1070,4 +1082,49 @@ class ModelValidationTest extends BaseModelTest {
$this->assertEquals('foo', $model->field('title', array('body' => 'foo3'))); $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
} }
/**
* testValidateFirstWithDefaults method
*
* return @void
*/
public function testFirstWithDefaults() {
$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
$TestModel = new Article();
$result = $TestModel->find('first', array(
'conditions' => array('Article.id' => 1)
));
$expected = array(
'Article' => array(
'id' => 1,
'user_id' => 1,
'title' => 'First Article',
'body' => 'First Article Body',
'published' => 'Y',
'created' => '2007-03-18 10:39:23'
),
);
unset($result['Article']['updated']);
$this->assertEquals($expected['Article'], $result['Article']);
$data = array(
'Article' => array(
'id' => 1,
'title' => 'First Article (modified)'
),
'Comment' => array(
array('comment' => 'Article comment', 'user_id' => 1)
)
);
$result = $TestModel->saveAll($data, array('validate' => 'first'));
$this->assertTrue($result);
$result = $TestModel->find('first', array(
'conditions' => array('Article.id' => 1)
));
$expected['Article']['title'] = 'First Article (modified)';
unset($result['Article']['updated']);
$this->assertEquals($expected['Article'], $result['Article']);
}
} }

View file

@ -4277,7 +4277,7 @@ class ModelWriteTest extends BaseModelTest {
'author_id' => '3', 'author_id' => '3',
'title' => 'Just update the title', 'title' => 'Just update the title',
'body' => 'Second Post Body', 'body' => 'Second Post Body',
'published' => 'N', 'published' => 'Y',
'created' => '2007-03-18 10:41:23' 'created' => '2007-03-18 10:41:23'
)), )),
array( array(
@ -4366,7 +4366,7 @@ class ModelWriteTest extends BaseModelTest {
'author_id' => '3', 'author_id' => '3',
'title' => 'Just update the title', 'title' => 'Just update the title',
'body' => 'Second Post Body', 'body' => 'Second Post Body',
'published' => 'N', 'published' => 'Y',
'created' => '2007-03-18 10:41:23' 'created' => '2007-03-18 10:41:23'
) )
), ),
@ -4734,7 +4734,7 @@ class ModelWriteTest extends BaseModelTest {
'password' => '5f4dcc3b5aa765d61d8327deb882cf90' 'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
))); )));
$result = $TestModel->find('all'); $result = $TestModel->find('all', array('order' => array('Post.id ' => 'ASC')));
$expected = array( $expected = array(
'Post' => array( 'Post' => array(
'id' => '4', 'id' => '4',
@ -5631,7 +5631,7 @@ class ModelWriteTest extends BaseModelTest {
'author_id' => '3', 'author_id' => '3',
'title' => 'Just update the title', 'title' => 'Just update the title',
'body' => 'Second Post Body', 'body' => 'Second Post Body',
'published' => 'N', 'published' => 'Y',
'created' => '2007-03-18 10:41:23' 'created' => '2007-03-18 10:41:23'
) )
), ),
@ -5727,7 +5727,7 @@ class ModelWriteTest extends BaseModelTest {
'author_id' => '3', 'author_id' => '3',
'title' => 'Just update the title', 'title' => 'Just update the title',
'body' => 'Second Post Body', 'body' => 'Second Post Body',
'published' => 'N', 'published' => 'Y',
)), )),
array( array(
'Post' => array( 'Post' => array(

View file

@ -4975,6 +4975,11 @@ class CustomArticle extends AppModel {
**/ **/
public function beforeValidate($options = array()) { public function beforeValidate($options = array()) {
$this->data[$this->alias]['title'] = 'foo'; $this->data[$this->alias]['title'] = 'foo';
if ($this->findMethods['unPublished'] === true) {
$this->findMethods['unPublished'] = false;
} else {
$this->findMethods['unPublished'] = 'true again';
}
} }
} }