2011-06-17 63 views
0

我很難弄清楚如何在zend框架中正確使用Doctrine 2。我正在閱讀文檔並根據我目前的工作和zendcasts。當我嘗試使用我的數據庫來處理關係數據時,問題實際上就開始了,因爲我不太確定如何使用學說集合。在我的測試情況下,我有一個用戶實體:使學說有意義的問題2

class User 
{ 
/** 
* @var integer 
* @Column (name="id", type="integer", nullable=false) 
* @Id 
* @GenerateValue(strategy="IDENTIY") 
* 
*/ 
private $id; 

/** 
* @Column(type="string",length=60,nullable=true) 
* @var string 
*/ 
private $email; 

/** 
* 
* @param \Doctring\Common\Collections\Collection $property 
* @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"}) 
*/ 
private $countries; 

public function __get($property) 
{ 
    return $this->$property; 
} 

public function __set($property, $value) 
{ 
    $this->$property = $value; 
} 
} 

這是關係到國家的實體:

class Countries { 
/** 
* @var integer 
* @Column (name="id", type="integer", nullable=false) 
* @Id 
* @GenerateValue(strategy="IDENTIY") 
* 
*/ 
private $id; 

/** 
* 
* @var string 
* @Column(type="string") 
*/ 
private $countryName; 

/** 
* 
* @var User 
* @ManyToOne(targetEntity="User") 
* @JoinColumns({ 
* @JoinColumn(name="user_id", referencedColumnName="id") 
* }) 
*/ 
private $user; 


public function __get($property) 
{ 
    return $this->$property; 
} 

public function __set($property, $value) 
{ 
    $this->$property = $value; 
} 
} 

現在我可以用的東西分配來自控制器的國家是這樣的:

$p1 = new \Federico\Entity\Countries(); 
    $p1->countryName = 'Argentina'; 
    $p2 = new \Federico\Entity\Countries(); 
    $p2->countryName = 'España'; 
    $u = new \Federico\Entity\User(); 
    $u->firstname = 'John'; 
    $u->lastname = 'Doe'; 
    $u->id = 1; 

這將顯示此對象:

object(Federico\Entity\User)[109] 
    private 'id' => int 1 
    private 'email' => null 
    private 'countries' => 
array 
    0 => 
    object(Federico\Entity\Countries)[107] 
     private 'id' => null 
     private 'countryName' => string 'Argentina' (length=9) 
     private 'user' => null 
    1 => 
    object(Federico\Entity\Countries)[108] 
     private 'id' => null 
     private 'countryName' => string 'España' (length=7) 
     private 'user' => null 
    public 'firstname' => string 'John' (length=4) 
    public 'lastname' => string 'Doe' (length=3) 

如果您注意到這一點,您會看到country對象中的user屬性設置爲null。我不明白這是否應該像這樣發生。此外,由於用戶將被允許從複選框列表中選擇國家,並且他們可以選擇多個國家,......國家不應該以某種方式存儲在Db中嗎?

回答

0

我看不到您在代碼中將國家/地區分配給用戶的位置。無論如何,你需要做兩件事:

在User構造函數中初始化$countries變量作爲新的Doctrine\Common\Collections\ArrayCollection

手動連接用戶的國家:

public function addCountry(Country $c) 
{ 
    if (!$this->countries->contains($c)) { 
    $this->countries->add($c); 
    $c->user = $user; 
    } 
} 
+0

不知道,如果我們兩個認識其他@的Ondrej Mirtes,假設我只是要允許用戶從4個不同的國家(這是他可以選擇所有選擇其中1個或2個......)這些國家不應該已經存儲在一個表中並且分配給country_id嗎?我以前曾用zend_db做過這樣的事情,我有三個表:用戶,國家和user_has_countries。我不太清楚我怎麼能應用這樣的教義,雖然 –

+0

在這種情況下,你想要一個用戶和國家之間的多對多關係。一個用戶可以有很多國家,一個國家可以有很多用戶。您只需要擔心用戶和國家實體; Doctrine將自行處理連接表(user_has_countries,在您的舊模式中)。 – timdev

0

在教義2使用魔法getter和setter方法是不鼓勵。正如您所看到的,他們可能會導致管理關聯問題。以下是如何管理您在用戶實體中的關聯的示例。

namespace Whatever/Your/Namespace/Is; 

use \Doctrine\Common\ArrayCollection; 

class User 
{ 
    /** 
    * @Column (type="integer") 
    * @Id 
    * @var integer 
    */ 
    private $id; 

    /** 
     * @OneToMany(targetEntity="Country", mappedBy="user", cascade={"persist", "remove"}) 
     * @var ArrayCollection 
    private $countries; 

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

    public function getCountries() 
    { 
     return $this->countries; 
    } 

    public function setCountry(Country $country) 
    { 
     $this->country[] = $country; 
     $country->setUser($this); 
     return $this; 
    } 

    public function removeCountry(Country $country) 
    { 
     return $this->country->removeElement($country); 
    } 
} 

和國家

class Country 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @var integer 
    */ 
    private $id; 

    /** 
    * @Column(length=100) 
    * @var string 
    */ 
    private $country_name; 

    /** 
    * @ManyToOne(targetEntity="User", inversedBy="countries") 
    * @var User 
    */ 
    private $user; 

    public function setUser(User $user) 
    { 
     $this->user = $user; 
     return $this; 
    } 

    public function getUser() 
    { 
     return $this->user; 
    } 

    // ... 
}