Symfony2:编辑

时间:2016-05-25 17:53:23

标签: php validation symfony doctrine-orm symfony2-easyadmin

Symfony版本: 2.8.5

上下文:我有一个实体Restaurant,它与实体Coordinates有一个OneToOne关系,它与其他与坐标信息相关的实体有几个关系。我的后端我创建了一个与Restaurant实体相关的表单,其中包含与Coordinates相关的自定义嵌套表单。

Nota:我使用EasyAdminBundle来生成我的后端。

实体关系计划:

Restaurant

  1 ________ 1 `Coordinates`
                    * ________ 1 `CoordinatesCountry`
                    1 ________ 1 `CoordinatesFR`
                                      * ________ 1 `CoordinatesFRLane`
                                      * ________ 1 `CoordinatesFRCity`

后端视图:

enter image description here

此时我尝试以下方案:

  1. 我创建了一个新餐厅,所以我第一次填写相关表格。我让Coordinates嵌套表单为空(空字段)。因此,在表单提交后,将显示验证消息(参见下图)。
  2. enter image description here

    1. 我编辑了上一个表单,这次我填写了Coordinates嵌套表单的字段。提交表单后,新的Coordinates实体会被充实,并且会在RestaurantCoordinates之间创建关系。

    2. 我再次编辑上一个表单,这次我清除了Coordinates嵌套表单的所有字段。验证未触发,我收到以下错误:

    3.   

      类型" FBN \ GuideBundle \ Entity \ CoordinatesFRCity"的预期参数,   " NULL"给定

      我在CoordinatesFRType(请参阅下面的代码)中确切地说明,在我第一次使用带有闭包的empty_data选项时触发验证消息(如official doc中所述) )如果数据为空(所有字段为空),则实例化新的CoordinatesFR实例。但是here,在本文中(由Symfony表单组件的创建者编写),解释了(参见empty_data和datta mappers段落)empty_data仅在创建对象时调用。所以我认为这就是为什么我的验证在版本的情况下不再起作用的原因。

      问题:在编辑表单并清除所有嵌入表单时,为什么验证无效?

      代码(只有必要):

      餐厅实体

      use Symfony\Component\Validator\Constraints as Assert;
      
      class Restaurant
      {
          /**
           * @ORM\OneToOne(targetEntity="FBN\GuideBundle\Entity\Coordinates", inversedBy="restaurant", cascade={"persist"})
           * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
           * @Assert\Valid()
           */
          private $coordinates;
      }
      

      协调实体

      use Symfony\Component\Validator\Constraints as Assert;
      
      class Coordinates
      {
          /**
           * @ORM\ManyToOne(targetEntity="FBN\GuideBundle\Entity\CoordinatesCountry")
           * @ORM\JoinColumn(nullable=false)
           */
          private $coordinatesCountry;
      
          /**
           * @ORM\OneToOne(targetEntity="FBN\GuideBundle\Entity\CoordinatesFR", inversedBy="coordinates", cascade={"persist"})
           * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
           * @Assert\Valid()
           */
          private $coordinatesFR;
      
          /**
           * @ORM\OneToOne(targetEntity="FBN\GuideBundle\Entity\Restaurant", mappedBy="coordinates")
           * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
           */
          private $restaurant;
      }
      

      CoordinatesFR实体

      use Symfony\Component\Validator\Constraints as Assert;
      
      class CoordinatesFR extends CoordinatesISO
      {
          /**
          * @ORM\ManyToOne(targetEntity="FBN\GuideBundle\Entity\CoordinatesFRLane")
          * @ORM\JoinColumn(nullable=true)
          * @Assert\NotBlank()
          */
         private $coordinatesFRLane;
      
         /**
          * @ORM\ManyToOne(targetEntity="FBN\GuideBundle\Entity\CoordinatesFRCity")
          * @ORM\JoinColumn(nullable=false)
          * @Assert\NotBlank()
          */
         private $coordinatesFRCity;
      
          /**
           * @ORM\OneToOne(targetEntity="FBN\GuideBundle\Entity\Coordinates", mappedBy="coordinatesFR")
           * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
           */
          private $coordinates;
      }
      

      Easy Admin配置(相当于RestaurantType)

      easy_admin:
          entities:
              Restaurant:
                  class : FBN\GuideBundle\Entity\Restaurant
                  form:
                      fields:
                          - { property: 'coordinates', type: 'FBN\GuideBundle\Form\CoordinatesType' }
      

      CoordinatesType

      class CoordinatesType extends AbstractType
      {
          /**
           * @param FormBuilderInterface $builder
           * @param array                $options
           */
          public function buildForm(FormBuilderInterface $builder, array $options)
          {
              $builder
                  ->add('CoordinatesCountry', EntityType::class, array(
                      'class' => 'FBNGuideBundle:CoordinatesCountry',
                      'property' => 'country',
                      ))
                  ->add('coordinatesFR', CoordinatesFRType::class)
              ;
          }
      
          /**
           * @param OptionsResolverInterface $resolver
           */
          public function setDefaultOptions(OptionsResolverInterface $resolver)
          {
              $resolver->setDefaults(array(
                  'data_class' => 'FBN\GuideBundle\Entity\Coordinates',
              ));
          }
      }
      

      CoordinatesFRType

      class CoordinatesFRType extends AbstractType
      {
          /**
           * @param FormBuilderInterface $builder
           * @param array                $options
           */
          public function buildForm(FormBuilderInterface $builder, array $options)
          {
              $builder
                  ->add('laneNum', TextType::class)
                  ->add('coordinatesFRLane', EntityType::class, array(
                      'class' => 'FBNGuideBundle:CoordinatesFRLane',
                      'property' => 'lane',
                      'placeholder' => 'label.form.empty_value',
                      ))
                  ->add('laneName', TextType::class)
                  ->add('miscellaneous', TextType::class)
                  ->add('locality', TextType::class)
                  ->add('metro', TextType::class)
                  ->add('coordinatesFRCity', EntityType::class, array(
                      'class' => 'FBNGuideBundle:CoordinatesFRCity',
                      'property' => 'display',
                      'query_builder' => function (CoordinatesFRCityRepository $repo) {
                          return $repo->getAscendingSortedCitiesQueryBuilder();
                          },
                      'placeholder' => 'label.form.empty_value',
                      ))
              ;
          }
      
          /**
           * @param OptionsResolverInterface $resolver
           */
          public function setDefaultOptions(OptionsResolverInterface $resolver)
          {
              $resolver->setDefaults(array(
                  'data_class' => 'FBN\GuideBundle\Entity\CoordinatesFR',
                  // Ensures that validation error messages will be correctly displayed next to each field 
                  // of the corresponding nested form (i.e if submission and CoordinatesFR nested form with all fields empty)
                  'empty_data' => function (FormInterface $form) {
                      return new CoordFR();
                  },
              ));
          }
      }
      

0 个答案:

没有答案