在未映射的字段上添加自定义验证器,但是使用整个表单提交的上下文?

Bri*_*ian 6 symfony-forms symfony

TL;博士:

  1. 我需要一个自定义验证约束来在未映射的表单字段上运行
  2. 我需要表单操作的对象的ID,以免考虑做我的验证约束
  3. 将验证附加到表单本身或未映射的字段不会给我足够的上下文来运行我的验证查询

我的Person实体表单上有一个未映射的字段,我需要对其进行验证.我已经按照这篇关于如何执行此操作的精彩文章,但我的用例略有不同,并未完全涵盖在文章中.

我正在创建自己的Unique Constraint,需要运行自定义查询来确定唯一性.要运行查询,我需要访问提交的字段值以及原始Person对象(如果是更新操作,我可以获取它的ID).如果没有该Person对象,我将无法在唯一性查询期间将其排除在外.

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

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

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

如果我直接将验证器应用于未映射的字段:

    $builder
        ->add('myUnmappedField', 'text', array(
            'mapped' => false,
            'constraints' => array(
                new MyUniqueValidator(),
              )
            ),
        ))
Run Code Online (Sandbox Code Playgroud)

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

希望我已经正确解释了这一点.我有任何选择优雅地进行此类验证吗?

tom*_*lin 6

你说你有未映射的字段.如果你把它映射到Person实体会有帮助吗?只需使用getter和setter方法在Person类中创建一个新属性,但不要在ORM中创建一个新属性,因为您不希望它持久存在.

如果您不想对Person类进行轮询,您还可以创建另一个复合类,它将保存当前未映射的字段和Person对象(然后您将对其进行映射).然后,您将设置data_class以匹配新对象的命名空间.

上述两种解决方案都应该与您拥有的上层代码一起使用.请让我知道它有帮助.

  • 当然,这是有效的,但这不能成为被问到的问题的公认答案......问题不是由此解决的,它只是被绕过了 (5认同)