CakePHP contains()方法在同一表的belongsTo上看到belongsToMany

时间:2018-10-29 18:45:56

标签: php mysql cakephp

所以我有以下(简化的)模型

                                +------------------+
                                | project_statuses |
                                +------------------+
+---------------------+    +----| id               |
| projects            |    |    | name             |
+---------------------+    |    +------------------+ 
| id                  |    |    +---------+                
| name                |    |    | clients |            
| project_statuses_id |----+    +---------+                               
| client_id           |---------| id      |            
+---------------------+         | name    |
           |                    +---------+
         +------------------+      |
         | clients_projects |------+
         +------------------+
         | id               |
         | client_id        |
         | project_id       |
         +------------------+

一个项目属于多个客户,一个客户可以有多个项目,但是只有一个客户(Projects.client_id)可以负责一个项目。项目状态仅用于比较。

所以我的ProjectsTable.phpClientsTabe.phpProjectStatusesTable.php中的关联看起来像这样

// In ProjectsTable.php
$this->belongsTo('ProjectStatuses', [
    'foreignKey' => 'project_status_id',
    'joinType' => 'INNER'
]);
$this->belongsTo('Clients', [
    'foreignKey' => 'client_id',
    'joinType' => 'INNER'
]);
$this->belongsToMany('Clients', [
    'foreignKey' => 'project_id',
    'targetForeignKey' => 'client_id',
    'joinTable' => 'clients_projects'
]);

// In ClientsTabe.php
$this->hasMany('Projects', [
    'foreignKey' => 'client_id'
]);
$this->belongsToMany('Projects', [
    'foreignKey' => 'client_id',
    'targetForeignKey' => 'project_id',
    'joinTable' => 'clients_projects'
]);

// In ProjectStatusesTable.php
$this->hasMany('Projects', [
    'foreignKey' => 'project_status_id'
]);

现在在我的projects/index页面上,我想要一个表来显示项目ID,名称,状态和责任。所以我想到了这样的

// In ProjectsController.php
$this->Projects->find()->select(['Projects.id','Projects.name'])
->contain(['ProjectStatuses' => [
    'fields' => [
      'ProjectStatuses.name',
    ]]])
->contain(['Clients' => [
    'fields' => [
      'Clients.name',
    ]]]);

但是仅获取ProjectStatuses.name,因为Clients.name会引发错误You are required to select the "ClientsProjects.project_id" field(s),告诉我正在通过belongsToMany关联而不是belongsTo关联

实际上,如果我只写->contain('Clients')而不是指定Clients.name字段,它将发送以下查询

SELECT 
 Projects.id AS `Projects__id`, 
 Projects.name AS `Projects__name`, 
 ProjectStatuses.name AS `ProjectStatuses__name` 
FROM 
 projects Projects 
INNER JOIN project_statuses ProjectStatuses ON ProjectStatuses.id = (Projects.project_status_id) 

SELECT 
 ClientsProjects.id AS `Clients_CJoin__id`, 
 ClientsProjects.client_id AS `Clients_CJoin__client_id`, 
 ClientsProjects.project_id AS `Clients_CJoin__project_id`, 
 Clients.id AS `Clients__id`, 
 Clients.name AS `Clients__name`,  
FROM 
 clients Clients 
INNER JOIN clients_projects ClientsProjects ON Clients.id = (ClientsProjects.client_id) 
WHERE 
 ClientsProjects.project_id in (4)

我如何告诉查询对象通过Clients.name通过Projects.client_id获取ProjectStatuses.name,就像我通过Projects.project_statuses_id获取ClientProjects而不是通过depends_on表传递一样?

1 个答案:

答案 0 :(得分:1)

在“项目”表中,您为客户端创建了两个关联,反之亦然。那是行不通的(就像高地人所说的,“只能有一个”),很可能是所有问题的根源。

您需要在每个表中更改这些关联之一。也许一个项目应该belongsToMany个客户,但是只有belongTo个ResponsibleClient,一个客户应该belongsToMany个项目和hasMany个ResponsibleProjects?