2016-05-17 124 views
0

我认为这是一个简单的belongsToMany情况,除了关系的名称不是实体表的联名名称。这是因为这种关系是一个非常具体的关系。连接表中没有额外的数据,因此直通选项不是必需的。Cakephp3 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

好吧我发现问题的步骤通过核心源代码几个小时(追踪ORM逻辑是一个真正的痛苦!!)。

关系的另一面,公司,已经从早期在开发周期的这种关系:

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

我从候选人相反的关系取代了它:

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

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

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