Warm tip: This article is reproduced from serverfault.com, please click

symfony-在未映射的字段上添加自定义验证器,但是要提交整个表单吗?

(symfony - Add custom validator on unmapped field, but with context of whole form submission?)

发布于 2014-05-05 19:45:16

tl; dr:

  1. 我需要一个自定义验证约束才能在未映射的表单字段上运行
  2. 我需要表单正在处理的对象的ID,以免在考虑执行验证约束时将其消除
  3. 将验证附加到表单本身或未映射的字段并没有给我足够的上下文来运行验证查询

我的Person实体表单上有一个未映射的字段,需要对其进行验证。我已经关注了这篇很棒的文章,但是我的用例略有不同,并且并未完全涵盖在本文中。

我正在制作自己的唯一约束,需要运行自定义查询来确定唯一性。要运行查询,我需要访问已提交的字段值以及原始Person对象(因此,如果它是更新操作,则可以获取它的ID)如果没有那个Person对象,我将无法在唯一性查询期间将其从考虑中删除。

如果我在PersonType上应用验证器,如下所示:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver
        ->setDefaults(array(
            'data_class' => 'CS\AcmeBundle\Entity\Person',
            'constraints' => array(
                new MyUniqueValidator(),
            )
        ))
    ;
}

然后,验证器将传递整个Person对象以执行验证。这对我没有帮助,因为提交的表单数据不会持久保存到Person对象(这是我$form->isValid()在控制器中调用处理的未映射字段)。

如果我直接将验证器应用于未映射的字段,请执行以下操作:

    $builder
        ->add('myUnmappedField', 'text', array(
            'mapped' => false,
            'constraints' => array(
                new MyUniqueValidator(),
              )
            ),
        ))

然后,传递给验证器的对象只是独立的表单文本,而没有其他内容。我没有Person通过唯一性查询执行的ID对象(如果它是更新操作)。

希望我已经正确解释了这一点。我是否有任何选择可以优雅地进行这种验证?

Questioner
Brian
Viewed
11
tomazahlin 2014-05-06 04:19:41

你说你有未映射的字段。如果将其映射到Person实体,会有所帮助吗?只需使用getter和setter方法在Person类中创建一个新属性,而不是ORM,因为你不希望它持久化。

如果你不想污染你的Person类,则还可以创建另一个复合类,该复合类将保存你当前未映射的字段和一个Person对象(然后将其映射)。当然,你将随后设置data_class以匹配新对象的名称空间。

以上两种解决方案都应与你那里的上层代码一起使用。请让我知道它有所帮助。