Doctrine2: использование поля в объединенной таблице в качестве дискриминатора для сопоставленной сущности - PullRequest
1 голос
/ 03 мая 2019

В Doctrine 2 ORM у меня есть абстрактная сущность «Связь», которая использует наследование SINGLE_TABLE, чтобы решить, какой тип связи это:

Communication.orm.yaml:

App\Entity\Communication:

    type: entity
    table: communication

    inheritanceType: SINGLE_TABLE
    discriminatorColumn:
        name: mode
        type: string
    discriminatorMap:
        push: App\Entity\Communication\Push
        notice: App\Entity\Communication\Notice
        email: App\Entity\Communication\Email

# ...

Таким образом, есть 3 типа связи (push, уведомление и электронная почта), которые все используют таблицу «коммуникаций».

Каждая «Связь» является переводимой. Ранее у меня было 3 сущности, содержащие эти переводы. Каждый из этих объектов i18n использует одну и ту же таблицу «i18n_communication» и содержит двунаправленную взаимосвязь «многие к одному» с соответствующим типом связи:

  • App \ Entity \ I18n \ Связь \ Нажмите
  • App \ Entity \ I18n \ Связь \ Примечание
  • App \ Entity \ I18n \ Связь \ Электронная почта

Поскольку в Doctrine 2 использование нескольких сущностей, использующих одну и ту же таблицу без наследования таблиц, недопустимо, я заставил все сущности I18n расширить базовый класс I18nCommunication, аналогично сущностям не-i18n, которые они переводят:

I18nCommunication.orm.yaml:

App\Entity\I18N\Communication\I18nCommunication:

    type: entity
    table: i18n_communication
    inheritanceType: SINGLE_TABLE
    discriminatorColumn:
        name: communication.mode    ******
        type: string
    discriminatorMap:
        push: App\Entity\I18N\Communication\Push
        notice: App\Entity\I18N\Communication\Notice
        email: App\Entity\I18N\Communication\Email
# ...

Это не работает. Все сущности, которые расширяют I18nCommunication, имеют поле «связь», которое ссылается на сущность «Связь», которую они переводят, но Doctrine не знает, что делать с линией «name: communication.mode».

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

Я попытался использоватьоризонтовый тип: JOINED и расширение I18nCommunication от связи, чтобы у меня был доступ к полю режима родителя. Тем не менее, это не работает из-за CommunicationTesignType: SINGLE_TABLE, он думает, что I18nCommunication должен находиться в таблице связи.

Есть ли способ сделать это? Или мне придется прибегнуть к объединению моих объектов I18nCommunication в один объект?

Спасибо.

1 Ответ

0 голосов
/ 06 мая 2019

Это не сработает. DiscriminatorColumn объявляется внутри настраиваемого объекта. Аннотация также, это «EntityAnnotation», а не «PropertyAnnotation».

По какой-то конкретной причине у вас нет ничего похожего на:

class I18nCommunication { ... }
class Push extends I18nCommunication { ... }
class Notice extends I18nCommunication { ... }
class Email extends I18nCommunication { ... }
App\Entity\I18N\Communication\I18nCommunication:

    type: entity
    table: i18n_communication
    inheritanceType: SINGLE_TABLE
    discriminatorColumn:
        name: discr
        type: string

Поскольку вы используете Наследование одной таблицы все данные будут там в любом случае.

Далее, не объявляйте DiscriminatorMap, Doctrine будет обрабатывать это для вас автоматически. См. Последний пункт под ссылкой STI выше:

Если карта дискриминатора не указана, карта генерируется автоматически. Автоматически сгенерированный дискриминатор отображает в качестве ключа краткое имя каждого класса в нижнем регистре.

Кроме того, вы задаете в своем вопросе название:

Использовать поле в объединенной таблице в качестве дискриминатора

Этого никогда не произойдет, просто потому, что эта объединенная таблица будет единственной, которая знает об этих данных. Это не будет доступно для братьев и сестер, поэтому они никогда не узнают, что являются частью чего-то другого.

Как таковое, оно также никогда не создается как нечто доступное.

Дискриминатор, являющийся аннотацией класса, всегда должен происходить с «родителем» распознаваемого лота. В вашем случае: I18nCommunication.

...