2015-05-19 59 views
0

我對Doctrine很新,所以我希望有人能幫助我或將我重定向到良好的文檔頁面。主義arrayCollections和關係

我建立一個應用程序有兩個實體(我減少的解釋):
- 招標
- 文件

每份標書,我們可以有一個或多個文件。所以我做了以下的對象。

招標人:

<?php 

namespace TenderBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\Table(name="tender") 
*/ 
class Tender 
{ 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $tender_id; 

    /** 
    * @ORM\Column(type="array") 
    * @ORM\ManyToOne(targetEntity="File", inversedBy="tenders") 
    * @ORM\JoinColumn(name="tender_files", referencedColumnName="file_id") 
    */ 
    private $tender_files; 
} 

文件:

<?php 

namespace TenderBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\HttpFoundation\File\UploadedFile; 

/** 
* @ORM\Entity 
* @ORM\Table(name="file") 
*/ 
class File 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $file_id; 

    /** 
    * @ORM\OneToMany(targetEntity="Tender", mappedBy="tender_files", cascade={"persist", "remove"}) 
    */ 
    private $file_tender; 
} 

第一個問題:是不是這樣做的正確方法? (當然,我已經創建了獲取和設置屬性的方法,但它們是基本的)。

當我堅持我的每個File對象時,我試圖添加到我的Tender實例。但要做到這一點,我需要讓$tender_files公衆和做到這一點:

$tender->tender_files[] 

這不是一個可行的解決方案適合我,因爲我需要我的所有領域都是私人,我想恢復我的對象時,我打電話這:

$this->getDoctrine()->getManager()->getRepository('TenderBundle:Tender')->find($id)->getTenderFiles()->getFileName(); 

所以,我解釋並要求找到正確的方式來做我想做的。我希望我所需要的是清楚的,如果需要,我在這裏回答問題或顯示更多代碼。

謝謝!

+0

你的關係是錯誤的招標許多tender_files所以它的你的溫柔類中的一對多和對面也爲文件實體,那麼你應該有addTenderFile和removeTenderFile在你的溫柔類,可以生成這些 –

回答

0

你應該在你的文件實體類似這樣的setter和getter:

public function setTender(\Your\Namespace\Tender $tender) 
{ 
    $this->tender = $tender; 

    return $this; 
} 

public function setTender() 
{ 
    return $this->tender; 
} 

所以,當你的實例(或創建)文件,你可以去像這樣:

$file = new File(); // or file fetched from DB, etc. 
// here set $file properties or whatever 
$tender->setFile($file); 
$entityManager->persist($tender); 
$entityManager->flush(); 

然後您的投標將與您的文件正確關聯。

同樣從文件末尾,你應該能夠做到:

$file->addTender($tender); 
$entityManager->persist($file); 
$entityManager->flush(); 

而且你的標書將被添加到您的文件 - >投標集合。

欲瞭解更多信息,documentation是非常有用的,並有或多或少的一切你需要開始。

另外,保存自己使用generate:doctrine:entity

+0

維護設備或課程。我從命令行生成了實體。但你給我看的吸氣劑和二手菸不適合我的投標人,但由於我的許多人/人之間的關係而存檔。我誤解了什麼?感謝幫助 :)。 – Bardyl

+0

嘿,對不起。我以錯誤的方式得到了關係,我編輯了我的答案是正確的。 – Richard

+0

你好!謝謝你的幫助。那是我做的第一件事。但它保存了一個blob,而不是數據庫中的id(參見[這個Gist](https://gist.github.com/Bardyl/87caf720dc3d406b60f0))。當我試圖保存'$ tender_file-> getFileId()'時,我不能這樣做,因爲這不是File的一個實例。 – Bardyl

0

像理查德已經提到的,你缺少的getter和被宣佈爲公衆制定者手動創建getter和setter方法。他們可以訪問你的私有變量。用symfony的快捷方式做到這一點:

php app/console doctrine:generate:entities 

它會產生這樣的:

public function addTenderFile(\TenderBundle\Entity\File $file) 
{ 
    $this->tender_files[] = $file; 

    return $this; 
} 

/** 
* Remove 
*/ 
public function removeTenderFile(\TenderBundle\Entity\File $file) 
{ 
    $this->tender_files->removeElement($file); 
} 

/** 
* Get 
*/ 
public function getTenderFiles() 
{ 
    return $this->tender_files; 
} 

這是很好的做法,如果你是一個初學者,看看你的代碼線與汽車發電機。一旦你明白了發生了什麼,就讓發電機做好工作。

+0

你好!就像我在我的問題中提到的,我已經爲我的實體創建了getter和setter。 – Bardyl

+0

直接訪問該變量是私有的。但是,如果你的getter是公共的,那麼你可以訪問私有變量。 – daSn0wie

0

這是不正確的:

/** 
* @ORM\Column(type="array") 
* @ORM\ManyToOne(targetEntity="File", inversedBy="tenders") 
* @ORM\JoinColumn(name="tender_files", referencedColumnName="file_id") 
*/ 
private $tender_files; 

你不能堅持一個數組到數據庫。數據庫行是一個實體,它是相應的屬性。如果招標文件可以有多個,那麼這種關係應該是:

* @ORM\OneToMany 

對於文件實體同樣如此。如果許多文件可以有一個投標那麼它的關係應該是:使用Doctrine

* @ORM\ManyToOne 

對於映射關係,它有助於與您目前正處於對左實體讀取左到右,而您正在設置的實體作爲右側的變量。

如果您在Tender閱讀從左到右Tender可能有「OneToMany」文件。並且文件可能有許多投標。 Doctrine Association Mapping