В методе CakePHP contains () обнаруживается принадлежность ToTany к принадлежащему той же таблицы. - PullRequest
0 голосов
/ 29 октября 2018

Итак, у меня есть следующая (упрощенная) модель

                                +------------------+
                                | 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.php, ClientsTabe.php и ProjectStatusesTable.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 я бы хотел иметь таблицу с идентификатором проекта, именем, статусом и ответственным лицом. Вот я и подумал примерно так

// 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?

1 Ответ

0 голосов
/ 29 октября 2018

В вашей таблице Projects вы создали две ассоциации для клиентов и наоборот. Это не работает (как сказал Горец: «Может быть только один») и, вероятно, является источником всех ваших проблем.

Вам нужно будет изменить одну из этих ассоциаций в каждой таблице. Может быть, Проект должен belongsToMany Клиентов, но только belongTo один ResponsibleClient, а Клиент должен belongsToMany Проектов и hasMany ReponsibleProjects?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...