2012-07-03 24 views
7

Tôi thấy tài liệu rất kém khi nói đến việc giải thích việc tạo mối quan hệ giữa các thực thể. Vì vậy, tôi sẽ phải yêu cầu giúp đỡ để StackExchangers đồng bào của tôi. Vì vậy, tôi đang cố gắng để xây dựng các trường hợp sau:Làm thế nào để ManyToMany và OneToMany trong Symfony và Doctrine?

Trường hợp 1

Một User thuộc về một hoặc nhiều Group, và một Group có thể có nhiều Permission. A User cũng có thể có Permission.

Trường hợp 2

Một TicketCategory, nhiều Tag và nhiều Comment.

Cảm ơn trước!

Trả lời

17

Điều chắc chắn. Điều đầu tiên cần hiểu là không có "một cách" để làm điều này. Doctrine cung cấp nhiều tính linh hoạt về cách bạn define the relationship - ngay cả khi nhiều định nghĩa tạo ra cùng một DDL (và điều này rất quan trọng để hiểu - một số lựa chọn ánh xạ chỉ ảnh hưởng đến phía đối tượng của ORM, chứ không phải phía mô hình)

Dưới đây là người dùng/nhóm/Quyền ví dụ của bạn, mà thực sự là tất cả nhiều-nhiều hiệp hội (tôi loại trừ tất cả không liên quan nhưng cần mã, như định nghĩa cột 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 {} 

Nếu bạn có câu hỏi về những gì đang xảy ra ở đây, hãy cho tôi biết.

Bây giờ, với ví dụ thứ hai của bạn

<?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 {} 

Như trước đây, cho tôi biết nếu bạn muốn bất kỳ điều này giải thích.

P.S. Không ai trong số này đã được thử nghiệm thực sự, tôi chỉ kinda đập nó ra trong IDE của tôi thực sự nhanh chóng. Có thể có lỗi đánh máy hoặc hai lỗi;)

+0

Tại sao inverseJoinColumns? – vinnylinux

+0

Ngoài ra, tại sao các tên bảng khác nhau?Và should'nt permission_id được khai báo? – vinnylinux

+1

@vinnylinux - Tôi hoàn toàn không nhận được câu hỏi của bạn. inverseJoinColumns chỉ là cách bạn khai báo một mối quan hệ nhiều-một-nhiều chiều - không có "lý do" để trả lời - đó chỉ là cách nó được thực hiện. Và tôi không hiểu câu hỏi thứ hai của bạn là gì. –

4

Hãy thử điều này:

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

Bạn sẽ có một đến nhiều mối quan hệ giữa UserGroup .. Các targetEntity là đường dẫn đến Entity mà bạn muốn có một mối quan hệ với, các mappedBy là biến từ Group Thực thể. cascade nghĩa User có thể thêm vào Group và loại bỏ từ Group

Lớp Nhóm {

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

Đây là đội dự bị của mối quan hệ .. targetEntity nên có con đường trở về của công ty mẹ, đó là User trong trường hợp này. inversedBy là biến số từ thực thể User. JoinColumn chỉ cần nói cho Doctrine biết nên tham gia vào điều gì, việc này sẽ tự động được thực hiện nếu bạn không tự thiết lập.

+0

bạn có thể giải thích không? – MDrollette

Các vấn đề liên quan