Итак, у меня есть следующая (упрощенная) модель
+------------------+
| 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
?