2012-03-09 20 views
3

我有兩個實體綁定和使用陣列保存與收集字段的表單/ Doctrine2

Room.php

/** 
* @ORM\Table(name="room") 
* @ORM\Entity(repositoryClass="Ahsio\StackBundle\Repository\RoomRepository") 
*/ 
class Room 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    // ...  

    /** 
    * @ORM\OneToMany(targetEntity="Ahsio\StackBundle\Entity\Workstation", mappedBy="room", cascade={"persist", "remove"}, orphanRemoval=true) 
    */ 
    protected $workstations; 

workstation.php

/** 
* @ORM\Table(name="workstation") 
* @ORM\Entity(repositoryClass="Ahsio\StackBundle\Repository\Workstation") 
*/ 
class Workstation 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Room") 
    * @ORM\JoinColumn(name="room_id", referencedColumnName="id", nullable=false) 
    */ 
    private $room; 

    // ... 

我添加了一個房間類型和一個集合字段,用於添加/更新/刪除工作站

RoomType.php

class RoomType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('id', 'hidden', array(
       'read_only' => true, 
      )) 
      // .... 
      ->add('workstations', 'collection', array(
       'type'   => new WorkstationType(), 
       'allow_add' => true, 
       'allow_delete' => true, 
       'by_reference' => false, 
      )) 
     ; 
    } 
    // ... 
} 

工作站類型是一個簡單的與只有兩個字段(id & number)。

的問題是,當我試圖結合RoomType爲現有室(其中包含ID(1的兩個工作站和2)),與下面的陣列(僅包含兩個工作站中的一個):

array(4) { 
    ["id"]=> string(1) "3" 
    ["workstations"]=> array(1) { 
    [0]=> array(2) { 
     ["id"]=> int(1) 
     ["number"]=> int(200) 
    } 
    } 

更新完成,id = 2的工作站被刪除。但是,當我試圖使用刪除所有工作站對於給定的房間:

array(4) { 
    ["id"]=> string(1) "3" 
    ["workstations"]=> array(0) { 
    } 

工作站仍然存在,我做的是結合很好地進行,這裏是我得到了什麼,當我做了$形式 - >使用最後給定的數組綁定我的$ form後的getData():

object(Ahsio\StackBundle\Entity\Room)#229 (4) { 
    ["id":protected]=> string(1) "3" 
    ["name":protected]=> string(20) "first room (updated)" 
    ["description":protected]=> string(39) "This first room is an old one (updated)" 
    ["workstations":protected]=> array(0) { 
    } 
} 

因此,沒有更新的Room的工作站。有人能告訴我爲什麼當我堅持這最後一個綁定的房間時,我的工作站沒有被刪除嗎?

這裏是我的控制器代碼的一部分我使用來測試更新,其中...

 // The Room $id is given ... 
     $roomArray = array(
     'id'   => $id, 
     'name'   => 'first room (updated)', 
     'description' => 'This first room is an old one (updated)', 
      'workstations' => array(), 
     ); 
     $form  = $this->createForm(new RoomType(), $room);  

     $form->bind($roomArray); 

     if ($form->isValid()) { 
      $em = $this->getDoctrine()->getEntityManager(); 
      $em->persist($room); 
      $em->flush(); 
     } 
+0

你好艾哈邁德,你好嗎?你可以在第113行和第146行的src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php中設置一個斷點(如果你使用的是最新版本的Symfony)並告訴我們發生了什麼? +1有趣的問題 – greg0ire 2012-03-09 16:40:45

+0

Hello Gregoire!我很好,你呢?當我在ResizeFormListener.php(第113行)中設置一個斷點時,我得到一個空數組'array(0){}'用於使用沒有任何工作站的房間數組進行更新。即使當我將一個或多個工作站設置到該陣列時,它看起來也可以正常工作。 'form-> remove($ name)'是使用每個工作站的數組索引執行的。我不認爲這個問題與綁定有關。 – 2012-03-13 13:34:10

回答

0

我認爲接收workstations數組的setter永遠不會被調用,因爲數組是空的。

嘗試查看是否通過添加跟蹤來調用它。

此外,您應該在工作站映射中添加cascade =「merge」選項。

+0

它被稱爲和一個空陣列傳遞到房間的工作站,我認爲這是正確的行爲。 – 2012-03-13 14:27:45

+0

我接受了答案,因爲它幫助我弄清楚如何解決這個問題。我稍後會更新你的答案。 – 2013-03-15 14:20:00

0

我想嘗試更新和刪除實體/相關實體時persist不應該被調用。

你應該嘗試致電:

$em->merge($room); 

之前的表單數據綁定。這樣你就可以恢復數據庫中的數據,剩下的工作就可以完成。

另外,你不應該bind你的形式與Request而不是與數據對象?