2010-07-20 17 views
7

sto avendo difficoltà a decifrare questo blocco di codice da doctrine documentationHai bisogno di aiuto per capire Dottrina molti a molti codice di autoregolamentazione riferimento

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

    // ... 
} 

di seguito è come decifrare un uno a molti bidirezionale

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

ma se uso lo stesso metodo, ... di seguito è quello che ottengo

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

UPDATE

chiarisco la mia domanda. fondamentalmente, non capisco come è il contrario di myFriends, friendsWithMe. come ho senso di questo codice e, soprattutto, so come codificare tali relazioni da solo.

risposta

10

dò una prova a rispondere alla mia domanda, io sono ancora abbastanza sfocatura con questo, spero che qualcuno può davvero dare una risposta migliore,

così prima di rispondere alla domanda circa come faccio derivo con $friendsWithMe

in pratica, ho iniziato con "decodifica" una relazione più semplice, più comune, da molti a molti bidirezionale.

  • 1 utente può essere in molti gruppi
    • $ user-> gruppi
  • 1 gruppo può avere molti utenti
    • $ gruppo-> utenti

molto dritto in avanti. ma come ha senso questo in SQL?

alt text

codice per implementare

# 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 

ora al modello attuale ... in SQL

alt text

nel codice

# 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 ah! seleziona gli utenti amici di un determinato utente. quindi questo è il modo in cui ottengo $friendsWithMe. quindi per riempire il inversedBy & mappedBy & il resto della classe?

primo sguardo alla nota in basso.

alt text

non è chiaro, senza tanto e profondità di pensiero, circa 2 giorni. credo che

quindi come pratica come faccio a creare una relazione di auto-referenziamento da molti a molti?

l'esempio su cui sto andando a lavorare è ... hmm, piuttosto schifoso penso ma, proverò :) ... 1 utente/studente può avere molti insegnanti. 1 insegnante può avere molti utenti/studenti. 1 utente può essere un insegnante e uno studente qui. Sai come nei forum come questi, quando rispondi alle domande di qualcuno, sei un insegnante. quando u chiedere, u sono uno studente

il disco di ripristino sarà simile

alt text

po 'di codice per selezionare, gli studenti di insegnanti, insegnanti di studenti

# 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 dottrina ?

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

che ha generato questa tavoli per 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 

finalmente ho fatta! lascia testarlo ... ehm sto ottenendo

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

quando provo a fare uno zzz

$user = new User; 

...

inoltre ho bloggato circa questa domanda e la mia spiegazione sul mio tumblr

+0

$ user = new User(); – ruipacheco

+0

+1 Per chiarezza di domande e sforzi nella preparazione di materiale sorgente aggiuntivo – calumbrodie

+1

Ciao. Ho avuto problemi con la dottrina con queste relazioni. Quando aggiungo elementi a quel tipo di raccolta, svuota e dopo li rimuovo tutti e faccio di nuovo flush Sto ricevendo 'La classe 'Doctrine \ ORM \ Persisters \ ManyToManyPersister' non è stata trovata negli spazi dei nomi chain configurati'. Quando rimuovo gli oggetti, ma ne esco almeno uno tutto funziona perfettamente. Puoi testare questo comportamento per me? e se non ricevi alcun problema pubblica la versione della dottrina che stai utilizzando? Sarò grato. –

3

la domanda è, avente M: tabella N:

  • friend_user_id
  • ID_utente

con due utenti id 1 e 2. Avete solo:

friend_user_id = 1 e user_id = 2

o entrambi

friend_user_id = 1 e user_id = 2 user_id = 2 e friend_user_id = 1

È possibile implementare entrambi i modi, a seconda di come si codifica la gestione della raccolta del lato proprietario.

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

anche per quanto riguarda il tuo nuovo problema degli utenti, devi capire come funziona il PHP 5.3 namespacing, devi prima configurare un autoloader per lo spazio dei nomi "Entities", quindi devi anche chiamare "use Entities \ User;" essere in grado di fare "nuovo utente" invece di "new \ Entities \ User;" – beberlei

+1

per quanto riguarda il mio errore utente, risulta che non ho inserito un 'namespace Entities' in cima alla mia dichiarazione di classe –

+0

quindi posso dire che il caso 1 è una relazione unidirezionale e 2 un bi? Penso che se io sono un utente di un social network, dove ogni 1 può essere amico di ogni 1, non voglio essere amico di qualcuno1 solo perché mi ha aggiunto come amico? ho testato la relazione M: N che anche nell'impostazione self reference/bidirezionale, quando alcuni mi aggiunge come amico, non sono un amico con lui. sembra che sia più di una cosa di comodità che posso scoprire chi sono amiciWithMe? –

Problemi correlati