首页 文章

CakePHP:从belongsToManay关系中的连接表中重新获取列

提问于
浏览
2

我的应用程序允许用户通过将 soe_blocks 链接在一起来创建 scenarios . 反过来, soe_blocks 引用变量 soe_entries .

要构建 scenariossoe_blocks 链接到 scenario 并按 offset 排序 . soe_blocks 可用于许多不同的 scenarios . soe_entries 只能与一个 soe_block 相关

MySQL Workbench model

我认为这种关系定义为:

  • scenarios belongsToMany soe_blocksscenarios_soe_blocks

  • soe_blocks belongsToMany scenariosscenarios_soe_blocks

  • scenarios_soe_blocks 是保留 offset 的地方

  • soe_entries haveOne soe_blocks

表:

scenarios: id | name
     data: 0, 'scenario_1'

soe_blocks: id | name
      data: 0, 'soe_block_1'
            1, 'soe_block_2'

scenarios_soe_blocks: id | scenario_id | soe_block_id | offset
                data: 1, 0, 1, 1
                      2, 0, 2, 2

楷模:

class ScenariosTable extends Table
{
    $this->belongsToMany('SoeBlocks', [
        'foreignKey' => 'scenario_id',
        'targetForeignKey' => 'soe_block_id',
        'through' => 'ScenariosSoeBlocks',
        'joinTable' => 'soe_blocks'
    ]);
}

class SoeBlocksTable extends Table
{
    $this->belongsToMany('Scenarios', [
        'foreignKey' => 'soe_block_id',
        'targetForeignKey' => 'scenario_id',
        'joinTable' => 'scenarios_soe_blocks',
        'through' => 'ScenariosSoeBlocks'
    ]);
}

class ScenariosSoeBlocksTable extends Table
    $this->belongsTo('SoeBlocks', [
        'foreignKey' => 'soe_block_id',
        'joinType' => 'INNER'
    ]);
}

控制器:

public function view($id = null)
{
    $scenario = $this->Scenarios->get($id, [
        'contain' => ['SoeBlocks', 'RunStatus', 'ScenarioLog']
    ]);

    $this->set('scenario', $scenario);
}

据我所知,CakePHP Doc,这就是我所需要的 . 但我无法让 ScenarioController->view() 方法从与 soe_blocks 关联的 scenarios_soe_blocks 表中返回 offsets .

我尝试将 ScenariosSoeBlocks 添加到ScenarioController的 'contain' 子句中,但得到错误: Scenarios is not associated with ScenariosSoeBlocks . 我发现了一篇SO文章建议我将以下内容添加到ScenarioTable中:

$this->hasMany('ScenariosSoeBlocks', [
        'foreignKey' => 'scenario_id'
    ]);

这似乎有效,现在我可以在我的控制器中请求 ScenariosSoeBlocks ,如下所示:

$scenario = $this->Scenarios->get($id, [
   'contain' => ['SoeBlocks', 'ScenariosSoeBlocks', 'RunStatus', 'ScenarioLog']
]);

至少将数据放入视图模板,但不是我希望的单个对象 . 最终,我希望能够在一个看起来像这样的对象中将 soe_blocks 及其关联的 soe_entries 与CRUD一起:

offset | soe_block_id | soe_entry_id |

我还有很多其他的问题,比如如何保存等等,但我认为我需要先让它工作 .

所以,我现在的问题是:

  • 我的协会是否正确?

  • 如何检索要查看的所有关联?

1 回答

  • 1

    我的协会是否正确?

    前两个是,但它应该是:

    • soe_blocks hasOne soe_entries

    • soe_entries belongsTo soe_blocks

    如何检索要查看的所有关联?

    通过包含它们,就像你在第一个例子中所做的那样 . 这个问题似乎源于如何访问连接表数据的问题,这很简单,连接表数据是在目标表实体上设置的( ScenarioSoeBlock ,具体取决于您发出查询的哪一方/表) ,在名为 _joinData 的属性中:

    $joinTableEntity = $scenario->soe_blocks[0]->_joinData;
    $offset = $joinTableEntity->offset;
    

    您可以通过转储实体内容轻松收集有关数据结构的信息:

    debug($scenario);
    

    也可以看看

    • Cookbook > Database Access & ORM > Associations - Linking Tables Together

    • Cookbook > Database Access & ORM > Saving Data > Saving Additional Data to the Join Table

相关问题