【问题标题】:Delete an item from oneToMany relationship从 oneToMany 关系中删除项目
【发布时间】:2013-04-24 16:35:41
【问题描述】:

我有以下图库实体

class Gallery
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var ArrayCollection
     * @ORM\OneToMany(targetEntity="Tessa\GalleryBundle\Entity\Photo", mappedBy="gallery", cascade={"persist", "remove"})
     */
    private $photos;

    /* ... */
}

gallerymanyToOne 关系链接到PointOfInterest 实体。这是声明

class PointOfInterest
{
 /* ... */
 /**
 * @ORM\ManyToOne(targetEntity="Tessa\GalleryBundle\Entity\Gallery", cascade={"persist", "remove"})
 * @ORM\JoinColumn(nullable=false)
 */
private $gallery;
 /* ... */

我还使用表单来更新PointOfInterest 实体。这是表单声明

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
            ->add('name',           'text')
            ->add('gallery',        new GalleryType())
       ;
}

还有GalleryType 声明。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('photos', 'collection', array('type'          => new PhotoType(),
                                            'required'      => false,
                                            'allow_add'     => true,
                                            'allow_delete'  => true,
                                            'by_reference'  => false
                                            ))
    ;
}

当我编辑PoI 时,我可以毫无问题地将照片添加到图库,但我无法删除任何内容。

我尝试连接到画廊PreUpdate,但它从未被调用。我以Gallery 实体的removePhotos 方法打印输出,照片从图库中删除。然后我怀疑画廊永远不会被保留。

这是我在编辑后坚持 PoI 时的代码。

private function handleForm($elem, $is_new)
{
    $form = $this->createForm(new CircuitType, $elem);

    $request = $this->get('request');
    if ($request->getMethod() == 'POST') {
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($elem);
            $em->flush();

            return $this->redirect($this->generateUrl('tessa_circuit_index'));
        }
    }

    return $this->render('TessaUserBundle:Circuits:add.'.'html'.'.twig',
        array(
            'form' => $form->createView(),
            'is_new' => $is_new,
        ));
}

【问题讨论】:

标签: symfony doctrine-orm


【解决方案1】:

article in Symfony2 cookbook 处理这种情况。由于您有 OneToMany 关系,因此您必须在控制器中手动删除相关对象。

编辑: 或者您可以使用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);
    }
}

【讨论】:

  • 这里的问题是画廊不能自己工作。我在多个实体中使用它,并且需要复制我的代码。我想找到一个 DRY 解决方案。
  • @TomAhh 在这种情况下,我没有看到任何标准解决方案,除非您可以尝试在$photos 关联上设置orphanRemoval=true。然后在画廊的removePhotos($photo) 方法中调用$photo->setGallery(null)
  • 这是一个完美的解决方案,谢谢!现在它的工作方式和我想要的完全一样。您能否更新您的答案以便我验证它?
  • +1 用于关于 Doctrine 的孤儿删除功能的编辑 - 这就是让事情对我有用的原因。
猜你喜欢
  • 1970-01-01
  • 2016-09-03
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多