我认为这是一个简单的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?它不存在于任何地方。黑名单是一个连接表,而不是具有在任何地方引用它的外键的实体!!
我做错了什么?
答案 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关系是对称的!