Need help understanding Doctrine many to many self referencing code

前端 未结 2 1674
野性不改
野性不改 2020-12-29 13:45

i am having trouble deciphering this block of code from doctrine documentation

/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntit         


        
相关标签:
2条回答
  • 2020-12-29 14:19

    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
    }
    
    0 讨论(0)
  • 2020-12-29 14:40

    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?

    alt text

    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

    alt text

    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.

    alt text

    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

    alt text

    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

    0 讨论(0)
提交回复
热议问题