views:

238

answers:

1

Hello!

So I have a table schema that has users who can be friends.

User:
  actAs: { Timestampable: ~ }
  columns:
    name: { type: string(255), notnull: true }
    email: { type: string(255), notnull: true, unique: true }
    nickname: { type: string(255), unique: true }
    password: { type: string(300), notnull: true }
    image: { type: string(255) }

FriendsWith:
  actAs: { Timestampable: ~ }
  columns:
    friend1_id: { type: integer, primary: true }
    friend2_id: { type: integer, primary: true }
  relations:
    User: { onDelete: CASCADE, local: friend1_id, foreign: id }
    User: { onDelete: CASCADE, local: friend2_id, foreign: id }

It builds the database correctly, but when I try to insert test data like:

User:
  user1:
    name: Danny Gurt
    email: [email protected]
    nickname: danny
    password: test1
  user2:
    name: Adrian Soian
    email: [email protected]
    nickname: adrian
    password: test1

FriendsWith:
  friendship1:
    friend1_id: user1
    friend2_id: user2

I get this integrity constraint problem:

  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`krowdd`.`friends_with`, CONSTRAINT `friends_with_ibfk_1` FOREIGN KEY (`friend1_id`) REFERENCES `user` (`id`) ON DELETE CASCADE)  

Any ideas?

ADDITION:

I noticed the generated sql code is only showing one constraint for the friends_with table:

ALTER TABLE friends_with ADD CONSTRAINT friends_with_friend2_id_user_id FOREIGN KEY (friend2_id) REFERENCES user(id) ON DELETE CASCADE;

Maybe this will help!

Thanks!

+1  A: 

Name the relations in your FriendsWith table differently so Doctrine can use them properly:

relations:
  User1:   { onDelete: CASCADE, local: friend1_id, foreign: id, foreignAlias: Friend1 }
  User2:   { onDelete: CASCADE, local: friend2_id, foreign: id, foreignAlias: Friend2 }

The numbers might not be the best names for the relations but you get the idea.

UPDATE - CODE:

This should do the job for you - note that I'm adding the relationship in the User table, not the FriendsWith table:

relations:
  Friend1:  {class: FriendsWith, local: id, foreign: friend1_id, type: many, foreignType: one, foreignAlias: User1, onDelete: CASCADE}
  Friend2:  {class: FriendsWith, local: id, foreign: friend2_id, type: many, foreignType: one, foreignAlias: User2, onDelete: CASCADE}
Tom
Still didn't fix the problem. Btw the tables need to both be called User because they reference the actual table names. I still get the same sql error as before. I did notice something weird though. When I checked the generated sql code, there is only one constraint created for the friends_with table when there should be two. I'll post the code in my original post.
Daniel Hertz
There's an additional attribute called "class" that you can use to specify the model it relates to. Set that to indicate the right table, and then rename the relations. I've had this exact same issue, exact same situation, exact same problem. Worked with above method. Let me know if you can't get it to work and I'll post you my code.
Tom
Hi Tom. Thanks for your help, but I'm still a little confused. If you could post your code that would be super helpful. Thanks again!
Daniel Hertz
Try that... posted code above. The relationship is now defined under the User model.
Tom
I tried it and it created the proper sql code but I still get this when it tries to insert: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`krowdd`.`friends_with`, CONSTRAINT `friends_with_friend1_id_user_id` FOREIGN KEY (`friend1_id`) REFERENCES `user` (`id`))
Daniel Hertz
Are you using symfony doctrine:build --all --and-load? If so, the problem is that you're loading data in the wrong order into the tables via fixtures. Make sure parent comes before child. As the error states: it cannot add data into a child table when there is no parent present for it.
Tom
hmmm. I am using that command but the fixtures file is exactly as I posted in my original post. As you can see the users are created before the friendships are.. I'll keep tinkering around. Thanks for all your help Tom.
Daniel Hertz
Ok, hope you get it working. I remember when initially testing my schema having to first sfDoctrineGuard fixtures, then user profiles, then the types of tables you have. Combining them all into a single fixture.yml fixes it too as they get loaded in the order you've written them.
Tom