Browse Source

Merge pull request #3719 from cakephp/3.0-bake-entity-associations

Ensure generated entity classes include association fields.
José Lorenzo Rodríguez 11 years ago
parent
commit
3a7a79d42d

+ 23 - 0
src/Console/Command/Task/ModelTask.php

@@ -99,7 +99,10 @@ class ModelTask extends BakeTask {
 	public function bake($name) {
 		$table = $this->getTable($name);
 		$model = $this->getTableObject($name, $table);
+
 		$associations = $this->getAssociations($model);
+		$this->applyAssociations($model, $associations);
+
 		$primaryKey = $this->getPrimaryKey($model);
 		$displayField = $this->getDisplayField($model);
 		$fields = $this->getFields($model);
@@ -187,6 +190,26 @@ class ModelTask extends BakeTask {
 	}
 
 /**
+ * Sync the in memory table object.
+ *
+ * Composer's class cache prevents us from loading the
+ * newly generated class. Applying associations if we have a
+ * generic table object means fields will be detected correctly.
+ */
+	public function applyAssociations($model, $associations) {
+		if (get_class($model) !== 'Cake\ORM\Table') {
+			return;
+		}
+		foreach ($associations as $type => $assocs) {
+			foreach ($assocs as $assoc) {
+				$alias = $assoc['alias'];
+				unset($assoc['alias']);
+				$model->{$type}($alias, $assoc);
+			}
+		}
+	}
+
+/**
  * Find belongsTo relations and add them to the associations list.
  *
  * @param \Cake\ORM\Table $model Database\Table instance of table being generated.

+ 75 - 0
tests/TestCase/Console/Command/Task/ModelTaskTest.php

@@ -16,6 +16,7 @@ namespace Cake\Test\TestCase\Console\Command\Task;
 
 use Cake\Console\Command\Task\ModelTask;
 use Cake\Console\Command\Task\TemplateTask;
+use Cake\Core\Configure;
 use Cake\Core\Plugin;
 use Cake\Model\Model;
 use Cake\ORM\TableRegistry;
@@ -157,6 +158,80 @@ class ModelTaskTest extends TestCase {
 	}
 
 /**
+ * Test applying associations.
+ *
+ * @return void
+ */
+	public function testApplyAssociations() {
+		$articles = TableRegistry::get('BakeArticles');
+		$assocs = [
+			'belongsTo' => [
+				[
+					'alias' => 'BakeUsers',
+					'foreignKey' => 'bake_user_id',
+				],
+			],
+			'hasMany' => [
+				[
+					'alias' => 'BakeComments',
+					'foreignKey' => 'bake_article_id',
+				],
+			],
+			'belongsToMany' => [
+				[
+					'alias' => 'BakeTags',
+					'foreignKey' => 'bake_article_id',
+					'joinTable' => 'bake_articles_bake_tags',
+					'targetForeignKey' => 'bake_tag_id',
+				],
+			],
+		];
+		$original = $articles->associations()->keys();
+		$this->assertEquals([], $original);
+
+		$this->Task->applyAssociations($articles, $assocs);
+		$new = $articles->associations()->keys();
+		$expected = ['bakeusers', 'bakecomments', 'baketags'];
+		$this->assertEquals($expected, $new);
+	}
+
+/**
+ * Test applying associations does nothing on a concrete class
+ *
+ * @return void
+ */
+	public function testApplyAssociationsConcreteClass() {
+		Configure::write('App.namespace', 'TestApp');
+		$articles = TableRegistry::get('Articles');
+		$assocs = [
+			'belongsTo' => [
+				[
+					'alias' => 'BakeUsers',
+					'foreignKey' => 'bake_user_id',
+				],
+			],
+			'hasMany' => [
+				[
+					'alias' => 'BakeComments',
+					'foreignKey' => 'bake_article_id',
+				],
+			],
+			'belongsToMany' => [
+				[
+					'alias' => 'BakeTags',
+					'foreignKey' => 'bake_article_id',
+					'joinTable' => 'bake_articles_bake_tags',
+					'targetForeignKey' => 'bake_tag_id',
+				],
+			],
+		];
+		$original = $articles->associations()->keys();
+		$this->Task->applyAssociations($articles, $assocs);
+		$new = $articles->associations()->keys();
+		$this->assertEquals($original, $new);
+	}
+
+/**
  * Test getAssociations
  *
  * @return void