Symfony/Doctrine:在 symfony 在提交表单时将其解析为实体之前验证关系 ID
Symfony/Doctrine: Validating ID of relation BEFORE symfony resolves it to an entity on form submission
class Thing {
/*** loads of properties ***/
/**
* This is a many to many relation from Thing to Tags
* @var \Doctrine\Common\Collections\Collection
*
* @Assert\All({
* @Assert\Uuid()
* })
*/
private $tags;
/*** moar stuff ***/
}
/*** On the controller ***/
protected function validateAndPersist(Request $request, AbstractEntity $entity, $successHttpCode)
{
$form = $this->createForm($this->getFormDefinition(), $entity);
$form->submit($request);
if ($form->isValid() === true) {
$this->getDoctrineManager()->persist($entity);
$this->getDoctrineManager()->flush();
return $this->createView($entity, $successHttpCode);
}
return $form;
}
所以我在上面有这个实体,它有一个匹配的 Symfony 形式,并且都由一个控制器很好地捆绑在一起。传入的有效负载旨在将一组 UUID 发送到标签 属性。这工作得很好,关系被正确保存。
所以有一些验证可以确保我们收到一组 UUID。
然而,问题恰恰是在我没有收到一组 UUID 时出现的。 $form->submit()
正在尝试通过学说将传入的 ID 解析为实际标签。 postgres 数据库抱怨说它不是一个有效的 UUID(相关字段的类型是 guid),我得到了一个 Doctrine 错误。感觉好像这是在表单验证之前发生的,或者由于多对多关系,可能根本没有对该字段执行验证。
无论哪种方式,这都会导致 Doctrine\DBAL\DBALException
,其中消息包含 SQL 查询的详细信息和诸如此类的东西以及一个多汁的 500 大错误:
{
"code": 500,
"message": "An exception occurred while executing 'SELECT t0_.tag_id AS tag_id_0, t0_.name AS name_1 FROM tag t0_ WHERE t0_.tag_id IN (?)' with params [\"comedy\"]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for uuid: \"comedy\""
}
我显然想要的是在实体上定义的验证实际发生,因为这将触发正确的 HTTP 响应,而无需任何样板代码来处理这种特定情况。
有什么想法吗?
您是否在主窗体中为标签使用了另一个嵌入窗体?
这种情况下,需要设置cascade_validation
属性到true
就可以了。
class Thing {
/*** loads of properties ***/
/**
* This is a many to many relation from Thing to Tags
* @var \Doctrine\Common\Collections\Collection
*
* @Assert\All({
* @Assert\Uuid()
* })
*/
private $tags;
/*** moar stuff ***/
}
/*** On the controller ***/
protected function validateAndPersist(Request $request, AbstractEntity $entity, $successHttpCode)
{
$form = $this->createForm($this->getFormDefinition(), $entity);
$form->submit($request);
if ($form->isValid() === true) {
$this->getDoctrineManager()->persist($entity);
$this->getDoctrineManager()->flush();
return $this->createView($entity, $successHttpCode);
}
return $form;
}
所以我在上面有这个实体,它有一个匹配的 Symfony 形式,并且都由一个控制器很好地捆绑在一起。传入的有效负载旨在将一组 UUID 发送到标签 属性。这工作得很好,关系被正确保存。
所以有一些验证可以确保我们收到一组 UUID。
然而,问题恰恰是在我没有收到一组 UUID 时出现的。 $form->submit()
正在尝试通过学说将传入的 ID 解析为实际标签。 postgres 数据库抱怨说它不是一个有效的 UUID(相关字段的类型是 guid),我得到了一个 Doctrine 错误。感觉好像这是在表单验证之前发生的,或者由于多对多关系,可能根本没有对该字段执行验证。
无论哪种方式,这都会导致 Doctrine\DBAL\DBALException
,其中消息包含 SQL 查询的详细信息和诸如此类的东西以及一个多汁的 500 大错误:
{
"code": 500,
"message": "An exception occurred while executing 'SELECT t0_.tag_id AS tag_id_0, t0_.name AS name_1 FROM tag t0_ WHERE t0_.tag_id IN (?)' with params [\"comedy\"]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for uuid: \"comedy\""
}
我显然想要的是在实体上定义的验证实际发生,因为这将触发正确的 HTTP 响应,而无需任何样板代码来处理这种特定情况。
有什么想法吗?
您是否在主窗体中为标签使用了另一个嵌入窗体?
这种情况下,需要设置cascade_validation
属性到true
就可以了。