Поддерживает ли доктрина составные ключи в таблицах соединения «многие ко многим»?

У меня есть сущности Channel и Post. Channel имеет простое целое число id. Post имеет составной ключ, состоящий из собственных id и channel_id.

Я хотел бы иметь отношение «многие ко многим» между этими сущностями (упоминание), чтобы у одного Post могло быть много упомянутых Channel, а Channel могло быть упомянуто многими Posts.

Вопрос в том, если это поддерживается Doctrine, как мне реализовать такие отношения?

Domain\Telegram\Models\Channel:
  type: entity
  id:
    id:
      type: integer

  fields:
    name:
      type: string
      nullable: true

  oneToMany:
    posts:
      targetEntity: Domain\Telegram\Models\Post
      mappedBy: channel


Domain\Telegram\Models\Post:
  type: entity
  id:
    channel:
      associationKey: true
    id:
      type: integer

  manyToOne:
    channel:
      targetEntity: Domain\Telegram\Models\Channel
      inversedBy: posts

Обновление и решение

Решение @WilliamPerron почти сработало. При использовании в текущем состоянии doctrine:schema:validate возвращает ошибку:

[Mapping] FAIL — сопоставление класса сущностей 'Domain\Telegram\Models\Channel' недопустимо:

Столбцы обратного соединения таблицы «многие ко многим» «упоминания» должны содержать ВСЕ столбцы идентификаторов целевого объекта «Домен\Telegram\Models\Post», однако «channel_id» отсутствует.

Раздел inverseJoinColumns должен выглядеть так:

    inverseJoinColumns:
      post_id:
        referencedColumnName: id
      post_channel_id:
        referencedColumnName: channel_id

Таким образом, этот тип отношений практически такой же, как и простые отношения «многие ко многим».


person svgrafov    schedule 03.11.2017    source источник


Ответы (1)


Да, это возможно

Вам просто нужно указать, к какой таблице он присоединяется с помощью элемента groups, а затем сущность, с которой он сопоставляется. Для однонаправленных отношений схема будет выглядеть так:

Channel:
  type: entity
  manyToMany:
    posts:
      targetEntity: Post
      joinTable:
        name: posts_channels
        joinColumns:
          channel_id:
            referencedColumnName: id
        inverseJoinColumns:
          post:
            referencedColumnName: id

а для двунаправленных отношений вам нужно будет добавить элемент inversedBy:

Channel:
  type: entity
  manyToMany:
    posts:
      targetEntity: Post
      inversedBy: channels
      joinTable:
        name: posts_channels
        joinColumns:
          channel_id:
            referencedColumnName: id
        inverseJoinColumns:
          post_id:
            referencedColumnName: id

Post:
  type: entity
  manyToMany:
    channels:
      targetEntity: Channel
      mappedBy: posts

Официальную документацию по этому вопросу можно найти здесь.

person William Perron    schedule 03.11.2017
comment
Вы уверены, что ваш ответ относится к ситуации с составными ключами? Насколько я знаю, ваш код не показывает никакой осведомленности об этом. - person svgrafov; 03.11.2017
comment
@svgrafov Самое приятное в отношениях «многие ко многим» в Doctrine заключается в том, что он позаботится о правильном сопоставлении идентификаторов и вернет все связанные записи в ArrayCollection, поэтому нет необходимости использовать составной ключ вообще - person William Perron; 03.11.2017
comment
Можете ли вы обновить свой код (в частности, часть joinColumns), чтобы он был ближе к моей ситуации? - person svgrafov; 03.11.2017