@Assert\Valid() 在实体上,删除表单上的验证

@Assert\Valid() on Entity, remove the validation on form

我一直在网上搜索,找不到我的问题的答案。

如果用户选择了第二个字段,我想在第一个字段上禁用@Assert/Valid()。现在两个领域都在进行验证。


表格类型

AppBundle/Form/ParcelType.php
class ParcelType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = 1;

        $builder
            //TODO if address is selected from history, then dont validate this field
            ->add('pickupAddressNew', new AddressType())

            ->add('pickupAddressHistory', 'entity', [
                'class' => 'AppBundle\Entity\Address',
                'property' => 'formatAddress',
                'query_builder' => function (EntityRepository $er) use ($user) {
                    return $er->createQueryBuilder('a')
                        ->where('a.user = :user')
                        ->andWhere('a.type = :type')
                        ->setParameter('user', $user)
                        ->setParameter('type', 'pickup')
                        ->orderBy('a.isDefault', 'DESC')
                        ->addOrderBy('a.id', 'DESC');
                }
            ]););

    }

    public function getName()
    {
        return 'parcel';
    }
}

AppBundle/Entity/Model/Parcel.php
class Parcel
{
    protected $name;

    /**
     * @Assert\Type(type="AppBundle\Entity\Address")
     * @Assert\Valid()
     */
    protected $pickupAddressNew;

    /**
     * @Assert\Type(type="AppBundle\Entity\Address")
     * @Assert\Valid()
     */
    protected $pickupAddressHistory;
...
}

地址

AppBundle/Entity/Address.php

class Address
{
...
private $id;

..
private $firstName;

   /**
     * @var string
     *
     * @Assert\NotBlank(message="field.address.blank")
     * @Assert\Length(
     *      min = 3,
     *      max = 255,
     *      minMessage = "field.address.min",
     *      maxMessage = "field.address.max"
     * )
     * @ORM\Column(name="format_address", type="string", length=255, nullable=false)
     */
    private $address;
}

经过长时间的搜索,我找不到任何答案,但找到了另一个解决方案。与社区分享,以便其他人可以快速解决。

从注释中删除@Assert/Valid() 并在表单类型中添加以下内容

public function buildForm(...) {
...
$form->add('pickupAddressNew', new AddressType(), [
                    'label' => 'form.label.pickupAddressNew',
                    'constraints' => new Valid()
                ])

// also add event listener 
$builder->addEventListener(FormEvents::SUBMIT, array($this, 'conditionValid'));

}

现在在相同的 formType 上创建条件有效方法 class。

public function conditionValid (FormEvent $event)
    {
        $parcel = $event->getData();

        $form = $event->getForm();

        if ($parcel->getPickupAddressHistory() > 0)
        {
            $form->add('pickupAddressNew', new AddressType(), [
                'label' => 'form.label.pickupAddress'
            ]);
        }
    }

在这个方法中,我们检查第二个字段是否有值及其选择,然后重新创建没有验证规则的第一个字段,这将绕过组验证。