Привязать и сохранить форму с полем коллекции, используя массив / Doctrine2 - PullRequest
3 голосов
/ 09 марта 2012

У меня есть две сущности

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 к существующей комнате (которая содержит две рабочие станции с идентификатором (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) {
  }

Рабочие станции все еще там, связывание, которое я сделал, хорошо выполнено, вот что я получил, когда сделал форму $-> 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();
        }

Ответы [ 2 ]

0 голосов
/ 10 марта 2012

Я думаю, что сеттер, который получает массив workstations, никогда не вызывается, потому что массив пуст.

Попробуйте узнать, вызывается ли он, добавив трассировку.

Кроме того, вы должны добавить опцию cascade = "merge" в ваше отображение рабочих станций.

0 голосов
/ 09 марта 2012

Я думаю, persist не следует вызывать при попытке обновить и удалить объекты / связанные объекты.

Возможно, вам следует попробовать позвонить:

$em->merge($room);

перед связыванием с данными формы. Таким образом вы восстановите данные из базы данных, а orphanRemoval сделает все остальное.

Кроме того, разве вы не должны bind свою форму с Request, а не с объектом данных?

...