Метод CakePHP contain () видит, что принадлежитToMany вместо принадлежитTo той же таблицы

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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Это сработало как шарм :) Думаю, теперь я понял важность псевдонимов, большое вам спасибо!

AronNeewart 30.10.2018 01:53

Другие вопросы по теме