Skip to content

Commit

Permalink
Ensure generated entity classes include association fields.
Browse files Browse the repository at this point in the history
Because composer caches whether or not a class exists, we cannot simply
reload the table class once it has been created. Instead if bake is
using a base Table instance, we can add the associations that would be
present into the table. This allows the entity's `$_accessible`
attribute to be correctly generated.

Refs #3715
  • Loading branch information
markstory committed Jun 15, 2014
1 parent c3824d2 commit 9a6a7cb
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/Console/Command/Task/ModelTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ public function main($name = null) {
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);
Expand Down Expand Up @@ -186,6 +189,26 @@ public function getAssociations(Table $table) {
return $associations;
}

/**
* 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.
*
Expand Down
75 changes: 75 additions & 0 deletions tests/TestCase/Console/Command/Task/ModelTaskTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

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;
Expand Down Expand Up @@ -156,6 +157,80 @@ public function testGetAssociationsNoFlag() {
$this->assertEquals([], $this->Task->getAssociations($articles));
}

/**
* 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
*
Expand Down

0 comments on commit 9a6a7cb

Please sign in to comment.