这必须是非常简单的事情,但我无法理解。
我得到了一个父实体,它具有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,是否有其他方式不使用任何验证?
答案 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;
}