i want Bake to allow multiple foreign keys between the same tables. Multiple belongsTo and multiple HABTM (using multiple joinTables).
I have no problems with the belongsTo part, but i am struggling with implementing multiple HABTM tables. My syntax looks like this:
[joinTable, prefix, [joined Tables Array]],
["in_protocols_plant_controllers", "in", ["protocols", "plant_controllers"]],
["out_protocols_plant_controllers", "out", ["protocols", "plant_controllers"]]
The prefix is used for producing different alias association names.
I edited the ModelTask and my model file looks now how i want it to.
This is what i added to ModelTask.findBelongsToMany( ) before return $associations
.
foreach (Configure::read("specialBelongsToMany") as $elem) {
$joinTableName = $elem[0];
if (!in_array($joinTableName, $tables)) { debug($elem); die(); }
$prefix = $elem[1];
$conTables = $elem[2];
$currIndex = array_search($tableName, $conTables);
if ($currIndex !== false) {
$otherIndex = $currIndex == 0 ? 1 : 0;
$otherTableName = $conTables[$otherIndex];
if (!in_array($otherTableName, $tables)) { debug($elem); die(); }
$assoc = [
'alias' => $this->_camelize($prefix . "_" . $otherTableName),
'className' => $this->_camelize($otherTableName),
'foreignKey' => $this->_modelKey($tableName),
'targetForeignKey' => $this->_modelKey($otherTableName),
'joinTable' => $joinTableName
];
$associations['belongsToMany'][] = $assoc;
}
}
My power_analyzers association produced by this looks like
[
'belongsTo' => [
(int) 0 => [
'alias' => 'Manufacturers',
'className' => 'Contacts',
'foreignKey' => 'manufacturer_id'
]
],
'hasMany' => [],
'belongsToMany' => [
(int) 0 => [
'alias' => 'PlantControllers',
'foreignKey' => 'power_analyzer_id',
'targetForeignKey' => 'plant_controller_id',
'joinTable' => 'plant_controllers_power_analyzers'
]
]
]
I didnt edited any other stuff in my tasks besides findbelongsto() in ModelTask for my multiple belongsTo logic and the above code.
But for some reason TableRegistry::get() is returning not existing associations and i dont know how to fix this. TableRegistry::get() in ControllerTask.php returns in function bake() this modelobject for power_analyzers
object(App\Model\Table\PowerAnalyzersTable) {
'registryAlias' => 'PowerAnalyzers',
'table' => 'power_analyzers',
'alias' => 'PowerAnalyzers',
'entityClass' => 'App\Model\Entity\PowerAnalyzer',
'associations' => [
(int) 0 => 'manufacturers',
(int) 1 => 'plantcontrollers',
(int) 2 => 'plantcontrollerspoweranalyzers',
**(int) 3 => 'inplantcontrollers',** // i dont want this
**(int) 4 => 'outplantcontrollers'** // i dont want this
],
'behaviors' => [
(int) 0 => 'Timestamp',
(int) 1 => 'Search'
],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
Here is a snipped of my database schema. It returns that power_analyzers and power_controller_features are connected with in_protocols_plan_controllers and out_protocols_plant_controllers, vice versa. This association isnt returned in ModelTask.
Where is the information for TableRegistry saved? Why does it save associations which aren't listed in the corresponding model file? How can i fix by TableRegistry? I hope you can help me.
TableRegistry is definitly retrieving data from ModelTask, but why does it connect different HABTM associations? Without my modification it does not.
I have problems with this because my Controllers now try to contain the not existing associations in their find.
Thanks for your help!
Edit:
I tried something more and figured out, that the tableobject changes while ModelTask.php is running. The two unwanted associations get added after protocol table's ModelTask bake() is done (after $this->bakeTest but before end of function). This is the table which introduces the associations. But i couldnt figure out why the associations of protocols were also added to power_analyzers associations. And what makes me more confused is that the tableobject changes after bakeTest(). What the hell has bakeTest to do with associations.
Maybe it would help me, if I knew where the association (int) 2 => 'plantcontrollerspoweranalyzers',
got added to the tableobject. This is a wanted behaviour. I think that my modification doesnt work with it and i have to modify that part.
My bake processes are always clean. I am using a python script deleting all old stuff before bake.
Thanks for your help so far!
Edit 2:
Found a trace from Table::belongsToMany(). I will look into this the next days.
########## DEBUG ##########
'power_analyzers InPlantControllers'
###########################
Cake\ORM\Table::belongsToMany() - CORE\src\ORM\Table.php, line 1117
Cake\ORM\Association\BelongsToMany::_generateTargetAssociations() - CORE\src\ORM\Association\BelongsToMany.php, line 364
Cake\ORM\Association\BelongsToMany::junction() - CORE\src\ORM\Association\BelongsToMany.php, line 322
Bake\Shell\Task\TestTask::_processModel() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 459
Bake\Shell\Task\TestTask::_processModel() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 456
Bake\Shell\Task\TestTask::_processModel() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 456
Bake\Shell\Task\TestTask::_processModel() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 456
Bake\Shell\Task\TestTask::_processModel() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 456
Bake\Shell\Task\TestTask::generateFixtureList() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 424
Bake\Shell\Task\TestTask::bake() - ROOT\vendor\cakephp\bake\src\Shell\Task\TestTask.php, line 231
App\Shell\Task\ModelTask::bakeTest() - APP/Shell\Task\ModelTask.php, line 1195
App\Shell\Task\ModelTask::bake() - APP/Shell\Task\ModelTask.php, line 118
App\Shell\Task\ModelTask::main() - APP/Shell\Task\ModelTask.php, line 101
Bake\Shell\BakeShell::Bake\Shell\{closure}() - ROOT\vendor\cakephp\bake\src\Shell\BakeShell.php, line 259
Cake\Collection\Collection::each() - CORE\src\Collection\CollectionTrait.php, line 51
Bake\Shell\BakeShell::all() - ROOT\vendor\cakephp\bake\src\Shell\BakeShell.php, line 260
Cake\Console\Shell::runCommand() - CORE\src\Console\Shell.php, line 493
Cake\Console\CommandRunner::run() - CORE\src\Console\CommandRunner.php, line 141
[main] - ROOT\bin\cake.php, line 12
TableRegistry::get()
will return what it's being asked for, either a concrete table class instance for the given alias, or an auto-table (that is an instance of\Cake\ORM\Table
), it has no involvement with associations. I think you need to add more details to your question (including yourTableRegistry::get()
usage and possibly the modified task code), as it's really hard to tell where in your code, what technical problem it is exactly that you are experiencing. – ndm\Cake\ORM\Table::addAssociations()
and\Cake\ORM\Table::belongsToMany()
, then you'll see from where the methods are being invoked (if at all). All I can do from here without seeing the full context, is shooting into the dark, which isn't too helpful. – ndm