我有一个Case实体,该实体可以有多个楼层(OneToMany),每个楼层都有一个指定其类型的FloorType。我的Floors实体上也有一个UniqueConstraint,不允许每个Case包含两个具有相同FloorType的Floors。

为了将Floors插入到每个Case中,我为Floors创建了一个Symfony Collection类型,并使用js将新的Floors添加到我的Case中。

Symfony的表单收集文档说,如果未提交项目,则会自动将其从数据库中删除。

现在的问题是,如果数据库中已经有一个案例的楼层,则当我在表单中删除该楼层并再次添加时,它将被视为新的INSERT,但是由于Doctrine首先通过执行INSERT来执行刷新操作和DELETE,最后,由于违反了我设置的uniqueConstraint,我将得到以下错误:



这意味着Doctrine尝试在将FloorType与已删除的FloorType相同的行插入Floors表中,然后再尝试从同一表中删除最后一个。

是否有任何方法可以使在插入之前执行DELETE或其他任何方法来解决此问题?

最佳答案

一种方法是FormEvent
我建议您register your FormType as a service以便注入(inject)教义:

# in your services.yml:
services:
    yourbundle.form.case_type:
        class: Your\Bundle\CaseType
        arguments: ["@doctrine"]
        tags:
            - { name: form.type, alias: your_bundle_case_type }

并扩展您的FormType:
class CaseType /*...*/
{
    private $doctrine;

    public function __construct($doctrine)
    {
        $this->doctrine = $doctrine;
    }
}

现在,在buildFormCaseType方法中注册一个EventListener:
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
     $data = $event->getData();
     $em  = $this->doctrine->getEntityManager();

     foreach ($data['floor'] as $floor) {
         // delete floors here...
         $duplicateFloor = $em->find('YourBundle:Floor', $floor->getId);
         $em->remove($duplicateFloor);
     }
     $em->flush();
});

关于php - 在Doctrine flush中插入之前删除,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22250540/

10-14 23:19