2012-07-03 12 views
7

Uważam, że dokumentacja bardzo słaba, jeśli chodzi o wyjaśnienie tworzenia relacji między podmiotami. Muszę więc poprosić o pomoc moich kolegów z StackExchangers. Tak, staram się budować następujących przypadkach:Jak ManyToMany i OneToMany w Symfony i Doctrine?

Przypadek 1

User należy do jednej lub więcej Group i Group może mieć wiele Permission. A User może również mieć wartość Permission.

Case 2

A Ticket ma Category, stwardnienie Tag i wielokrotne Comment.

Z góry dziękuję!

Odpowiedz

17

Pewnie. Pierwszą rzeczą do zrozumienia jest to, że nie ma "jednego sposobu", aby to zrobić. Doctrine daje dużą elastyczność w zakresie tego, w jaki sposób: define the relationship - nawet jeśli wiele definicji tworzy dokładnie to samo DDL (i to jest ważne, aby zrozumieć - niektóre opcje mapowania wpływają tylko na stronę ORM, a nie stronę modelu)

Oto użytkownicy/grupy/example Uprawnienia, które są rzeczywiście wszystko wiele-do-wielu stowarzyszeń (I wykluczona wszystko nie istotne, ale wymagany kod, jak definicji kolumny PK)

<?php 

namespace Your\Bundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @ORM\Entity 
*/ 
class User 
{ 
    /** 
    * Many-To-Many, Unidirectional 
    * 
    * @var ArrayCollection $groups 
    * 
    * @ORM\ManyToMany(targetEntity="Group") 
    * @ORM\JoinTable(name="user_has_group", 
    *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $groups; 

    /** 
    * Many-To-Many, Unidirectional 
    * 
    * @var ArrayCollection $permissions 
    * 
    * @ORM\ManyToMany(targetEntity="Permission") 
    * @ORM\JoinTable(name="user_has_permission", 
    *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $permissions; 

    public function __construct() 
    { 
    $this->groups = new ArrayCollection(); 
    $this->permissions = new ArrayCollection(); 
    } 
} 

/** 
* @ORM\Entity 
*/ 
class Group 
{ 
    /** 
    * Many-To-Many, Unidirectional 
    * 
    * @var ArrayCollection $permissions 
    * 
    * @ORM\ManyToMany(targetEntity="Permission") 
    * @ORM\JoinTable(name="group_has_permission", 
    *  joinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $permissions; 

    public function __construct() 
    { 
    $this->permissions = new ArrayCollection(); 
    } 
} 

/** 
* @ORM\Entity 
*/ 
class Permission {} 

Jeśli masz pytania o to, co się tutaj dzieje, daj mi znać.

Teraz do drugiego przykładu

<?php 

namespace Your\Bundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @ORM\Entity 
*/ 
class Ticket 
{ 
    /** 
    * Many-To-One, Unidirectional 
    * 
    * @var Category 
    * 
    * @ORM\ManyToOne(targetEntity="Category") 
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
    */ 
    protected $category; 

    /** 
    * Many-To-Many, Unidirectional 
    * 
    * @var ArrayCollection $permissions 
    * 
    * @ORM\ManyToMany(targetEntity="Tag") 
    * @ORM\JoinTable(name="tickt_has_tag", 
    *  joinColumns={@ORM\JoinColumn(name="ticket_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")} 
    *) 
    */ 
    protected $tags; 

    /** 
    * One-To-Many, Bidirectional 
    * 
    * @var ArrayCollection $comments 
    * 
    * @ORM\OneToMany(targetEntity="Comment", mappedBy="ticket") 
    */ 
    protected $comments; 

    public function __construct() 
    { 
    $this->tags = new ArrayCollection(); 
    $this->comments = new ArrayCollection(); 
    } 
} 

/** 
* @ORM\Entity 
*/ 
class Comment 
{ 
    /** 
    * Many-To-One, Bidirectional 
    * 
    * @var Ticket $ticket 
    * 
    * @ORM\ManyToOne(targetEntity="Ticket") 
    * @ORM\JoinColumn(name="ticket_id", referencedColumnName="id") 
    */ 
    protected $ticket=null; 
} 

/** 
* @ORM\Entity 
*/ 
class Tag {} 

/** 
* @ORM\Entity 
*/ 
class Category {} 

Jak poprzednio, daj mi znać, jeśli chcesz coś z tego wytłumaczyć.

P.S. Żadna z tych rzeczy nie została faktycznie przetestowana, po prostu trochę ją zgniotłem w moim IDE naprawdę szybko. Może być literówka lub dwa;)

+0

Dlaczego inverseJoinColumns? – vinnylinux

+0

Dlaczego różne nazwy tabel?A czy nie powinno być zadeklarowane pozwolenie? – vinnylinux

+1

@vinnylinux - Nie otrzymuję twoich pytań. inverseJoinColumns to sposób, w jaki deklarujesz jednokierunkową relację wiele do wielu - nie ma "dlaczego", aby odpowiedzieć - tak po prostu się to robi. I nie rozumiem, o co w ogóle chodzi. –

4

Spróbuj tego:

Class User { 
/** 
    * @ORM\OneToMany(targetEntity="path\to\group", mappedBy="user", cascade={"persist", "remove"}) 
    */ 
    private $group; 

Będziesz mieć jeden do wielu relacji między User i Group .. The targetEntity jest ścieżką do podmiotu, który chcesz mieć związek z tymi mappedBy jest zmienna z Group Podmiot. cascade oznacza User można dodać do Group i wyjąć z Group

klasy grupy {

/** 
* @ORM\ManyToOne(targetEntity="path\to\user, inversedBy="group") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
private $user; 

To jest strona zapasowy związku .. targetEntity powinny mieć drogę z powrotem do jednostki nadrzędnej, która jest w User ta sprawa. inversedBy to zmienna z jednostki User. JoinColumn po prostu mówi Doktrynie o tym, do czego dołączyć, to dzieje się automatycznie, jeśli nie ustawisz go sam.

+0

czy możesz wyjaśnić? – MDrollette

Powiązane problemy