views:

2321

answers:

2

I have a many-to-many relationship defined in my Symfony (using doctrine) project between Orders and Upgrades (an Order can be associated with zero or more Upgrades, and an Upgrade can apply to zero or more 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: {...}

I want to set up delete cascade behavior so that if I delete an Order or an Upgrade, all of the related OrderUpgrades are deleted. Where do I put onDelete: CASCADE? Usually I would put it at the end of the relations section, but that would seem to imply in this case that deleting Orders would cascade to delete Upgrades. Is Symfony + Doctrine smart enough to know what I'm wanting if I put onDelete: CASCADE in the above relations sections of schema.yml?

+1  A: 

I almost always use Propel but it should be essentially the same. Use: onDelete: CASCADE

Should be:

Order:
  columns:
    order_id: {...}
  relations:
    Upgrades:
      onDelete: CASCADE
      class: Upgrade
      local: order_id
      foreign: upgrade_id
      refClass: OrderUpgrade
Jestep
Just to confirm the desired behavior: with this specification, if I delete an Upgrade, it will delete related OrderUpgrades, but won't delete any Orders?
nselikoff
Actually, the onDelete: CASCADE should be on the Upgrade table and not the Orders table, after looking again. However, given the m2m relationship, this may not work at all. What I'm not understanding about this setup is why wouldn't you have an Orders table, an Upgrades table and have the OrderUpgrade with a foreign key to the other 2. I can't see the whole picture but it would appear to reduce the complexity of this.
Jestep
I tried that at first but couldn't get doctrine:build-model and doctrine:build-sql to work until I defined the m2m relationship as per this page: http://www.doctrine-project.org/documentation/manual/1_0/en/defining-models:relationships:join-table-associations
nselikoff
+1 that onDelete configuration worked for me in SF 1.4. Thanks.
Cryo
+1  A: 

After much trial and error, the only way I was able to get it to work was to follow the suggestion in Jestep's comment and move the relationship definitions including onDelete: CASCADE to the linking table, so in the end it looks like this and behaves how I want it to (deletes cascade from Order to OrderUpgrade, and from Upgrade to 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

I must say I'm got a bit overwhelmed with all of the different Doctrine Many-to-Many YML examples out there on the internet, each with the relations in slightly different places. A frustrating experience.

nselikoff