Cakephp3属于ToMany查询未正确生成

时间:2016-05-17 20:42:11

标签: cakephp-3.0

我认为这是一个简单的belongsToMany情况,但关系的名称不是实体表的联合名称。这是因为这种关系非常具体。在连接表中没有保留额外数据,因此不需要通过选项。

实体:

table candidates {
  id int,
  <other fields>
}

table companies {
  id int,
  <other fields>
}

加入表格(允许候选人将公司列入黑名单):

table blacklists {
  id int,
  candidate_id int,
  company_id int
}

CandidatesTable.php:

 $this->belongsToMany('BlacklistedCompanies', [
            'className' => 'Companies',
            'joinTable' => 'blacklists',
            'foreignKey' => 'candidate_id',
            'targetForeignKey' => 'company_id'              
    ]);

在控制器中查询:

$bl = $this->Candidates->find("all")->where(["id" => 1])->contain("BlacklistedCompanies")->all();

运行时,会生成以下错误查询并引发错误(1054未知列) - 请参阅底部带箭头的行:

SELECT 
    Blacklists.company_id AS `Blacklists__company_id`, 
    Blacklists.id AS `Blacklists__id`, 
    Blacklists.candidate_id AS `Blacklists__candidate_id`, 
    BlacklistedCompanies.id AS `BlacklistedCompanies__id`, 
    <remaining companies fields expunged>
FROM companies BlacklistedCompanies 
LEFT JOIN blacklists Blacklists ON 
    (BlacklistedCompanies.id = (Blacklists.company_id) 
      AND Blacklists.id = (Blacklists.blacklist_id)) <<-- ERROR!!
WHERE Blacklists.candidate_id in (:c0)

为什么CakePHP正在寻找blacklist_id?它不存在于任何地方。黑名单是一个连接表,而不是具有在任何地方引用它的外键的实体!!

我做错了什么?

1 个答案:

答案 0 :(得分:1)

好的,我通过核心源代码踩了几个小时找到了问题(跟踪ORM逻辑是一个真正的痛苦!!)。

关系的另一方,公司,在开发周期的早期就有这种关系:

    $this->belongsToMany('Blacklists', [
            'className' => 'Candidates',
            'joinTable' => 'Blacklists'
    ]);

我用候选人的反向关系取而代之:

    $this->belongsToMany('BlacklistingCandidates', [
            'className' => 'Candidates',
            'joinTable' => 'Blacklists',
            'foreignKey' => 'company_id',
            'targetForeignKey' => 'candidate_id',                       
    ]);

它似乎按预期工作。我怀疑缺少外键提示是罪魁祸首。

所以CakePHP3课#1342:确保你的belongsToMany关系是对称的!