Bind and save form to collection field using array / Doctrine2

I have two objects

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;

      

and 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;

     // ...

      

I added a room type with a collection field to add / update / remove workstations

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,
            ))
        ;
     }
     // ...
}

      

Workstation type is a simple two-field ( id

and number

).

The problem is when I try to bind the RoomType for an existing room (which contains two workstations id (1 and 2)) with the following array (which only contains one of the two workstations):

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

      

Update well done, workstation for id = 2 removed. But when I try to remove all workstations for a given room using:

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

      

The workstations are still there. The binding I did is well done, this is what I got when I created $ form-> getData () after binding my $ -form using the last given array:

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

      

So, there are no workstations for the refurbished room. Can anyone tell me why my workstations are not deleted when I save this last linked room?

Here is some of my controller code that I'm using to test the upgrade ...

        // 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();
        }

      

+3


source to share


2 answers


I think the setter that receives the array workstations

is never called because the array is empty.

Try to see if it was caused by adding a trace.



In addition, you must add the cascade = "merge" parameter to your workstation mapping.

0


source


I think persist

it shouldn't be called when trying to update and delete objects / related objects.

You should probably try calling:

$em->merge($room);

      



before binding to form data. Thus, you will restore data from the database, and orphanRemoval

- do the rest.

Also, shouldn't you bind

your form with Request

, not with a data object?

0


source







All Articles