2010-07-20 13 views
7

estoy teniendo problemas para descifrar este bloque de código de doctrine documentationnecesita ayuda para entender la doctrina de muchos a muchos código autorreferenciados

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

    /** 
    * @ManyToMany(targetEntity="User", mappedBy="myFriends") 
    */ 
    private $friendsWithMe; 

    /** 
    * @ManyToMany(targetEntity="User", inversedBy="friendsWithMe") 
    * @JoinTable(name="friends", 
    *  joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@JoinColumn(name="friend_user_id", referencedColumnName="id")} 
    *  ) 
    */ 
    private $myFriends; 

    // ... 
} 

a continuación es cómo descifrar una relación bidireccional de uno a muchos

alt text http://29.media.tumblr.com/tumblr_l5uwg3VH171qbp1vqo1_r1_500.png

pero si uso el mismo método, ... a continuación es lo que obtienes

alt text http://img514.imageshack.us/img514/2918/snagprogram0000.png

ACTUALIZACIÓN

i shld aclarar mi pregunta. básicamente, no entiendo cómo es el opuesto de myFriends, friendsWithMe. cómo tendré sentido este código y lo que es más importante, cómo codificar esas relaciones yo mismo.

Respuesta

10

i darle una oportunidad a responder a mi pregunta, soy todavía bastante difuminar con esto, espero que alguien realmente puede dar una mejor respuesta,

por lo primero responder a la pregunta ABT ¿cómo derivo con $friendsWithMe

básicamente, comencé con la "decodificación" de una relación bidireccional más simple, más común, de muchos a muchos.

  • 1 usuario puede estar en muchos grupos
    • $ usuario-> grupos
  • 1 grupo puede tener muchos usuarios
    • $ grupo-> usuarios

muy directo. pero, ¿cómo tiene sentido esto en SQL?

alt text

código para implementar

# 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 

ahora al modelo real ... en SQL

alt text

en el código

# 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, ja! selecciona usuarios que son amigos del usuario dado. entonces así es como obtengo $friendsWithMe. luego para completar el inversedBy & mappedBy & el resto de la clase?

1ª mirada a la nota inferior.

alt text

no está claro sin tanto y el pensamiento profundo, ABT 2 días. Supongo

y luego, como práctica, ¿cómo puedo crear una relación de autoreferencia de muchos a muchos desde cero?

el ejemplo en el que voy a trabajar es ... hmm, bastante asqueroso, pero creo que lo intentaré :) ... 1 usuario/alumno puede tener muchos profesores. 1 maestro puede tener muchos usuarios/estudiantes. 1 usuario puede ser profesor y alumno aquí. Como en foros como estos, cuando respondes preguntas de alguien, eres un profesor. cuando usted pide, u es un estudiante

el ERD se verá como

alt text

algo de código para seleccionar, los estudiantes de los maestros, los maestros de estudiantes

# 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, la parte doctrina ?

/** @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; 
} 

que generó este mesas para mí

# 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 

al fin lo he hecho! vamos a probarlo ... erm que estoy recibiendo

Fatal error: Class 'Entities\User' not found in D:\ResourceLibrary\Frameworks\Doctrine\tools\sandbox\index.php on line 61

cuando intento hacer una zzz

$user = new User; 

...

también he blogged ABT esta pregunta y mi explicación en mi tumblr

+0

$ user = usuario nuevo(); – ruipacheco

+0

+1 Para mayor claridad de la pregunta y el esfuerzo en la preparación de material fuente adicional – calumbrodie

+1

Hola. Tengo un problema con la doctrina con estas relaciones. Cuando agrego elementos a ese tipo de colección, limpio y después de eso los elimino a todos y vuelvo a descargar. Estoy recibiendo 'La clase 'Doctrine \ ORM \ Persisters \ ManyToManyPersister' no se encontró en la cadena de espacios de nombres configurados'. Cuando elimino elementos, pero dejo al menos uno, todo funciona perfectamente. ¿Puedes probar este comportamiento por mí? y si no recibes ningún problema después de la versión de la doctrina que estás usando? Estaré agradecido. –

3

la pregunta es, que tiene la M: mesa de N:

  • friend_user_id
  • USER_ID

con dos usuarios ID 1 y 2. ¿Tiene solamente:

friend_user_id = 1 y user_id = 2

o ambos

friend_user_id = 1 y user_id = 2 user_id = 2 y friend_user_id = 1

Puede implementar ambas formas, dependiendo de cómo codifique la administración de la colección del lado propietario.

Caso A:

public function addFriend(User $friend) 
{ 
    $this->myFriends[] = $friend; 
} 

Caso 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

también con respecto a su nuevo problema de usuario, debe comprender cómo funciona el espaciado de nombre PHP 5.3, primero tiene que configurar un autocargador para el espacio de nombres "Entidades", luego también debe llamar "use Entities \ User"; poder hacer "nuevo usuario" en lugar de "nuevo \ entidades \ usuario"; – beberlei

+1

con respecto a mi error de Usuario, resulta que no puse 'namespace Entities' sobre mi declaración de clase –

+0

entonces puedo decir que Case 1 es una relación unidireccional y 2 a bi? Creo que si soy un usuario de una red social, donde every1 puede ser amigo de cada uno, no quiero ser amigo de alguien que me haya agregado como amigo. He probado la relación M: N que incluso en la configuración de autorreferencia/bidireccional, cuando alguien1 me agrega como amigo, no soy un amigo con él. Parece que es más conveniente que pueda averiguar quiénes son mis amigos? –

Cuestiones relacionadas