Permalink
Browse files

Refactoring methods, adding self join association detection.

Test cases updated.
  • Loading branch information...
1 parent 4b4875e commit 5c48603bd0e655da4a932c166dfbad54973a5b3e @markstory markstory committed May 10, 2009
Showing with 124 additions and 53 deletions.
  1. +60 −43 cake/console/libs/tasks/model.php
  2. +64 −10 cake/tests/cases/console/libs/tasks/model.test.php
@@ -79,6 +79,15 @@ class ModelTask extends Shell {
var $__validations = array();
/**
+ * startup method
+ *
+ * @return void
+ **/
+ function startup() {
+ App::import('Core', 'Model');
+ }
+
+/**
* Execution method always used for tasks
*
* @access public
@@ -127,13 +136,8 @@ function all() {
* @param string $className Name of class you want model to be.
* @return object Model instance
**/
- function _getModelObject($className) {
- if (App::import('Model', $className)) {
- $object = new $className();
- } else {
- App::import('Model');
- $object = new Model(array('name' => $className, 'ds' => $this->connection));
- }
+ function &_getModelObject($className) {
+ $object = new Model(array('name' => $className, 'ds' => $this->connection));
return $object;
}
/**
@@ -159,7 +163,6 @@ function __interactive() {
$fullTableName = $db->fullTableName($useTable);
if (in_array($useTable, $this->__tables)) {
- App::import('Model');
$tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $this->connection));
$fields = $tempModel->schema();
if (!array_key_exists('id', $fields)) {
@@ -387,7 +390,6 @@ function doAssociations(&$model) {
if (!is_object($model)) {
return false;
}
- App::import('Model');
$this->out(__('One moment while the associations are detected.', true));
$fields = $model->schema();
@@ -415,38 +417,7 @@ function doAssociations(&$model) {
} else {
$this->out(__('Please confirm the following associations:', true));
$this->hr();
- foreach ($associations as $type => $settings) {
- if (!empty($associations[$type])) {
- $count = count($associations[$type]);
- $response = 'y';
- for ($i = 0; $i < $count; $i++) {
- $prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}";
- $response = $this->in("{$prompt}?", array('y','n'), 'y');
-
- if ('n' == low($response) || 'no' == low($response)) {
- unset($associations[$type][$i]);
- } else {
- if ($model->name === $associations[$type][$i]['alias']) {
- if ($type === 'belongsTo') {
- $alias = 'Parent' . $associations[$type][$i]['alias'];
- }
- if ($type === 'hasOne' || $type === 'hasMany') {
- $alias = 'Child' . $associations[$type][$i]['alias'];
- }
-
- $alternateAlias = $this->in(sprintf(__('This is a self join. Use %s as the alias', true), $alias), array('y', 'n'), 'y');
-
- if ('n' == low($alternateAlias) || 'no' == low($alternateAlias)) {
- $associations[$type][$i]['alias'] = $this->in(__('Specify an alternate alias.', true));
- } else {
- $associations[$type][$i]['alias'] = $alias;
- }
- }
- }
- }
- $associations[$type] = array_merge($associations[$type]);
- }
- }
+ $associations = $this->confirmAssociations($model, $associations);
}
$wannaDoMoreAssoc = $this->in(__('Would you like to define some additional model associations?', true), array('y','n'), 'n');
@@ -534,13 +505,19 @@ function findBelongsTo(&$model, $associations) {
$fields = $model->schema();
foreach ($fields as $fieldName => $field) {
$offset = strpos($fieldName, '_id');
- if ($fieldName != $model->primaryKey && $offset !== false) {
+ if ($fieldName != $model->primaryKey && $fieldName != 'parent_id' && $offset !== false) {
$tmpModelName = $this->_modelNameFromKey($fieldName);
$associations['belongsTo'][] = array(
'alias' => $tmpModelName,
'className' => $tmpModelName,
'foreignKey' => $fieldName,
);
+ } elseif ($fieldName == 'parent_id') {
+ $associations['belongsTo'][] = array(
+ 'alias' => 'Parent' . $model->name,
+ 'className' => $model->name,
+ 'foreignKey' => $fieldName,
+ );
}
}
return $associations;
@@ -561,16 +538,29 @@ function findHasOneAndMany(&$model, $associations) {
$pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/';
$possibleJoinTable = preg_match($pattern , $otherTable);
+ if ($possibleJoinTable == true) {
+ continue;
+ }
foreach ($modelFieldsTemp as $fieldName => $field) {
- if ($fieldName != $model->primaryKey && $fieldName == $foreignKey && $possibleJoinTable == false) {
+ $assoc = false;
+ if ($fieldName != $model->primaryKey && $fieldName == $foreignKey) {
$assoc = array(
'alias' => $tempOtherModel->name,
'className' => $tempOtherModel->name,
'foreignKey' => $fieldName
);
+ } elseif ($otherTable == $model->table && $fieldName == 'parent_id') {
+ $assoc = array(
+ 'alias' => 'Child' . $model->name,
+ 'className' => $model->name,
+ 'foreignKey' => $fieldName
+ );
+ }
+ if ($assoc) {
$associations['hasOne'][] = $assoc;
$associations['hasMany'][] = $assoc;
}
+
}
}
return $associations;
@@ -615,6 +605,33 @@ function findHasAndBelongsToMany(&$model, $associations) {
}
return $associations;
}
+/**
+ * Interact with the user and confirm associations.
+ *
+ * @param array $model Temporary Model instance.
+ * @param array $associations Array of associations to be confirmed.
+ * @return array Array of confirmed associations
+ **/
+ function confirmAssociations(&$model, $associations) {
+ foreach ($associations as $type => $settings) {
+ if (!empty($associations[$type])) {
+ $count = count($associations[$type]);
+ $response = 'y';
+ for ($i = 0; $i < $count; $i++) {
+ $prompt = "{$model->name} {$type} {$associations[$type][$i]['alias']}";
+ $response = $this->in("{$prompt}?", array('y','n'), 'y');
+
+ if ('n' == low($response)) {
+ unset($associations[$type][$i]);
+ } elseif ($type == 'hasMany') {
+ unset($associations['hasOne'][$i]);
+ }
+ }
+ $associations[$type] = array_merge($associations[$type]);
+ }
+ }
+ return $associations;
+ }
/**
* Assembles and writes a Model file.
@@ -39,6 +39,7 @@
if (!class_exists('ModelTask')) {
require CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'model.php';
+ require CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'fixture.php';
}
Mock::generatePartial(
@@ -54,6 +55,10 @@
Mock::generate(
'Model', 'MockModelTaskModel'
);
+
+Mock::generate(
+ 'FixtureTask', 'MockModelTaskFixtureTask'
+);
/**
* ModelTaskTest class
*
@@ -66,7 +71,7 @@ class ModelTaskTest extends CakeTestCase {
*
* @var array
**/
- var $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag');
+ var $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag', 'core.category_thread');
/**
* setUp method
@@ -99,20 +104,22 @@ function endTest() {
function testListAll() {
$this->Task->expectAt(1, 'out', array('1. Article'));
$this->Task->expectAt(2, 'out', array('2. ArticlesTag'));
- $this->Task->expectAt(3, 'out', array('3. Comment'));
- $this->Task->expectAt(4, 'out', array('4. Tag'));
+ $this->Task->expectAt(3, 'out', array('3. CategoryThread'));
+ $this->Task->expectAt(4, 'out', array('4. Comment'));
+ $this->Task->expectAt(5, 'out', array('5. Tag'));
$result = $this->Task->listAll('test_suite');
- $expected = array('articles', 'articles_tags', 'comments', 'tags');
+ $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags');
$this->assertEqual($result, $expected);
- $this->Task->expectAt(6, 'out', array('1. Article'));
- $this->Task->expectAt(7, 'out', array('2. ArticlesTag'));
- $this->Task->expectAt(8, 'out', array('3. Comment'));
- $this->Task->expectAt(9, 'out', array('4. Tag'));
+ $this->Task->expectAt(7, 'out', array('1. Article'));
+ $this->Task->expectAt(8, 'out', array('2. ArticlesTag'));
+ $this->Task->expectAt(9, 'out', array('3. CategoryThread'));
+ $this->Task->expectAt(10, 'out', array('4. Comment'));
+ $this->Task->expectAt(11, 'out', array('5. Tag'));
$this->Task->connection = 'test_suite';
$result = $this->Task->listAll();
- $expected = array('articles', 'articles_tags', 'comments', 'tags');
+ $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags');
$this->assertEqual($result, $expected);
}
@@ -133,7 +140,7 @@ function testGetName() {
$expected = 'Article';
$this->assertEqual($result, $expected);
- $this->Task->setReturnValueAt(2, 'in', 3);
+ $this->Task->setReturnValueAt(2, 'in', 4);
$result = $this->Task->getName('test_suite');
$expected = 'Comment';
$this->assertEqual($result, $expected);
@@ -319,6 +326,20 @@ function testBelongsToGeneration() {
)
);
$this->assertEqual($result, $expected);
+
+
+ $model = new Model(array('ds' => 'test_suite', 'name' => 'CategoryThread'));
+ $result = $this->Task->findBelongsTo($model, array());
+ $expected = array(
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'ParentCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ )
+ );
+ $this->assertEqual($result, $expected);
}
/**
@@ -348,6 +369,27 @@ function testHasManyHasOneGeneration() {
),
);
$this->assertEqual($result, $expected);
+
+
+ $model = new Model(array('ds' => 'test_suite', 'name' => 'CategoryThread'));
+ $result = $this->Task->findHasOneAndMany($model, array());
+ $expected = array(
+ 'hasOne' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ ),
+ 'hasMany' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ )
+ );
+ $this->assertEqual($result, $expected);
}
/**
@@ -373,5 +415,17 @@ function testHasAndBelongsToManyGeneration() {
);
$this->assertEqual($result, $expected);
}
+
+/**
+ * Ensure that the fixutre object is correctly called.
+ *
+ * @return void
+ **/
+ function testFixture() {
+ $this->Task->Fixture =& new MockModelTaskFixtureTask();
+ $this->Task->Fixture->expectAt(0, 'bake', array('Article', 'articles'));
+ $this->Task->fixture('Article', 'articles');
+ }
+
}
?>

0 comments on commit 5c48603

Please sign in to comment.