TableRegistry关联与模型关联

时间:2018-01-14 16:49:06

标签: cakephp cakephp-3.0

我希望Bake在同一个表之间允许多个外键。多个belongsTo和多个HABTM(使用多个joinTables)。

我对belongsTo部分没有任何问题,但我正在努力实现多个HABTM表。 我的语法如下:

[joinTable, prefix, [joined Tables Array]],
["in_protocols_plant_controllers", "in", ["protocols", "plant_controllers"]], 
["out_protocols_plant_controllers", "out", ["protocols", "plant_controllers"]]

前缀用于生成不同的别名关联名称。 我编辑了ModelTask​​,我的模型文件现在看起来我想要它。 这是我在return $associations之前添加到ModelTask​​.findBelongsToMany()的内容。

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;
    }
}

我的power_analyzers协会看起来像

[
    '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'
        ]
    ]
]

我没有在ModelTask​​中的findbelongsto()中编辑我的任务中的任何其他内容,以获取我的多个belongsTo逻辑和上面的代码。

但由于某种原因,TableRegistry :: get()返回的不是现有的关联,我不知道如何解决这个问题。 ControllerTask.php中的TableRegistry :: get()返回函数bake()这个mode_bject 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'

}

这是我database schema的剪辑。它返回power_analyzers和power_controller_features与in_protocols_plan_controllers和out_protocols_plant_controllers连接,反之亦然。在ModelTask​​中没有返回此关联。

TableRegistry的信息保存在哪里?为什么它会保存未在相应模型文件中列出的关联?我如何通过TableRegistry修复?我希望你能帮助我。

TableRegistry绝对从ModelTask​​检索数据,但为什么它连接不同的HABTM关联?如果没有我的修改,它就不会。

我遇到此问题,因为我的控制器现在试图在其查找中包含不存在的关联。

感谢您的帮助!

修改

我尝试了更多的东西并弄清楚,当ModelTask​​.php正在运行时,tableobject会发生变化。在协议表的ModelTask​​ bake()完成之后(在$ this-> bakeTest之后但在函数结束之前)添加了两个不需要的关联。这是介绍关联的表。 但我无法弄清楚为什么协议的关联也被添加到power_analyzers协会。让我更困惑的是桌面对象在bakeTest()之后发生了变化。到底该怎么做才能与协会做关系。

如果我知道关联(int) 2 => 'plantcontrollerspoweranalyzers',被添加到tableobject的位置,它可能对我有所帮助。这是一种通缉行为。我认为我的修改不起作用,我必须修改那部分。

我的烘烤过程总是很干净。我正在使用python脚本删除所有旧东西,然后烘烤。

到目前为止,感谢您的帮助!

编辑2:

从Table :: belongsToMany()中找到一条跟踪。接下来的几天我会对此进行调查。

########## 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

1 个答案:

答案 0 :(得分:0)

我发现TestTask正在运行调用 Cake\ORM\Association::junction() 的所有关联,这会增加“缺失”关联。我不想编辑cakephp的核心文件。相反,我通过在 TestTask::_processModel()

的开头添加此代码来避免TestTask调用联结函数
foreach (Configure::read("specialBelongsToMany") as $elem) {
    $joinTableName = $elem[0];
    $prefix = $elem[1];
    $conTables = $elem[2];

    foreach ($conTables as $conTable) {
        $conAlias = Inflector::camelize($prefix . "_" . $conTable);
        if ($conAlias == $subject->alias()) {
            return;
        }
    }
}