【问题标题】:CakePHP: Retreiving a column from the join table in a belongsToManay relationshipCakePHP:从 belongsToMany 关系中的连接表中检索列
【发布时间】:2018-09-15 10:36:10
【问题描述】:

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

要构建scenariossoe_blocks 链接到scenario 并由offset 排序。 soe_blocks 可以用于许多不同的scenariossoe_entries 只能与单个 soe_block 关联

认为关系定义为:

  • scenarios belongsToMany soe_blocksscenarios_soe_blocks
  • soe_blocks belongsToMany scenariosscenarios_soe_blocks
  • scenarios_soe_blocks 是保存 offset 的位置
  • soe_entrieshaveOne 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 | 

我还有很多其他问题,比如如何保存等,但我想我需要先解决这个问题。

所以,我现在的问题是:

  • 我的关联正确吗?
  • 如何检索所有要查看的关联?

【问题讨论】:

    标签: php cakephp cakephp-3.0 has-and-belongs-to-many jointable


    【解决方案1】:

    我的联想正确吗?

    前两个是,但后来应该是:

    • soe_blockshasOne soe_entries
    • soe_entries 属于soe_blocks

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

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

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

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

    debug($scenario);
    

    另见

    【讨论】:

    • 感谢您的回复。我发现我犯的错误是为连接表创建一个控制器,而事实上,这应该是不透明的。您对这两个缺失的关系描述是正确的 - 我将它们省略了,因为我更关注问题的连接表部分。
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2018-05-19
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多