2016-09-27 51 views
0

我需要幫助,我symfony3應用程序創建我的實體絲毫原則2:帶有doctrine和symfony 3的文件存儲?

我想我的用戶可以張貼文章,其內容是:

  • 標題
  • 作者
  • 任何一個獨特的圖像(上傳文件)
  • 或一個獨特的電影($網址)

什麼你推薦? 我應該如何構建我的文章實體?

class Article 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

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

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

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="media", type="integer") 
    */ 
    private $media; 
} 

(在控制器:如果$媒體= 1 =>這是一個圖像,否則這是一個視頻)

或者使用類似的關係一比一與新的實體「媒體」例如 ?

我的情況最好的辦法是什麼?

回答

1

是的,這是正常的。可悲的是,鑑別器列是由數據庫方面的Doctrine使用,因此它不能在您的實體中訪問。有兩種可能的方式來實現你想要什麼:


首先,使用兒童類名:

/** 
* Article 
* 
* @ORM\Table(name="article") 
* @ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository") 
* @ORM\InheritanceType("SINGLE_TABLE") 
* @ORM\DiscriminatorColumn(name="media", type="string") 
* @ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"}) 
*/ 
class Article 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    //... 

    /** 
    * Get article type. 
    * 
    * @return string 
    */ 
    public function getType() 
    { 
     // This will return "movie" or "image" 
     return strtolower(substr(strrchr(get_class($this), "\\"), 1)); 
    } 
} 

/** 
* Movie 
* 
* @ORM\Entity 
*/ 
class Movie extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="url", type="text") 
    */ 
    private $url; 

    //getter setter 
} 

/** 
* Image 
* 
* @ORM\Entity 
*/ 
class Image extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="path", type="string", length=255) 
    */ 
    private $path; 

    //getter setter 
} 

第二,在你的類聲明手動類型:

/** 
* Article 
* 
* @ORM\Table(name="article") 
* @ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository") 
* @ORM\InheritanceType("SINGLE_TABLE") 
* @ORM\DiscriminatorColumn(name="media", type="string") 
* @ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"}) 
*/ 
class Article 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @var string 
    */ 
    protected $type; 

    //... 

    /** 
    * Get article type. 
    * 
    * @return string 
    */ 
    public function getType() 
    { 
     return $this->type; 
    } 
} 

/** 
* Movie 
* 
* @ORM\Entity 
*/ 
class Movie extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="url", type="text") 
    */ 
    private $url; 

    public function __construct() 
    { 
     $this->type = 'movie'; 
    } 

    //getter setter 
} 

/** 
* Image 
* 
* @ORM\Entity 
*/ 
class Image extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="path", type="string", length=255) 
    */ 
    private $path; 

    public function __construct() 
    { 
     $this->type = 'image'; 
    } 

    //getter setter 
} 

Personnaly,我有一個pr參考第一個解決方案。我發現它更清潔,更具演化性(如果您必須添加第三種文章類型,此代碼將適應)。

當然,您也可以使用instanceof來確定哪個子類是您正在操作的Article實體。

+1

感謝您的幫助,但我已經在我的模板中直接爲測試文章類型創建了自己的樹枝擴展,現在它完美地工作!不需要手動聲明類型或其他方法。 –

+0

這是另一種方式來做到這一點!我很高興你達到了你想要的。 :) – Boulzy

+0

我回到了這裏,目前我正在通過表單添加新文章。我很困惑。看這裏http://stackoverflow.com/questions/39791247/build-form-with-single-table-inheritance –

1

我認爲使用媒體實體和處理媒體實體中的媒體類型是最好的方法。

class Article 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    // ... 

    /** 
    * @var Media 
    * 
    * @OneToOne(targetEntity="Media") 
    * @ORM\JoinColumn(name="media_id", referencedColumnName="id") 
    */ 
    private $media; 
} 

class Media 
{ 
    const TYPE_IMAGE = 'image'; 
    const TYPE_MOVIE = 'movie'; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string") 
    */ 
    private $url; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string") 
    */ 
    private $type; 
} 

一種其他的方式來做到這一點可能是使用entity inheritance來對圖像和動畫型動物實體 - 如果你需要。

+0

但是我不明白你上面的媒體類。您的類別沒有圖片路徑或電影網址的屬性。它是如何工作的? –

+1

我沒有將這個反射推得太遠:D我假設(錯誤地,我猜^^)你的圖像也是由URL定義的。如果管理它們的方式不同,那麼實體繼承可能是一個很好的選擇。媒體實體將只是一個類,在您的Article實體中只有一個屬性「媒體」,它可以包含兩種不同類的類。 – Boulzy

+0

有效的是。所以在Doctrine的文檔中,我必須在單表繼承和類表繼承之間進行選擇? –

0

好吧,我做了我的文章類中的單表繼承:

/** 
* Article 
* 
* @ORM\Table(name="article") 
* @ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository") 
* @ORM\InheritanceType("SINGLE_TABLE") 
* @ORM\DiscriminatorColumn(name="media", type="string") 
* @ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"}) 
*/ 
class Article 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    //... 
} 

/** 
* Movie 
* 
* @ORM\Entity 
*/ 
class Movie extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="url", type="text") 
    */ 
    private $url; 

    //getter setter 
} 

/** 
* Image 
* 
* @ORM\Entity 
*/ 
class Image extends Article 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="path", type="string", length=255) 
    */ 
    private $path; 

    //getter setter 
} 

這偉大工程!