Need help understanding Doctrine many to many self referencing code
The question is, having the M:N table:
- friend_user_id
- user_id
with two users id 1 and 2. Do you have only:
friend_user_id = 1 and user_id = 2
or both
friend_user_id = 1 and user_id = 2 user_id = 2 and friend_user_id = 1
You can implement both ways, depending on how you code the management of the collection of the owning side.
Case A:
public function addFriend(User $friend)
{
$this->myFriends[] = $friend;
}
Case B:
public function addFriend(User $friend)
{
$this->myFriends[] = $friend;
$friend->myFriends[] = $this; // php allows to access private members of objects of the same type
}
i give a try at answering my question, i am still quite blur with this, hope someone can really give a better answer,
so 1st to answer the question abt how do i derive with $friendsWithMe
basically, i started off with "decoding" a simpler, more common, many to many bidirectional relationship.
- 1 user can be in many groups
- $user->groups
- 1 group can have many users
- $group->users
very straight forward. but how does this make sense in SQL?
code to implement
# select groups user is in
select group_id from users_groups
where user_id = 1
#select users of group
select user_id from users_groups
where group_id = 1
now to the actual model ... in SQL
in code
# select friends of given user
# $user->myFriends
select friend_id from friends
where user_id = 1;
# select users that are friends of given user
# $user->friendsWithMe
select user_id from friends
where friend_id = 1;
ah ha! select users that are friends of given user. so this is how i get $friendsWithMe
. then to fill up the inversedBy
& mappedBy
& the rest of the class?
1st look at the bottom note.
not clear without so much and deep thinking, abt 2 days. i guess
then as practice how do i create a many to many self referencing relationship from scratch?
the example i am going to work on is... hmm, quite crappy i think but, i'll try :) ... 1 user/student can have many teachers. 1 teacher can have many users/students. 1 user can be a teacher and student here. u know like in forums such as these, when u answer someones questions, you are a teacher. when u ask, u are a student
the ERD will look like
some code to select, students of teachers, teachers of students
# select students of teacher
# $teacher->students
select student from teacher_student
where teacher = 1;
# select teachers of student
# $student->teachers
select teacher from teacher_student
where student = 2;
ok, the doctrine part?
/** @Entity @Table(name="users")) */
class User {
/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Column(type="string", length="30")
*/
private $name;
/**
* @ManyToMany(targetEntity="User", inversedBy="teachers")
* @JoinTable(name="Teachers_Students",
* joinColumns={@JoinColumn(name="teacher", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="student", referencedColumnName="id")}
* )
*/
private $students;
/**
* @ManyToMany(targetEntity="User", mappedBy="students")
*/
private $teachers;
}
which generated this tables for me
# users
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
#teachers_students
CREATE TABLE `teachers_students` (
`teacher` int(11) NOT NULL,
`student` int(11) NOT NULL,
PRIMARY KEY (`teacher`,`student`),
KEY `student` (`student`),
CONSTRAINT `teachers_students_ibfk_2` FOREIGN KEY (`student`) REFERENCES `users` (`id`),
CONSTRAINT `teachers_students_ibfk_1` FOREIGN KEY (`teacher`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
at last i done it! lets test it ... erm i am getting
Fatal error: Class 'Entities\User' not found in D:\ResourceLibrary\Frameworks\Doctrine\tools\sandbox\index.php on line 61
when i try to do a
$user = new User;
zzz ...
i have also blogged abt this question and my explaination on my tumblr