【发布时间】:2014-08-05 09:09:31
【问题描述】:
使用: Symfony 2.5 SonataAdminBundle
当数据提交/保存到数据库时,我正在尝试更改其中一个实体字段(标题),方法是使用关联实体中的两个字段。
DocumentRevision CustomEntity [title] = Document[title]+DocumentRevision[number]
但 CustomEntity 的标题必须是唯一的 - 这是我试图通过数据库约束和 UniqueEntity 验证来解决和管理的问题(不完全 - 稍后会详细介绍)。
现在的问题是我更改了 Doctrine preUpdate/Persist 上的标题数据,有效地跳过了对该字段的验证,因为它在验证时为空。当用户输入错误的数据时,数据库层抛出一个关于唯一约束重复的错误。
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function setTitleFromDocumentName() {
$this->setTitle($this->getDocument()->getName() . " rev. " . $this->getDocumentRevision()->getRevisionNumber());
}
实体本身在字段 title 上使用 UniqueEntity 约束,因此从我的角度来看,自定义约束或验证组是毫无意义的,因为它只会复制已使用的约束。
/**
* @UniqueEntity(
* fields={"title"}
* )
**/
似乎最简单的解决方案是在验证之前提交提交之间的某个位置,但这必须从实体完成。
我的问题是如何(可以吗?) 不覆盖 SonataCRUD 控制器或其其他部分,甚至可能吗?
可以,但是有问题:
我可以像这样使用表单事件更改标题:
protected function configureFormFields(FormMapper $formMapper) {
...
$builder = $formMapper->getFormBuilder();
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (!$data) {
return;
}
$data['title'] = $data['document'] . ' rev. ' . $data['documentRevision'];
$event->setData($data);
}
...
formMapper
->add('title',null,array(
...
);
当前的问题是我正在获取“document”和“documentRevision”的 ID,我至少需要它们的名称或 __toString() 表示。
另一个问题是,虽然我可以使用事件设置标题,但当它应该显示表单错误时,它会显示来自 DB 的错误,因为应该在 FormEvents::SUBMIT 上完成验证 - 这个我不明白。强>
最后要注意的是,如果我尝试使用回调函数:
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this,'onPreSubmit'))
public function onPreSubmit() {
$entity = $this->getSubject();
$entity->setTitleFromDocumentName();
}
如果实体尝试从相关实体获取字段,我将得到空标题和错误 - 在非对象上调用函数。
【问题讨论】:
标签: forms validation symfony doctrine-orm sonata-admin