2012-03-09 8 views
3

私は2つのエンティティバインドと配列を使用して、コレクションのフィールドを持つフォームを保存/ 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をバインドしようとしているとき(2つのID(1のワークステーションとを含んでいる2))(2つのだけのワークステーションの1含まれています)次の配列を持つ:

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) { 
    } 
} 

ので、ノーワークステーション。この最後のバインドされた部屋を維持すると、私のワークステーションが削除されない理由を誰かが教えてもらえますか?ここで

は私が更新をテストするために使用しています私のコントローラのコードの一部です...

 // 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行目(最新バージョンのSymfonyを使用している場合)の 'src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php'にブレークポイントを設定して、何が起こっているのか教えてください。興味深い質問のための+1 – greg0ire

+0

こんにちはGregoire!私は大丈夫です、あなたはどうですか? ResizeFormListener.php(Line 113)にブレークポイントを設定すると、ワークステーションなしで部屋の配列を使って更新する空の配列 'array(0){}'が得られます。この配列に1つ以上のワークステーションを設定しても、それは正常に動作します。 'form-> remove($ name)'は各ワークステーションの配列インデックスを使って実行されます。私は問題がバインドに関連しているとは思わない。 –

答えて

0

workstations配列を受け取るセッターは、配列が空であるため呼び出されません。

トレースを追加して呼び出されるかどうかを確認してください。

また、ワークステーションマッピングにcascade = "merge"オプションを追加する必要があります。

+0

これは呼び出され、空の配列が部屋のワークステーションに渡されますが、これは正しい動作だと思います。 –

+0

私はこの問題を解決する方法を見つけ出すのを助けたので、答えを受け入れました。私はあなたの答えを後で更新します。 –

0

私は、エンティティ/関連エンティティを更新し、削除しようとしたときにpersistが呼び出されるべきではないと思います。

おそらく呼び出し試してみてください:

$em->merge($room); 

フォームデータをバインドする前に。そうすれば、データベースからデータを復元し、残りの作業はorphanRemovalで行う必要があります。

bindあなたのフォームはRequestで、データオブジェクトではありませんか?

関連する問題