首页 > 解决方案 > Symfony 3:如何使用 Collection 并验证它

问题描述

我的问题显然来自于我不太了解如何使用 CollectionType 并对其进行验证。

这是我的课程:

class Reservation {
   private startDate;
   private startTime;
   private endDate;
   private endtime;
   .....
}

class Mission {
   private $reservations

   public function __construct() {        
       $this->reservations = new ArrayCollection();
   }

   ....
}

在某个时间,我创建了我的 Mission 对象,并用一些 Reservation 对象的集合填充了 reservations firld。

关于集合,我的表单类型是这样的:

$builder->add('reservations', CollectionType::class, array(
   'entry_type' => ReservationType::class,
   'entry_options' => array('label' => false),
   'label' => false,
   'required'=> false
));

如果 ReservationType 类我有这个:

$builder->add('startDate', DateType::class, array(
    'label' => 'Date Aller',
    'widget' => 'single_text',
    'format' => 'dd/MM/yyyy',
    'attr' => array(
        'no_results_text' => 'JJ/MM/AAAA'
     )
));

$builder->add('startTime', TextType::class, array(
    'label' => 'Heure Aller',
    'attr' => array(
         'placeholder' => 'Heure:Minutes'
    )
));

$builder->add('endDate', DateType::class, array(
    'label' => 'Date Aller',
    'widget' => 'single_text',
    'format' => 'dd/MM/yyyy',
    'attr' => array(
        'no_results_text' => 'JJ/MM/AAAA'
     )
));

$builder->add('endTime', TextType::class, array(
    'label' => 'Heure Aller',
    'attr' => array(
         'placeholder' => 'Heure:Minutes'
    )
));

在树枝上:

{% for reservation in form_mission.reservations %}
    I display the reservation Object startDate, startTime, endDate, endTime
{% endfor %}

一切都很好地展示了。

让我们尝试使用注释进行一些简单的验证(NotBlank 之一)。内部任务类,上面保留私有字段:

/**
 * @Assert\Collection(
 *      fields = {
 *          "startDate" = @Assert\NotBlank,
 *          "startTime" = @Assert\NotBlank,
 *          "endDate" = @Assert\NotBlank,
 *          "endTime" = @Assert\NotBlank
 *      },
 *      allowMissingFields = true
 * )
 */
 private $reservations

在我的任务对象的预订集合中,我有六个预订对象。我确保其中一个保留对象的 startDate 为空。

验证表单,没有出现错误,但在开发栏中,我有 6 个错误。每个预订一个,它是相同错误的 6 倍:

This field was not expected.    0   Caused by: ConstraintViolation {#1358 ▶}
This field was not expected.    1   Caused by: ConstraintViolation {#1370 ▶}
This field was not expected.    2   Caused by: ConstraintViolation {#5597 ▶}
This field was not expected.    3   Caused by: ConstraintViolation {#1371 ▶}
This field was not expected.    4   Caused by: ConstraintViolation {#1378 ▶}
This field was not expected.    5   Caused by: ConstraintViolation {#1382 ▶}

在 ConstraintViolation 里面我有这个:

root: Form {#3185 …}
path: "data.reservations[0]"
value: Reservation {#3054 ▶}

所以发生的错误与预期的错误无关,我不明白我的错误。

也许 fields 属性需要集合的键(0、1、2、3、4、5)。所以我不明白如何验证我的 startDate 字段。

我像这样替换了我的注释:

/**
 * @Assert\Collection(
 *      fields = {
 *          "3" = @AssertPersonnelNotBlank,
 *          "4" = @AssertPersonnelNotBlank,
 *          "5" = @AssertPersonnelNotBlank,
 *      },
 *      allowMissingFields = true,
 *      allowExtraFields = true
 * )
 */

我的自定义验证器中的值是一个预留对象:

结论:在自定义验证器中,您检查所有不应为空的字段并返回一条消息

  1. 我不知道如何在树枝中显示错误
  2. 显然,集合中的任何错误都会有一个显示。无法在集合对象上显示错误?

标签: symfonyvalidationcollections

解决方案


您的集合是类数组,因此您需要向Reservation类添加验证规则,例如

class Reservation {
   /**
    * @Assert\NotBlank
    */
   private startDate;
   /**
    * @Assert\NotBlank
    */
   private startTime;
   /**
    * @Assert\NotBlank
    */
   private endDate;
   /**
    * @Assert\NotBlank
    */
   private endtime;
   .....
}

然后在您的父实体中添加@Assert\Valid到集合字段

 /**
  * @Assert\Valid
  */
 private $reservations

推荐阅读