2012-01-19 101 views
4

我尝试从集合中删除实体,但它不起作用。Symfony2表单集合:如何从集合中删除实体?

我想我在某个地方有一个错误,但我不知道在哪里。

下面的代码从我updateAction

$em = $this->getDoctrine()->getEntityManager(); 

    $entity = new Person(); 

    if (!$entity) { 
     throw $this->createNotFoundException('Unable to find Person entity.'); 
    } 

    $editForm = $this->createForm(new PersonType(), $entity); 
    $deleteForm = $this->createDeleteForm($id); 

    $request = $this->getRequest(); 

    $editForm->bindRequest($request); 

    if ($editForm->isValid()) { 
     $entity = $editForm->getData(); 

     $em->persist($entity); 
     foreach($entity->getAddresses() as $address) 
     {    
      $em->persist($address); 
     } 
     $em->flush();         

     return $this->redirect($this->generateUrl('person_show', array('id' => $id))); 
    } 

    return $this->render('AppPersonBundle:Person:edit.html.twig', array(
     'entity'  => $entity, 
     'edit_form' => $editForm->createView(), 
     'delete_form' => $deleteForm->createView(), 

    ); 

请注意,除去我的实体我从HTML删除DIV。例如,我删除了<div id="myapp_personbundle_persontype_address_4">

这是正确的方式吗?

回答

2

,现在我做:

[...]   
    $editForm = $this->createForm(new PersonType(), $entity); 
    $deleteForm = $this->createDeleteForm($id); 

    $previousCollections = array(
     'addresses' => $entity->getAddresses(), 
    );   

    $request = $this->getRequest(); 
    $editForm->bindRequest($request); 

    if ($editForm->isValid()) { 
     $entity = $editForm->getData(); 

     $this->deleteCollections($em, $previousCollections, $entity); 

     $em->persist($entity); 
     foreach($entity->getAddresses() as $address) 
     {    
      $em->persist($address); 
     } 
     $em->flush();         

     return $this->redirect($this->generateUrl('person_show', array('id' => $id))); 
    } 
    [...] 
} 

private function deleteCollections($em, $init, $final) 
{ 
    if (empty($init)) { 
     return; 
    } 

    if (!$final->getAddresses() instanceof \Doctrine\ORM\PersistentCollection) { 
     foreach ($init['addresses'] as $addr) { 
      $em->remove($addr); 
     } 
    } 
} 

我希望的解决方案,会发现有一天https://github.com/symfony/symfony/issues/1540,但慢被发现。

+0

非常感谢你这么多帮助我。我还有一个问题是可以做一个比较2 ArrayCollection比较? – Sam

+0

不是原生的,但在API的帮助下(http://www.doctrine-project.org/api/common/2.1/doctrine/common/collections/arraycollection.html),你应该成功地 – webda2l

+0

好吧......谢谢所有山姆 – Sam

1

symfony2中的表单集合非常简单,它为您完成几乎所有的工作。基本上你只需要添加一个collection type并设置allow_add,allow_delete标志并添加一个小的JavaScript代码。看看cookbook example

+0

它应该是'''allow_delete'''''' allow_remove''' –

+0

@AcelasiEu这就是为什么在SO上有一个编辑按钮;-) –

13

感谢this answer,我找到了一个更好的解决方案。您可以使用Doctrine's orphan removal功能:

class Gallery 
{ 
    //...  

    /** 
    * @ORM\OneToMany(targetEntity="Photo", mappedBy="gallery", cascade={"persist", "remove"}, orphanRemoval=true) 
    */ 
    private $photos; 

    //... 

    public function removePhotos($photo) 
    { 
     $this->photos->remove($photo); 
     $photo->setGallery(null); 
    } 
} 
0

我使用这种解决方案

在CONTROLER:

$em = $this->getDoctrine()->getManager(); 
$enity->removeElements($em); 

//Add all your elements again in order to update entity collection. 
$entity->addElement($element) ... 
.... 
$em->persist($entity); 
$em->flush(); 

在实体:

public function removeElements($em) 
{ 
    $elements = $this->elements; 

    foreach ($elements as $element) { 
     $this->elements->removeElement($element); 
     $em->remove($element); 
     $em->persist($this); 
    } 

} 

对我来说它的工作原理和它显示较少的代码,我不必使用orphanRemoval功能。