From 0f1e075d681f0a9850187038a5deb92335126a34 Mon Sep 17 00:00:00 2001 From: nate Date: Fri, 16 May 2008 05:31:14 +0000 Subject: [PATCH] Adding fix for Model::saveAll() with 'validate' => 'first' and hasMany records, fixes #4387, adding test cases to disprove #4494 git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6897 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/model/model.php | 23 +++++-- cake/tests/cases/libs/model/model.test.php | 80 +++++++++++++++++++--- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 08c664d33..1e014fe64 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1388,13 +1388,28 @@ class Model extends Overloadable { foreach ($values as $i => $value) { $values[$i][$this->{$type}[$association]['foreignKey']] = $this->id; } - $_return = $this->{$association}->saveAll($values, array_merge($options, array('atomic' => false))); - if (in_array(false, $_return)) { + $_options = array_merge($options, array('atomic' => false)); + + if ($_options['validate'] === 'first') { + $_options['validate'] = 'only'; + } + $_return = $this->{$association}->saveAll($values, $_options); + + if ($_return === false || (is_array($_return) && in_array(false, $_return, true))) { $validationErrors[$association] = $this->{$association}->validationErrors; $validates = false; } - foreach ($_return as $val) { - $return[$association][] = $val; + if (is_array($_return)) { + foreach ($_return as $val) { + if (!isset($return[$association])) { + $return[$association] = array(); + } elseif (!is_array($return[$association])) { + $return[$association] = array($return[$association]); + } + $return[$association][] = $val; + } + } else { + $return[$association] = $_return; } break; } diff --git a/cake/tests/cases/libs/model/model.test.php b/cake/tests/cases/libs/model/model.test.php index ebbc5ec20..843ada5a1 100644 --- a/cake/tests/cases/libs/model/model.test.php +++ b/cake/tests/cases/libs/model/model.test.php @@ -2128,16 +2128,60 @@ class ModelTest extends CakeTestCase { $this->assertTrue($result); $result = $TestModel->find('all'); - $expected = array('id' => '7', 'article_id' => '2', 'user_id' => '2', 'comment' => 'New comment with attachment', 'published' => 'Y', 'created' => $ts, 'updated' => $ts); + $expected = array('id' => '7', 'article_id' => '2', 'user_id' => '2', 'comment' => 'New comment with attachment', 'published' => 'Y', 'created' => $ts, 'updated' => $ts); $this->assertEqual($result[6]['Comment'], $expected); - $expected = array('id' => '7', 'article_id' => '2', 'user_id' => '2', 'comment' => 'New comment with attachment', 'published' => 'Y', 'created' => $ts, 'updated' => $ts); + $expected = array('id' => '7', 'article_id' => '2', 'user_id' => '2', 'comment' => 'New comment with attachment', 'published' => 'Y', 'created' => $ts, 'updated' => $ts); $this->assertEqual($result[6]['Comment'], $expected); $expected = array('id' => '2', 'comment_id' => '7', 'attachment' => 'some_file.tgz', 'created' => $ts, 'updated' => $ts); $this->assertEqual($result[6]['Attachment'], $expected); } + function testSaveAllHasOne() { + $model = new Comment(); + $model->deleteAll(true); + $this->assertEqual($model->find('all'), array()); + + $model->Attachment->deleteAll(true); + $this->assertEqual($model->Attachment->find('all'), array()); + + $this->assertTrue($model->saveAll(array( + 'Comment' => array('comment' => 'Comment with attachment', 'article_id' => 1, 'user_id' => 1), + 'Attachment' => array('attachment' => 'some_file.zip') + ))); + $result = $model->find('all', array('fields' => array( + 'Comment.id', 'Comment.comment', 'Attachment.id', 'Attachment.comment_id', 'Attachment.attachment' + ))); + $expected = array(array( + 'Comment' => array('id' => '1', 'comment' => 'Comment with attachment'), + 'Attachment' => array('id' => '1', 'comment_id' => '1', 'attachment' => 'some_file.zip') + )); + $this->assertEqual($result, $expected); + } + + function testSaveAllBelongsTo() { + $model = new Comment(); + $model->deleteAll(true); + $this->assertEqual($model->find('all'), array()); + + $model->Article->deleteAll(true); + $this->assertEqual($model->Article->find('all'), array()); + + $this->assertTrue($model->saveAll(array( + 'Comment' => array('comment' => 'Article comment', 'article_id' => 1, 'user_id' => 1), + 'Article' => array('title' => 'Model Associations 101', 'user_id' => 1) + ))); + $result = $model->find('all', array('fields' => array( + 'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title' + ))); + $expected = array(array( + 'Comment' => array('id' => '1', 'article_id' => '1', 'comment' => 'Article comment'), + 'Article' => array('id' => '1', 'title' => 'Model Associations 101') + )); + $this->assertEqual($result, $expected); + } + function testSaveAllAtomic() { $this->loadFixtures('Article', 'User'); $TestModel =& new Article(); @@ -2385,24 +2429,38 @@ class ModelTest extends CakeTestCase { } function testSaveAllValidateFirst() { - $TestModel =& new Article(); - $TestModel->deleteAll(true); + $model =& new Article(); + $model->deleteAll(true); - $TestModel->Comment->validate = array('comment' => VALID_NOT_EMPTY); - $result = $TestModel->saveAll(array( + $model->Comment->validate = array('comment' => VALID_NOT_EMPTY); + $result = $model->saveAll(array( 'Article' => array('title' => 'Post with Author', 'body' => 'This post will be saved author'), 'Comment' => array( array('comment' => 'First new comment'), array('comment' => '') ) ), array('validate' => 'first')); - $this->assertFalse($result); - $result = $TestModel->find('all'); + $result = $model->find('all'); $this->assertEqual($result, array()); $expected = array('Comment' => array(0 => array('comment' => 'This field cannot be left blank'))); - $this->assertEqual($TestModel->validationErrors, $expected); + $this->assertEqual($model->validationErrors, $expected); + + $this->assertIdentical($model->Comment->find('count'), 0); + + $result = $model->saveAll(array( + 'Article' => array('title' => 'Post with Author', 'body' => 'This post will be saved without an author'), + 'Comment' => array( + array('comment' => 'Only new comment'), + ) + ), array('validate' => 'first')); + $this->assertIdentical($result, true); + + $result = $model->Comment->find('all'); + $this->assertIdentical(count($result), 1); + $result = Set::extract('/Comment/article_id', $result); + $this->assertTrue($result[0] === 1 || $result[0] === '1'); } function testSaveWithCounterCache() { @@ -2431,7 +2489,7 @@ class ModelTest extends CakeTestCase { $this->assertIdentical($result['Syfile']['item_count'], null); } - function testSaveWithCounterCacheScope() { + function testSaveWithCounterCacheScope() { $this->loadFixtures('Syfile', 'Item'); $TestModel =& new Syfile(); $TestModel2 =& new Item(); @@ -3789,7 +3847,7 @@ class ModelTest extends CakeTestCase { $this->assertEqual($Post->displayField, 'title'); $this->assertEqual($Person->displayField, 'name'); $this->assertEqual($Comment->displayField, 'id'); - } + } function testSchema() { $Post = new Post();