views:

74

answers:

2

This is a strange one

Take this schema:

Contact:
  actAs: [Timestampable,SoftDelete]
  columns:
    first_name:  { type: string(255), notnull: true }
    second_name:  { type: string(255), notnull: true }
  relations:
    Forums:
      class: Forum
      refClass: ContactForum
      local: forum_id
      foreign: contact_id 
      foreignAlias: Contacts
    ContactForums:
      local: id
      foreign: contact_id
      class: ContactForum
      type: many
      foreignType: one
      cascade: [delete]

Forum:
  actAs: [Timestampable,SoftDelete]
  columns:
    name:  { type: string(255), notnull: true }
  relations:
    ContactForums:
      class: ContactForum
      local: id
      foreign: forum_id
      type: many
      cascade: [delete]

ContactForum:
  actAs: [Timestampable]
  columns:
    contact_id:  { type: integer, primary: true }
    forum_id: { type: integer, primary: true }

Then if we associate a couple of Forum objects to a Contact object and then try and delete this Contact object we get this error message:

Integrity constraint violation: 19 contact_forum.created_at may not be NULL

If you add SoftDelete to the link table the delete works correctly, and so does the SoftDelete. However we don't want SoftDelete on the link table as it means our primary keys don't work correctly. Is this a bug?

A: 

I think your ids for your many to many relationship are screwed up, assuming that symphony is using Doctrine 1.2.2. Try this:

Contact:
  actAs: [Timestampable,SoftDelete]
  columns:
    first_name:  { type: string(255), notnull: true }
    second_name:  { type: string(255), notnull: true }
  relations:
    Forums:
      refClass: ContactForum
      local: contact_id
      foreign: forum_id 
      cascade: [delete]

Forum:
  actAs: [Timestampable,SoftDelete]
  columns:
    name:  { type: string(255), notnull: true }
  relations:
    Contacts:
      refClass: ContactForum
      local: forum_id
      foreign: contact_id
      cascade: [delete]

ContactForum:
  actAs: [Timestampable]
  columns:
    contact_id:  { type: integer, primary: true }
    forum_id: { type: integer, primary: true }

In the relationship, when specifying the class with refClass, local and foreign mean "the column on this other class' table that represents me" and "the column on this other classes table that represents the other", respectively.

Edit: I'm not sure if your definition for the Forums relation under Contact is correct either. Assuming you just need a many-to-many relationship, it can be removed.

Double Edit: Look. Here is all the schema you should need for properly functioning and cascading many-to-many relationships. You shouldn't need two relationships defined to properly cascade deletes.

jeremiahd
The schema is correct. I don't need to define the rel on the forum table. The problem is with the contact table and the link table. The second relationship is defined to make sure the deletes cascade to the link table. This is what breaks. Add soft delete to the link table and it is fine. I want to use application deletes not db cascading deletes.
johnwards
If you don't want to use db cascading deletes, than don't use `cascade: [delete]` in your schema. It generates sql.Also, every source I've seen for writing many-to-many relationships using Doctrine does not define them the way you are. If you're sure that's what you want, then fine, but it sure looks like you have some redundant, if not incorrect stuff there.
jeremiahd
`cascade: [delete]` is application deletion. `onDelete: [CASCADE]` is db cascading deletion. See http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models%3Atransitive-persistence%3Adatabase-level-cascades/en
richsage
See this answer which solves the users problem at why I am putting the extra relationship on Contact. http://stackoverflow.com/questions/3100674/symfony-fixtures-set-ondelete-cascade-on-refclass-table/3102618#3102618
johnwards
If I take off the second relationship, "ContactForums", from Contact then it removes the cascade. You can't put an application delete on the ContactForum link table, that just doesn't work. As I am using SoftDelete I need application level deletes not DB level deletes as Contact isn't really getting deleted.
johnwards
Just noticed your other edit. You can't put cascades on a M-M relationship like you have done. If you don't believe me then download this sandbox. http://dl.dropbox.com/u/8354765/sf_sandbox_del.zip and run the test ./symfony test:unit Contact
johnwards
Oh, you're right, I put them on there backwards :/ In any case, that doesn't really help things out. It's clear why you're defining multiple relations now... as for why your problem is happening, I'm a bit stumped. It may actually be a bug.
jeremiahd
I do believe it is a bug. I think I know why too. I'll update the question with more info
johnwards
+1  A: 

This is a doctrine bug. Bug report here: http://www.doctrine-project.org/jira/browse/DC-795 with patch to fix.

johnwards