Doctrine OneToOne с несколькими таблицами

Я использую доктрину 2 и zend framework 3. У меня есть объект «Проект» с отношением OneToOne к «детали проекта». ProjectDetails разделен между несколькими таблицами в зависимости от типа поля проекта.

Есть ли простой способ сообщить доктрине, какую таблицу использовать для сведений о проекте в зависимости от значения поля типа?


person Lapskaus    schedule 18.09.2017    source источник
comment
Почему бы не сохранить детали объекта проекта? Есть ли какая-то конкретная причина иметь отношение OneToOne?   -  person M Khalid Junaid    schedule 18.09.2017
comment
Детали представляют собой фиксированную информацию из внешнего источника с несколькими источниками, и мне нужна 1 таблица для каждого источника. Они могут меняться в рамках проекта, но мне нужно иметь возможность сравнивать информацию из объекта деталей с информацией из самого проекта.   -  person Lapskaus    schedule 18.09.2017


Ответы (1)


Вы можете определить ассоциации «OneToOne» для каждой таблицы сведений о проекте:

/**
 * @OneToOne(targetEntity="ProjectDetails1")
 * @JoinColumn(name="project_details_id", referencedColumnName="id")
 */
private $projectDetails1;

/**
 * @OneToOne(targetEntity="ProjectDetails2")
 * @JoinColumn(name="project_details_id", referencedColumnName="id")
 */
private $projectDetails2;

Добавьте другие таблицы сведений о проекте. Затем используйте функцию получения, чтобы получить правильное отношение на основе типа:

function getProjectDetails() {
    if($this->type === 'type1') {
        return $this->projectDetails1;
    }
    elseif($this->type === 'type2') {
        return $this->projectDetails2;
    }
}

Обновление: в этом случае вы не можете использовать консольный инструмент доктрины для создания своих ассоциаций, так как будет невозможно установить внешний ключ для "project_details_id" для 2 разных таблиц.

Чтобы решить эту проблему, столбец project_details_id целочисленного типа должен быть создан с помощью миграции или вы можете определить поле в объекте Project:

/**
 * @ORM\Column(type="integer", nullable=true)
 */
private $projectDetailsId;

сгенерируйте и запустите миграцию. Наконец, замените последнее поле приведенными выше ассоциациями.

person Jannes Botis    schedule 18.09.2017
comment
Это было бы хорошо, спасибо. Но есть ли способ создать подкласс для каждого типа деталей проекта? Это всегда один и тот же объект, просто другая таблица. - person Lapskaus; 19.09.2017
comment
@Яннес Ботис! Что произойдет в схеме, если вы запустите доктрину: миграции: миграция? Я предполагаю, что project_id - это PK в таблице проектов, а также PK/FK как для ProjectDetails1, так и для ProjectDetails2. Если вы запустите указанную команду, я увижу проблему с уникальным ключом. Я хочу знать, есть ли что-то на вашем конце. - person Sam; 12.02.2018
comment
К сожалению, в этом случае вы не можете использовать инструмент консоли доктрины для обновления схемы, создания и выполнения миграций. Чтобы преодолеть это, вы можете сначала определить целочисленное поле без ассоциации, сгенерировать и запустить миграцию, а затем использовать вышеуказанные ассоциации. Я обновлю свой ответ, чтобы сделать его более понятным. - person Jannes Botis; 12.02.2018
comment
@Sam Примечание. Я изменил имя с project_id на project_details_id. - person Jannes Botis; 12.02.2018