Где в symfony/doctrine's schema.yml я должен поставить OnDelete: CASCADE для отношений "многие ко многим"?

У меня есть отношения многие ко многим, определенные в моем проекте Symfony (с использованием доктрины) между Orders а также Upgrades (Order может быть связано с нулем или более Upgradesи Upgrade может применяться к нулю или более Orders).

# schema.yml

Order:
  columns:
    order_id: {...}
  relations:
    Upgrades:
      class: Upgrade
      local: order_id
      foreign: upgrade_id
      refClass: OrderUpgrade

Upgrade:
  columns:
    upgrade_id: {...}
  relations:
    Orders:
      class: Order
      local: upgrade_id
      foreign: order_id
      refClass: OrderUpgrade

OrderUpgrade:
  columns:
    order_id: {...}
    upgrade_id: {...}

Я хочу настроить каскадное поведение, чтобы при удалении Order или Upgrade, все связанные OrderUpgrades удалены. Куда я положу onDelete: CASCADE? Обычно я ставлю это в конце раздела отношений, но в данном случае это может означать, что удаление Orders будет каскадом удалить Upgrades, Является ли Symfony + Doctrine достаточно умным, чтобы знать, чего я хочу, если я поставлю onDelete: CASCADE в приведенных выше разделах отношений schema.yml?

3 ответа

Решение

После долгих проб и ошибок единственный способ, которым я смог заставить его работать, состоял в том, чтобы следовать предложению в комментарии Джестепа и перенести определения отношений, включая onDelete: CASCADE, в таблицу ссылок, так что в итоге это выглядит так и ведет себя как Я хочу это (удаляет каскад из Order to OrderUpgrade и из Upgrade в OrderUpgrade):

# schema.yml

Order:
  columns:
    order_id: {...}

Upgrade:
  columns:
    upgrade_id: {...}

OrderUpgrade:
  columns:
    order_id: { type: integer, notnull: true, primary: true }
    upgrade_id: { type: integer, notnull: true, primary: true }
  relations:
    Order:
      onDelete: CASCADE
    Upgrade:
      onDelete: CASCADE

Я должен сказать, что я немного ошеломлен всеми различными примерами YML Doctrine "многие ко многим" в Интернете, каждый из которых имеет отношения в немного разных местах. Расстраивающий опыт.

Мне надоело гуглить по этому поводу каждый раз, когда мне нужно каскадировать отношения между многими и многими и находить неполные ответы, так что вот мое мнение, которое на данный момент является наиболее полным из доступных.

После простого теста я пришел к выводу, что вы должны определить отношения во всех трех объектах.
- Выполнение этого только в двух объектах, к которым вы хотите присоединиться, работает хорошо, за исключением каскадной части.
- Выполнение этого только в таблице соединений (OrderUpgrade) работает, но вы не получите код формы и фильтра форм, сгенерированный в ваших 2 сущностях.
- Выполнение этого во всех трех сущностях даст вам оба мира.

В следующем примере, который является многословным, но я предпочитаю это так:
- если вы удалите Свойство, соответствующая запись PropertyLandlord будет удалена, а запись об Арендодателе останется нетронутой.
- если вы удалите Арендодателя, то же самое.
- и если вы удаляете запись PropertyLandlord, она только удаляет запись ссылки и оставляет нетронутой, что, я думаю, является поведением, которое мы в основном ищем.

Property:
  columns:
    id:
      type: integer(8)
      primary: true
      autoincrement: true
    title:
      type: string(255)
      notnull: true
  relations:
    Landlords:
      class: Landlord
      local: property_id
      foreign: landlord_id
      refClass: PropertyLandlord

Landlord:
  columns:
    id:
      type: integer(8)
      primary: true
      autoincrement: true
    title:
      type: string(255)
      notnull: true
  relations:
    Properties:
      class: Property
      local: landlord_id
      foreign: property_id
      refClass: PropertyLandlord
      onDelete: CASCADE

PropertyLandlord:
  columns:
    property_id:
      type: integer(8)
      primary: true
      notnull: true
    landlord_id:
      type: integer(8)
      primary: true
      notnull: true
  relations:
    Property:
      local: property_id
      foreign: id
      class: Property
      onDelete: CASCADE
    Landlord:
      local: landlord_id
      foreign: id
      class: Landlord
      onDelete: CASCADE

Я почти всегда использую Propel, но он должен быть практически одинаковым. Использование: onDelete: CASCADE

Должно быть:

Order:
  columns:
    order_id: {...}
  relations:
    Upgrades:
      onDelete: CASCADE
      class: Upgrade
      local: order_id
      foreign: upgrade_id
      refClass: OrderUpgrade
Другие вопросы по тегам