为了简化,假设我有一个用户实体,其中包含许多地址实体。当我创建/更新用户时,我希望能够添加/删除/更新任意数量的地址。因此,在Symfony 2.8中,我遇到了这种情况: 用户 我使用注解验证器。
src/AppBundle/Entity/User.php
//...
class User
{
//...
/**
* @Assert\Count(min=1, max=10)
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Address", mappedBy="user", cascade={"persist", "remove"})
*/
protected $addresses;
//...
}
UserForm
src/AppBundle/Form/UserForm.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('addresses', CollectionType::class, [
'type' => AddressType::class,
'cascade_validation' => true,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
])
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'cascade_validation' => true,
'validation_groups' => // User's logic
]);
}
地址
src/AppBundle/Entity/Address.php
//...
class Address
{
//...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="user")
*/
protected $user;
/**
* @Assert\NotBlank(groups={"zipRequired"})
* @ORM\Column(type="text", nullable="true")
*/
protected $zipCode;
//...
}
地址表单
src/AppBundle/Form/AddressForm.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('zipCode', TextType::class)
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'data_class' => Address::class,
'cascade_validation' => true,
'validation_groups' => function(FormInterface $form) {
/** @var Address $data */
$data = $form->getData();
$validation_groups = [];
// Simplified here, it's a service call with heavy logic
if ($data->doesRequireZip()) {
$validation_groups[] = 'zipRequired';
}
return $validation_groups;
},
]);
}
在Symfony 2.8中
添加了3个地址,其中两个必须验证zipRequired组,一个不需要。我做到了!
在Symfony 3.4中
我在User::$zipCode声明中添加了@Assert\Valid()
并删除了'cascade_validation' => true
(不在configureOptions方法中,但似乎未使用,因为它已过时)。
但是现在添加了3个地址,其中两个应该验证zipRequired组,而另一个则不需要:仅使用User类的验证器组,所以我可以使用不连贯的数据验证表单!
我使用xdebug进行了检查,并且AddressForm中的validator_groups
回调被调用,但验证器没有被调用。
我尝试了此处描述的解决方案:Specify different validation groups for each item of a collection in Symfony 2?,但在symfony 3.4中无法工作,因为cascade_validation
在属性上会抛出错误。
在我的情况下,涉及的逻辑太重,不能像Specify different validation groups for each item of a collection in Symfony 3?中描述的那样使用解决方案,因为重写整个validation_groups
回调并将其应用于所有子实体非常低效。
@Assert\Valid
和cascade_validation
的行为不同,有没有一种方法来处理在Symfony 3.4中嵌入表单的各个实体验证组,或该功能已经消失了?