From 0ee0324e20ebcd3763324ac4d6be52d7f375f554 Mon Sep 17 00:00:00 2001 From: nate Date: Fri, 7 Mar 2008 01:29:19 +0000 Subject: [PATCH] Improving validation support in Model::saveAll(), adding tests for cross-database joins, disproves #4251 git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6511 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/model/datasources/dbo_source.php | 11 +- cake/libs/model/model.php | 253 +++++++++++---------- cake/tests/cases/libs/model/model.test.php | 186 ++++++++++++++- cake/tests/cases/libs/model/models.php | 4 +- 4 files changed, 313 insertions(+), 141 deletions(-) diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 20afef4d9..b2060bf83 100644 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -425,11 +425,12 @@ class DboSource extends DataSource { function logQuery($sql) { $this->_queriesCnt++; $this->_queriesTime += $this->took; - $this->_queriesLog[] = array('query' => $sql, - 'error' => $this->error, - 'affected' => $this->affected, - 'numRows' => $this->numRows, - 'took' => $this->took + $this->_queriesLog[] = array( + 'query' => $sql, + 'error' => $this->error, + 'affected' => $this->affected, + 'numRows' => $this->numRows, + 'took' => $this->took ); if (count($this->_queriesLog) > $this->_queriesLogMax) { array_pop($this->_queriesLog); diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index bdda9685e..cb3c2bdfc 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -843,12 +843,11 @@ class Model extends Overloadable { return $this->_schema; } /** - * See Model::schema - * * @deprecated * @see Model::schema() */ function loadInfo($clear = false) { + trigger_error(__('(Model::loadInfo) Deprecated - See Model::schema()', true), E_USER_WARNING); $info = $this->schema($clear); if (is_array($info)) { $fields = array(); @@ -1040,11 +1039,18 @@ class Model extends Overloadable { function save($data = null, $validate = true, $fieldList = array()) { $db =& ConnectionManager::getDataSource($this->useDbConfig); $_whitelist = $this->whitelist; + $defaults = array('validate' => true, 'fieldList' => array(), 'callbacks' => true); $fields = array(); - if (!empty($fieldList)) { - $this->whitelist = $fieldList; - } elseif ($fieldList === null) { + if (!is_array($validate)) { + $options = array_merge($defaults, compact('validate', 'fieldList', 'callbacks')); + } else { + $options = array_merge($defaults, $validate); + } + + if (!empty($options['fieldList'])) { + $this->whitelist = $options['fieldList']; + } elseif ($options['fieldList'] === null) { $this->whitelist = array(); } $this->set($data); @@ -1059,17 +1065,15 @@ class Model extends Overloadable { } } $exists = $this->exists(); - $dateFields = array('modified', 'updated'); + if (!$exists) { $dateFields[] = 'created'; } - if (isset($this->data[$this->alias])) { $fields = array_keys($this->data[$this->alias]); } - - if ($validate && !$this->validates()) { + if ($options['validate'] && !$this->validates()) { $this->whitelist = $_whitelist; return false; } @@ -1089,9 +1093,11 @@ class Model extends Overloadable { } } - if (!$this->Behaviors->trigger('beforeSave', array(), array('break' => true, 'breakOn' => false)) || !$this->beforeSave()) { - $this->whitelist = $_whitelist; - return false; + if ($options['callbacks'] === true || $options['callbacks'] == 'before') { + if (!$this->Behaviors->trigger('beforeSave', array(), array('break' => true, 'breakOn' => false)) || !$this->beforeSave()) { + $this->whitelist = $_whitelist; + return false; + } } $fields = $values = array(); @@ -1164,8 +1170,10 @@ class Model extends Overloadable { if (!empty($this->data)) { $success = $this->data; } - $this->Behaviors->trigger('afterSave', array($created)); - $this->afterSave($created); + if ($options['callbacks'] === true || $options['callbacks'] == 'after') { + $this->Behaviors->trigger('afterSave', array($created)); + $this->afterSave($created); + } if (!empty($this->data)) { $success = Set::pushDiff($success, $this->data); } @@ -1269,9 +1277,16 @@ class Model extends Overloadable { * Saves (a) multiple individual records for a single model or (b) this record, as well as * all associated records * - * @param array $data Record data to save - * @param array $options - * @return mixed True on success, or an array of validation errors on failure + * @param array $data Record data to save. This can be either a numerically-indexed array (for saving multiple + * records of the same type), or an array indexed by association name. + * @param array $options Options to use when saving record data, which are as follows: + * - validate: Set to false to disable validation, true to validate each record before + * saving, 'first' to validate *all* records before any are saved, or 'only' to only + * validate the records, but not save them. + * - atomic: If true (default), will attempt to save all records in a single transaction. + * Should be set to false if database/table does not support transactions + * - fieldList: Equivalent to the $fieldList parameter in Model::save() + * @return mixed True on success, or false on failure * @access public */ function saveAll($data = null, $options = array()) { @@ -1280,138 +1295,130 @@ class Model extends Overloadable { } $db =& ConnectionManager::getDataSource($this->useDbConfig); - $options = array_merge(array('validate' => true, 'fieldList' => array(), 'atomic' => true), $options); - $validationErrors = array(); + $options = array_merge(array('validate' => true, 'atomic' => true), $options); + $this->validationErrors = $validationErrors = array(); $validates = true; $return = array(); - if ($options['atomic']) { + if ($options['atomic'] && $options['validate'] !== 'only') { $db->begin($this); } if (Set::numeric(array_keys($data))) { - if ($options['validate'] === 'first' || $options['validate'] === 'only') { - $this->validationErrors = array(); - + while ($validates) { foreach ($data as $record) { - if (!($this->create($record) && $this->validates())) { - $validationErrors[] = $this->validationErrors; - $validates = false; - } - } - if (!$validates) { - $this->validationErrors = $validationErrors; - return false; - } - } - - foreach ($data as $record) { - if (!($this->create($record) && $result = $this->save(null, $options['validate'] !== false, $options['fieldList'])) && $options['atomic']) { - if ($options['atomic']) { - $db->rollback($this); - } - return false; - } - $return[] = $result[$this->alias]; - } - } else { - $associations = $this->getAssociated(); - - if ($options['validate'] === 'first' || $options['validate'] === 'only') { - foreach ($data as $association => $values) { - if (isset($associations[$association]) && ($type = $associations[$association]) == 'belongsTo') { - if (!($this->{$association}->create($values) && $this->{$association}->validates())) { - $validationErrors[$association] = $this->{$association}->validationErrors; - $validates = false; + if (!$validates = $this->__save($this, $record, $options)) { + if (empty($this->id)) { + $validationErrors[] = $this->validationErrors; + } else { + $validationErrors[$this->id] = $this->validationErrors; } } } - if (!($this->create($data[$this->alias]) && $this->validates())) { - $validationErrors[$this->alias] = $this->validationErrors; - $validates = false; - } - foreach ($data as $association => $values) { - if (isset($associations[$association])) { - switch ($associations[$association]) { - case 'hasOne': - $type = $associations[$association]; - $this->{$association}->set($this->{$type}[$association]['foreignKey'], $this->id); - if (!($this->{$association}->create($values) && $this->{$association}->validates())) { - $validationErrors[$association] = $this->{$association}->validationErrors; - $validates = false; - } - break; - case 'hasMany': - if (!$this->{$association}->saveAll($values, array('validate' => 'only'))) { - $validationErrors[$association] = $this->{$association}->validationErrors; - $validates = false; - } - break; - } - } - } - if ($options['validate'] === 'only') { - if (empty($validationErrors)) { - return true; - } - $this->validationErrors = $validationErrors; - return $validates; - } - } + $this->validationErrors = $validationErrors; - foreach ($data as $association => $values) { - if (isset($associations[$association]) && ($type = $associations[$association]) == 'belongsTo') { - $alias = $this->{$association}->alias; - $foreignKey = $this->{$type}[$association]['foreignKey']; - - if (!$result = $this->{$association}->save($values, ($options['validate'] !== false), $options['fieldList'])) { + switch (true) { + case ($options['validate'] === 'only'): + return $validates; + break; + case ($options['validate'] === 'first'): + $options['validate'] = true; + continue; + break; + default: if ($options['atomic']) { - $db->rollback($this); + if ($validates) { + return ($db->commit($this) !== false); + } else { + $db->rollback($this); + } } - return false; - } elseif (!isset($data[$foreignKey]) || empty($data[$foreignKey])) { - $data[$this->alias][$foreignKey] = $this->{$association}->id; - } - $return[$association] = $result[$association]; + return $validates; + break; } } + return $validates; + } + $associations = $this->getAssociated(); - if (!$result = $this->save($data[$this->alias], ($options['validate'] !== false), $options['fieldList'])) { - if ($options['atomic']) { - $db->rollback($this); - } - return false; - } - + while ($validates) { foreach ($data as $association => $values) { if (isset($associations[$association])) { switch ($associations[$association]) { - case 'hasOne': - $type = $associations[$association]; - $this->{$association}->set($this->{$type}[$association]['foreignKey'], $this->id); - if (!$result = $this->{$association}->save($values, ($options['validate'] !== false), $options['fieldList'])) { - if ($options['atomic']) { - $db->rollback($this); - } - return false; + case 'belongsTo': + if ($this->__save($this->{$association}, $values, $options)) { + $data[$this->alias][$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id; + } else { + $validationErrors[$association] = $this->{$association}->validationErrors; + $validates = false; } break; - case 'hasMany': - if (!$result = $this->{$association}->saveAll($values, $options)) { - if ($options['atomic']) { - $db->rollback($this); - } - return false; - } - $return[$association] = $result[$association]; - break; } } } - } + if (!$this->__save($this, $data[$this->alias], $options)) { + $validationErrors[$this->alias] = $this->validationErrors; + $validates = false; + } + foreach ($data as $association => $values) { + if (isset($associations[$association])) { + $type = $associations[$association]; + switch ($type) { + case 'hasOne': + $values[$this->{$type}[$association]['foreignKey']] = $this->id; + if (!$this->__save($this->{$association}, $values, $options)) { + $validationErrors[$association] = $this->{$association}->validationErrors; + $validates = false; + } + break; + case 'hasMany': + foreach ($values as $i => $value) { + $values[$i][$this->{$type}[$association]['foreignKey']] = $this->id; + } + if (!$this->{$association}->saveAll($values, array('validate' => 'only'))) { + $validationErrors[$association] = $this->{$association}->validationErrors; + $validates = false; + } + break; + } + } + } + $this->validationErrors = $validationErrors; - if ($options['atomic']) { - return ($db->commit($this) !== false); + switch (true) { + case ($options['validate'] === 'only'): + return $validates; + break; + case ($options['validate'] === 'first'): + $options['validate'] = true; + continue; + break; + default: + if ($options['atomic']) { + if ($validates) { + return ($db->commit($this) !== false); + } else { + $db->rollback($this); + } + } + return $validates; + break; + } + } + } +/** + * Private helper method used by saveAll + * + * @access private + * @see Model::saveAll() + */ + function __save(&$model, $data, $options) { + if ($options['validate'] === 'first' || $options['validate'] === 'only') { + if (!($model->create($data) && $this->validates())) { + return false; + } + } elseif (!($model->create($data) && $model->save(null, $options))) { + return false; } return true; } diff --git a/cake/tests/cases/libs/model/model.test.php b/cake/tests/cases/libs/model/model.test.php index fa95237df..45d308217 100644 --- a/cake/tests/cases/libs/model/model.test.php +++ b/cake/tests/cases/libs/model/model.test.php @@ -1876,22 +1876,23 @@ class ModelTest extends CakeTestCase { ); $this->assertEqual($result, $expected); - $data = array('Article' => array('id' => 10, 'user_id' => '2', 'title' => 'New Article With Tags and fieldList', - 'body' => 'New Article Body with Tags and fieldList', 'created' => '2007-03-18 14:55:23', - 'updated' => '2007-03-18 14:57:31'), - 'Tag' => array('Tag' => array(1, 2, 3))); + $data = array( + 'Article' => array('id' => 10, 'user_id' => '2', 'title' => 'New Article With Tags and fieldList', 'body' => 'New Article Body with Tags and fieldList', 'created' => '2007-03-18 14:55:23', 'updated' => '2007-03-18 14:57:31'), + 'Tag' => array('Tag' => array(1, 2, 3)) + ); $result = $this->model->create() && $this->model->save($data, true, array('user_id', 'title', 'published')); $this->assertTrue($result); $this->model->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment'))); $result = $this->model->read(); - $expected = array('Article' => array('id' => 4, - 'user_id' => 2, 'title' => 'New Article With Tags and fieldList', - 'body' => '', 'published' => 'N', 'created' => '', 'updated' => ''), - 'Tag' => array( - 0 => array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'), - 1 => array('id' => 2, 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31'), - 2 => array('id' => 3, 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31'))); + $expected = array( + 'Article' => array('id' => 4, 'user_id' => 2, 'title' => 'New Article With Tags and fieldList', 'body' => '', 'published' => 'N', 'created' => '', 'updated' => ''), + 'Tag' => array( + 0 => array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'), + 1 => array('id' => 2, 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31'), + 2 => array('id' => 3, 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31') + ) + ); $this->assertEqual($result, $expected); } @@ -1956,6 +1957,59 @@ class ModelTest extends CakeTestCase { $this->assertEqual($result[6]['Attachment'], $expected); } + function testSaveAllValidation() { + $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment'); + $this->model =& new Post(); + + $data = array( + array('id' => '1', 'title' => 'Baleeted First Post', 'body' => 'Baleeted!', 'published' => 'N'), + array('id' => '2', 'title' => 'Just update the title'), + array('title' => 'Creating a fourth post', 'body' => 'Fourth post body') + ); + $ts = date('Y-m-d H:i:s'); + $this->assertTrue($this->model->saveAll($data)); + + $result = $this->model->find('all', array('recursive' => -1)); + $expected = array( + array('Post' => array('id' => '1', 'author_id' => '1', 'title' => 'Baleeted First Post', 'body' => 'Baleeted!', 'published' => 'N', 'created' => '2007-03-18 10:39:23', 'updated' => $ts)), + array('Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', 'published' => 'N', 'created' => '2007-03-18 10:41:23', 'updated' => $ts)), + array('Post' => array('id' => '3', 'author_id' => '1', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')), + array('Post' => array('id' => '4', 'author_id' => '0', 'title' => 'Creating a fourth post', 'body' => 'Fourth post body', 'published' => 'N', 'created' => $ts, 'updated' => $ts)) + ); + $this->assertEqual($result, $expected); + + $this->model->validate = array('title' => VALID_NOT_EMPTY, 'author_id' => 'numeric'); + $data = array( + array('id' => '1', 'title' => 'Un-Baleeted First Post', 'body' => 'Not Baleeted!', 'published' => 'Y'), + array('id' => '2', 'title' => '', 'body' => 'Trying to get away with an empty title'), + ); + $ts = date('Y-m-d H:i:s'); + $this->assertFalse($this->model->saveAll($data)); + + $expected[0]['Post'] = array_merge($expected[0]['Post'], $data[0], array('updated' => $ts)); + $result = $this->model->find('all', array('recursive' => -1)); + $errors = array(2 => array('title' => 'This field cannot be left blank')); + + $this->assertEqual($result, $expected); + $this->assertEqual($this->model->validationErrors, $errors); + + $data = array( + array('id' => '1', 'title' => 'Re-Baleeted First Post', 'body' => 'Baleeted!', 'published' => 'N'), + array('id' => '2', 'title' => '', 'body' => 'Trying to get away with an empty title'), + ); + $this->assertFalse($this->model->saveAll($data, array('validate' => 'first'))); + + $result = $this->model->find('all', array('recursive' => -1)); + $this->assertEqual($result, $expected); + $this->assertEqual($this->model->validationErrors, $errors); + + $data = array( + array('title' => 'First new post', 'body' => 'Woohoo!', 'published' => 'Y'), + array('title' => 'Empty body', 'body' => '') + ); + $this->model->validate['body'] = VALID_NOT_EMPTY; + } + function testSaveWithCounterCache() { $this->loadFixtures('Syfile', 'Item'); $this->model =& new Syfile(); @@ -3049,6 +3103,116 @@ class ModelTest extends CakeTestCase { $this->assertFalse(isset($this->model->Behaviors->Tree)); } +/** + * Tests cross database joins. Requires $test and $test2 to both be set in DATABASE_CONFIG + * NOTE: When testing on MySQL, you must set 'persistent' => false on *both* database connections, + * or one connection will step on the other. + */ + function testCrossDatabaseJoins() { + $config = new DATABASE_CONFIG(); + + if (!isset($config->test) || !isset($config->test2)) { + echo "
Primary and secondary test databases not configured, skipping cross-database join tests
"; + return; + } + $this->loadFixtures('Article', 'Tag', 'ArticlesTag', 'User', 'Comment'); + $this->model =& new Article(); + + $expected = array( + array( + 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'), + 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'), + 'Comment' => array( + array('id' => '1', 'article_id' => '1', 'user_id' => '2', 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'), + array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'), + array('id' => '3', 'article_id' => '1', 'user_id' => '1', 'comment' => 'Third Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'), + array('id' => '4', 'article_id' => '1', 'user_id' => '1', 'comment' => 'Fourth Comment for First Article', 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31') + ), + 'Tag' => array( + array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'), + array('id' => '2', 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31') + ) + ), + array( + 'Article' => array('id' => '2', 'user_id' => '3', 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'), + 'User' => array('id' => '3', 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'), + 'Comment' => array( + array('id' => '5', 'article_id' => '2', 'user_id' => '1', 'comment' => 'First Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'), + array('id' => '6', 'article_id' => '2', 'user_id' => '2', 'comment' => 'Second Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31') + ), + 'Tag' => array( + array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'), + array('id' => '3', 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31') + ) + ), + array( + 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'), + 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'), + 'Comment' => array(), + 'Tag' => array() + ) + ); + $this->assertEqual($this->model->find('all'), $expected); + + $db2 =& ConnectionManager::getDataSource('test2'); + + foreach (array('User', 'Comment') as $class) { + $this->_fixtures[$this->_fixtureClassMap[$class]]->create($db2); + $this->_fixtures[$this->_fixtureClassMap[$class]]->insert($db2); + $this->db->truncate(Inflector::pluralize(Inflector::underscore($class))); + } + + $this->assertEqual($this->model->User->find('all'), array()); + $this->assertEqual($this->model->Comment->find('all'), array()); + $this->assertEqual($this->model->find('count'), 3); + + $this->model->User->setDataSource('test2'); + $this->model->Comment->setDataSource('test2'); + + $result = Set::extract($this->model->User->find('all'), '{n}.User.id'); + $this->assertEqual($result, array('1', '2', '3', '4')); + $this->assertEqual($this->model->find('all'), $expected); + + $this->model->Comment->unbindModel(array('hasOne' => array('Attachment'))); + $expected = array( + array( + 'Comment' => array('id' => '1', 'article_id' => '1', 'user_id' => '2', 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'), + 'User' => array('id' => '2', 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'), + 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31') + ), + array( + 'Comment' => array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'), + 'User' => array('id' => '4', 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'), + 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31') + ), + array( + 'Comment' => array('id' => '3', 'article_id' => '1', 'user_id' => '1', 'comment' => 'Third Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'), + 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'), + 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31') + ), + array( + 'Comment' => array('id' => '4', 'article_id' => '1', 'user_id' => '1', 'comment' => 'Fourth Comment for First Article', 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'), + 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'), + 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31') + ), + array( + 'Comment' => array('id' => '5', 'article_id' => '2', 'user_id' => '1', 'comment' => 'First Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'), + 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'), + 'Article' => array('id' => '2', 'user_id' => '3', 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31') + ), + array( + 'Comment' => array('id' => '6', 'article_id' => '2', 'user_id' => '2', 'comment' => 'Second Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'), + 'User' => array('id' => '2', 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'), + 'Article' => array('id' => '2', 'user_id' => '3', 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31') + ) + ); + $this->assertEqual($this->model->Comment->find('all'), $expected); + + foreach (array('User', 'Comment') as $class) { + $fixture =& $this->_fixtures[$this->_fixtureClassMap[$class]]->drop($db2); + } + } + function endTest() { ClassRegistry::flush(); } diff --git a/cake/tests/cases/libs/model/models.php b/cake/tests/cases/libs/model/models.php index c80d7ff16..49f14150d 100644 --- a/cake/tests/cases/libs/model/models.php +++ b/cake/tests/cases/libs/model/models.php @@ -98,7 +98,7 @@ class User extends CakeTestModel { class Article extends CakeTestModel { var $name = 'Article'; var $belongsTo = array('User'); - var $hasMany = array('Comment' => array('className'=>'Comment', 'dependent' => true)); + var $hasMany = array('Comment' => array('dependent' => true)); var $hasAndBelongsToMany = array('Tag'); var $validate = array('user_id' => VALID_NUMBER, 'title' => array('allowEmpty' => false, 'rule' => VALID_NOT_EMPTY), 'body' => VALID_NOT_EMPTY); @@ -184,7 +184,7 @@ class ArticleFeaturedsTag extends CakeTestModel { class Comment extends CakeTestModel { var $name = 'Comment'; var $belongsTo = array('Article', 'User'); - var $hasOne = array('Attachment' => array('className'=>'Attachment', 'dependent' => true)); + var $hasOne = array('Attachment' => array('dependent' => true)); } /** * Short description for class.