2012-08-05 62 views
3

我在Symfony 2.0.17-DEV和PHP 5.3.14上使用Doctrine 2.2.2。我遇到了多級聯合級聯選項的問題。例子很簡單,希望這個夢幻般的董事會的人能夠幫助我。學說2.2.2,級聯不能與多對多關聯?

無論如何,Meta超類是與User關係的所有者。相關領域和唯一的構造:

abstract class Meta 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="User", inversedBy="meta") 
    * @ORM\JoinTable(name="meta_users", 
    *  joinColumns={@ORM\JoinColumn(onDelete="CASCADE")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(onDelete="CASCADE")} 
    *) 
    */ 
    protected $users; 

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

    public function addUser(User $user) 
    { 
     $this->users[] = $user; 
     return $this; 
    } 

    public function getUsers() 
    { 
     return $this->users; 
    } 
} 

(實現,只是空類,是LabelCategory

很簡單,它的工作原理,實際上。我的意思是,從元中添加或刪除用戶實際上會在連接表中添加/刪除相應的行。

問題發生在做相反的事情:創建/編輯用戶並分配元。 User定義與元聯想這種方式,並增加了一個級聯=「所有」選項:

class User 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="Meta", mappedBy="users", cascade={"all"}) 
    */ 
    protected $meta; 

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

    public function addMeta(Meta $meta) 
    { 
     $this->meta[] = $meta; 
     return $this; 
    } 

    public function getMeta() 
    { 
     return $this->meta; 
    } 
} 

我是很新的學說,但是這是行不通的。在我的Symfony 2的形式,用於創建/編輯User,我已經添加entity類型的字段,只選擇所有的元:

$builder 
    ->add('meta', 'entity', array(
     'label'   => 'Meta', 
     'class'   => 'Acme\HelloBundle\Entity\Meta', 
     'property'  => 'select_label', 
     'multiple' => true, 
     'expanded' => true, 
    )) 
; 

任何表沒有改變分配(使用複選框)元給用戶時。怎麼了?我確定我錯過了一些東西,但我找不到什麼。

回答

1

說出我所知道的。

級聯選項與保持連接表關聯無關。當在實體User(或刪除舊實體)的關係meta中找到新的Meta實體時,應使用它。也就是說,在表單中,添加一些輸入以創建新元或刪除現有元,例如使用collection作爲Symfony 2提供的字段類型)。或者當你這樣做時:

$newMeta = new Meta(); 

$user->addMeta($meta); 

$em->persist($user); // A new entity was found in the relation meta 

就我所瞭解的你想要堅持關係本身; Doctrine 總是尋找擁有方爲了堅持實體。意思是從反面你想先堅持用戶,比堅持每個元添加或刪除用戶,如果相應的複選框被選中或沒有。

您的字段爲entity類型,表示所有元素都從您的表中獲取,並且已分配給用戶的元素被標記爲已選中。

我記得做類似的東西,這裏是一個「僞」控制器代碼:

$em->persist($user); // Perstist the inverse side 

// This is what user selected 
$selectedMeta = $user->getMeta(); 

// All meta coming from your database 
$allMeta = $em->getRepository('YourBundle::Meta')->find(); 

// Loop on the owning side 
foreach($allMeta as $meta) 
{ 
    // Is current meta selected? 
    $isSelected = $selectedMeta->contains($meta); 

    // Does this meta have already the user in it? 
    $hasUser = $meta->getUsers()->contains($user); 

    // To be removed: not selected and with the user 
    if(!$isSelected && $hasUser) 
     $meta->getUsers()->removeElement($user); 

    // To be added: selected and without the user 
    if($isSelected && !$hasUser) 
     $meta->addUser($user); 

    $em->persist($meta); // Persist the owning side and the association 
} 

// Apply 
$em->flush(); 

等待確認呢!