symfony形成一对一关系DELETE

时间:2014-07-12 19:41:08

标签: forms validation symfony one-to-one

这必须是非常简单的事情,但我无法理解。

我得到了一个父实体,它具有Child一对一的单向关系,Parent实体是拥有者:

/**
 * @ORM\OneToOne(targetEntity="Child", cascade={"persist", "remove"}, orphanRemoval=true)
 * @ORM\JoinColumn(name="child_id", referencedColumnName="id")}
 */
protected $Child;

表单添加了ChildType而不需要,但ChildType有一些必填字段:

$builder->add('child', new ChildType(), [
    'required' => false,
]);

创建操作中,没有问题:

  • 如果所有子字段都为空,则关联保持为空,将忽略子关系的验证约束,并且即使它具有一些必需字段,也不会创建子关系。

  • 当填写了一些子字段时,会创建关联,并且如果验证通过则会保留子实体。

到目前为止按预期工作..

更新数据集时,一切都与创建时完全相同。完美

现在我希望移除子实体的情况,这应该像清除所有子字段一样简单,因为不需要子节点。 然而,Emtying所有字段仍会触发验证并导致doctrine更新与所有NULL字段的关系。

我尝试了什么:

为Doctrine创建一个preUpdate侦听器,以便在所有字段为空时删除该关系。问题是如果不禁用验证,就无法实现这一目标。所以这不是正确的方法。 一种方法是仅使用一个回调约束,如果所有字段都为null,则返回true,但这会使所有属性约束对所有一对一情况都无效。不可能......

到目前为止还没有任何线索现在,文档中没有任何内容,只有x-to-many的大量使用情况......

是否有可能以某种方式使用不同的验证组或者在symfony表单中没有验证PostSubmit,或者如果所有字段都是子实体的NULL,是否有其他方式不使用任何验证?

2 个答案:

答案 0 :(得分:1)

您可以做的一件事是使用表单侦听器,例如:

$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
    $entity = $event->getForm()->getData();
    if (null === $entity->getChild->getField1() && null === $entity->getChild->getField2() ... and so on for each child field) {
        $entity->setChild(null);
    }
});

答案 1 :(得分:0)

$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
    $form = $event->getForm();

    if (
        $form->getData()->getChild()
        && $this->isChildrenHaveEmptyData($form->get('child'))
    ) {
        $entity->setChild(null);
    }
});

.....

private function isChildrenHaveEmptyData(FormInterface $form): bool
{
    foreach ($form as $child) {
        if ($child->getData()) {
            return false;
        }
    }

    return true;
}