У меня есть база данных с таблицей projekte (немецкое слово для проектов). Некоторые проекты имеют отношение друг к другу. Итак, я хотел бы иметь отношение BTM.
Я создал joinTable «projektverbindungen» со следующими полями:
projekt_id
nebenprojekt_id
Я нашел здесь похожий вопрос: Связь между таблица и сама , и я попробовал ответить ndm, но безуспешно.
Вот моя ProjekteTable. php
class ProjekteTable extends Table {
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('projekte');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->hasOne('Projekteigenschaften', [
'foreignKey' => 'projekt_id',
'dependent' => true,
]);
$this->belongsToMany('Projekte', [
'foreignKey' => 'projekt_id',
'targetForeignKey' => 'nebenprojekt_id',
'joinTable' => 'projektverbindungen',
]);
}
}
Вот мой шаблон (add.ctp )
<?php
echo $this->Form->create($projekt);
echo $this->Form->control('name', ['class' => 'form-control']);
echo $this->Form->control('projekteigenschaft.projektverantwortlich');
echo $this->Form->control('projekteigenschaft.beschreibung');
echo $this->Form->control('projekte._ids', ['options' => $projekte, 'multiple' => true]);
echo $this->Form->button(__('Submit'));
echo $this->Form->end();
?>
Первый шаг, сохранение проекта со связанным проектом, работает должным образом. id
созданного проекта был сохранен как projektverbindungen.projekt_id
, а id
связанного проекта как projektverbindungen.nebenprojekt_id
.
Когда я запрашиваю проект без связи с другими проектами, например:
$projekt = $this->Projekte->get($id, [
'contain' => ['Projekteigenschaften']
]);
запрос выглядит так:
SELECT Projekte.id AS `Projekte__id`, Projekte.name AS `Projekte__name`, Projekteigenschaften.id AS `Projekteigenschaften__id`, Projekteigenschaften.projektverantwortlich AS `Projekteigenschaften__projektverantwortlich`, Projekteigenschaften.beschreibung AS `Projekteigenschaften__beschreibung`, Projekteigenschaften.projekt_id AS `Projekteigenschaften__projekt_id` FROM projekte Projekte LEFT JOIN projekteigenschaften Projekteigenschaften ON Projekte.id = (Projekteigenschaften.projekt_id) WHERE (Projekte.id = :c0 AND (Projekte.deleted) IS NULL)
А результат отладки выглядит так:
"id": "6862279f-8134-401f-86ff-9278a3bfa5c3",
"name": "My Project",
"projekteigenschaft": {
"id": "89d9e241-e700-4c31-9266-ee5717f2a0aa",
"projektverantwortlich": "Blisginnis, Ralf",
"beschreibung": ""
}
Все работает нормально.
Но когда я добавляю проекты, которые будут содержать вот так:
$projekt = $this->Projekte->get($id, [
'contain' => ['Projekteigenschaften', 'Projekte']
]);
Запрос выглядит так же, как указано выше, но сущность выглядит немного иначе:
"Projekteigenschaften": {
"id": "89d9e241-e700-4c31-9266-ee5717f2a0aa",
"projektverantwortlich": "Blisginnis, Ralf",
"beschreibung": ""
}
Projekteigenschaften, похоже, больше не быть отношением hasOne, и "Projekte" полностью игнорируется.
Кто-нибудь знает, что я сделал не так? Или я должен предпочесть другой способ сделать это?
редактировать после комментария ndm
Я попытался определить отношения следующим образом:
$this->belongsToMany('Projektverbindungen', [
'class' => 'Projekte',
'foreignKey' => 'projekt_id',
'targetForeignKey' => 'nebenprojekt_id',
'joinTable' => 'projektverbindungen',
]);
и изменил шаблон add.ctp следующим образом:
echo $this->Form->control('projektverbindungen._ids', ['options' => $projekte, 'multiple' => true]);
Но тогда связь не сохраняется.
Я также попытался переименовать joinTable в projekte_projekte. Похоже, это не имело никакого значения.
Затем я попытался использовать сквозную опцию, но результаты были еще хуже. Поэтому я продолжил попытки найти решение с помощью описанного выше метода.
2-е редактирование
projekverbindungen ist доступно в Projekt. php:
protected $_accessible = [
'name' => true,
'projekteigenschaft' => true,
'projekte' => true,
'projektverbindungen' => true,
];
Отладка requestData:
[
'name' => 'My Project',
'projekteigenschaft' => [
'projektverantwortlich' => 'John Doe',
'beschreibung' => '',
'projektverbindungen' => [
'_ids' => [
(int) 0 => '809031f2-4ecd-4dfb-82d5-2c911286dd21'
]
]
]
Отладка объекта после исправления:
object(App\Model\Entity\Projekt) {
'name' => 'My Project',
'projekteigenschaft' => object(App\Model\Entity\Projekteigenschaft) {
'projektverantwortlich' => 'John Doe',
'beschreibung' => '',
'[new]' => true,
'[accessible]' => [
'projektverantwortlich' => true,
'beschreibung' => true,
'projekt_id' => true,
'projekt' => true
],
'[dirty]' => [
'projektverantwortlich' => true,
'beschreibung' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Projekteigenschaften'
},
'projektverbindungen' => [],
'[new]' => true,
'[accessible]' => [
'name' => true,
'projekteigenschaft' => true,
'projekte' => true,
'projektverbindungen' => true
],
'[dirty]' => [
'name' => true,
'projekteigenschaft' => true,
'projektverbindungen' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Projekte'
}
3-е изменение
В моем bootstrap . php у меня это:
Inflector::rules('plural', [
'/^(projekt)$/i' => '\1e',
'/^(projekteigenschaft|projektverbindung)$/i' => '\1en',
]);
Inflector::rules('singular', [
'/^(projekt)e$/i' => '\1',
'/^(projekteigenschaft|projektverbindung)en$/i' => '\1',
]);
После вашей рекомендации я дополнительно добавил propertyName
к определению ассоциации:
$this->belongsToMany('Projektverbindungen', [
'class' => 'Projekte',
'propertyName' => 'Projektverbindungen',
'foreignKey' => 'projekt_id',
'targetForeignKey' => 'nebenprojekt_id',
'joinTable' => 'projektverbindungen',
]);
После этого исправленная сущность выглядит как это:
object(App\Model\Entity\Projekt) {
'name' => 'My Project',
'projekteigenschaft' => object(App\Model\Entity\Projekteigenschaft) {
'projektverantwortlich' => 'John Doe',
'beschreibung' => '',
'[new]' => true,
'[accessible]' => [
'projektverantwortlich' => true,
'beschreibung' => true,
'projekt_id' => true,
'projekt' => true
],
'[dirty]' => [
'projektverantwortlich' => true,
'beschreibung' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Projekteigenschaften'
},
'projektverbindungen' => [
'_ids' => [
(int) 0 => '1e28a3d1-c914-44be-b821-0e87d69cd95f'
]
],
'[new]' => true,
'[accessible]' => [
'name' => true,
'projekteigenschaft' => true,
'projekte' => true,
'projektverbindungen' => true
],
'[dirty]' => [
'name' => true,
'projekteigenschaft' => true,
'projektverbindungen' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Projekte'
}
Но все еще нет новой записи в таблице "projektverbindungen"