2011-08-30 72 views
1

我很感興趣標籤是如何工作的。我的想法至今:Doctrine2對多對多標籤的管理

我有三個數據庫表Bookmarksid|title|uri|…Tagsid|title|…和bookmarks_tags(MXM,3NF)。我的第一個測試將只是一個單用戶系統,所以我沒有處理特定用戶擁有的標籤。

保存書籤:uri(字符串)+ tags(字符串,如Lorem Ipsum, Hello應導致兩個標籤:Lorem IpsumHello)。

問題:我應該在哪裏以及如何創建缺少的Tags並加載已知的?

在模型中創建標籤是可能的(參見下面的Bookmark :: setTags())。在Model中加載和鏈接似乎是不可能的,因爲ORM在類中不可用(或者是否存在用於獲取ORM的靜態資源?這是否會被推薦?)。

我可以加載現有標籤並在Controller內部創建標籤,但我認爲標籤應該是模型的工作。

我正在使用Symfony2與Doctrine2。

收藏類/表

* @ORM\Table() 
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\BookmarkRepository") 
*/ 
class Bookmark 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string $title 
    * 
    * @ORM\Column(name="title", type="string", length=255) 
    */ 
    private $title; 

    /** 
    * @var string $uri 
    * 
    * @ORM\Column(name="uri", type="string", length=255) 
    */ 
    private $uri; 

    /** 
    * @var datetime $created_at 
    * 
    * @ORM\Column(name="created_at", type="datetime") 
    */ 
    private $created_at; 

    /** 
    * @var datetime $deleted_at 
    * 
    * @ORM\Column(name="deleted_at", type="datetime") 
    */ 
    private $deleted_at; 


    /** @ORM\ManyToMany(targetEntity="Tag", cascade={"persist", "remove"}) */ 
    private $tags; 



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

    public function getTags() { 
     if ($this->tags->isEmpty()) { 
      return "NO TAGS"; 
     } 

     // TODO load tags from db 
     return "TODO: TAGS FOUND"; 
    } 

    public function setTags ($tags) { 
     // TODO create and load/link existing tags 
     $tag = new Tag(); 
     $tag->setTitle("test tag"); 
     $this->tags->add($tag); 
    } 

    /* setters and getters for other private variables here */ 

標記類/表

* @ORM\Table() 
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\TagRepository") 
*/ 
class Tag 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string $title 
    * 
    * @ORM\Column(name="title", type="string", length=64) 
    */ 
    private $title; 

    /** 
    * @var datetime $created_at 
    * 
    * @ORM\Column(name="created_at", type="datetime") 
    */ 
    private $created_at; 

    /** 
    * @var datetime $deleted_at 
    * 
    * @ORM\Column(name="deleted_at", type="datetime", nullable=true) 
    */ 
    private $deleted_at; 


    public function __construct() { 
     $this->created_at = new \DateTime('now'); 
    } 

     /* setters and getters for other private variables here */ 

回答

1

當從數據庫中獲取的實體,Doctrine2不給你的POPO的實體,而是一個「代理」。該代理能夠從數據庫加載缺失的元素。因此,您不必實現從數據庫中檢索缺失數據的邏輯。

順便說一句,你還可以創建這個方法:

public function addTag(Tag $tag) 
{ 
    $this->tags->add($tag); 
} 
+0

如何防止兩次添加標籤到數據庫?定義唯一標題列不會計數,因爲它會打破重複標籤上的腳本。 在存儲之前檢查標籤不是原子操作。 – Rayne

+0

在調用'$ this-> tags-> add($ tag)''之前,做一個'$ this-> tags-> has($ tag)'檢查。這僅僅是爲了建立關係。如果你在談論標籤的表格,那麼這個檢查應該已經完成​​了,可能在控制器中。 – gilden

+3

做重複檢查會破壞模型和控制器之間的界限。您將無法'重新使用'模型,因爲某些邏輯缺失。 –