使用sonata_type_admin嵌入式管理员停止SonataAdmin / Symfony2创建空对象

时间:2013-08-10 00:31:15

标签: symfony sonata-admin symfony-sonata symfony-2.3

首先,我不确定这是Sonata问题还是Symfony2问题,这是我第一次使用Sf2表单来编辑关系。

问题在于:

我有两个课程,我们称之为旧版:CarWheel。 Car与Wheel有一个可选的一对一关系(例如,它就是它......)。我已经使用CarAdmin类设置了SonataAdmin,使用WheelAdmin嵌入sonata_type_admin并尝试创建Car而不输入Wheel的任何数据。

然而,在提交时(在$ form-> bind()/ $ form-> submit()的某处,据我所知)Symfony和/或Sonata实例化一个Wheel并试图坚持它(与其所有值均为null)。由于Wheel有一些非null约束,因此会抛出一个DBALException,抱怨你不能插入带有null值的Wheel。

这很顽皮,我想阻止它发生。如果我没有输入Wheel的任何细节,我不希望幻影轮对我的代码和数据库造成威胁。我期望的是,如果我没有输入任何数据,就没有任何内容可以插入/保留,所以它不会被单独存在。但这不是正在发生的事情...... 任何想法如何将其变成合情合理的东西?


这是长版本,包含代码块和所有内容:

首先是ORM定义:

# MyNS\MyBundle\Resources\Config\Doctrine\Car.orm.yml
MyNS\MyBundle\Entity\Car:
  type: entity
  repositoryClass: MyNS\MyBundle\Entity\Repositories\CarRepository
  table: test_cars
  id:
    id:
      type:                     integer
      generator:                { strategy: AUTO }
  fields:
    color:
      type:                     string
      length:                   50
    owner:
      type:                     string
      length:                   50
      nullable:                 true
  oneToOne:
    leftFrontWheel:
      targetEntity:             Wheel
      cascade:                  [ persist ]
      joinColumn:
        name:                   leftFrontWheelId
        referencedColumnName:   id


# MyNS\MyBundle\Resources\Config\Doctrine\Wheel.orm.yml
MyNS\MyBundle\Entity\Wheel:
  type: entity
  repositoryClass: MyNS\MyBundle\Entity\Repositories\WheelRepository
  table: test_wheels
  id:
    id:
      type:                     integer
      generator:                { strategy: AUTO }
  fields:
    diameter:
      type:                     integer
      length:                   5

然后是SonataAdmin课程:

namespace MyNS\MyBundle\Admin

use ...

class CarAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('color',              null, array('required' => true))
            ->add('owner',              null, array('required' => false))
            ->add('leftFrontWheel',     'sonata_type_admin', array('delete' => false))
        ;
    }

    protected function configureListFields(ListMapper $listMapper) { ... }
}

namespace MyNS\MyBundle\Admin;

use ...

class WheelAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('diameter',   null,   array('required' => false))
        ;
    }

    protected function configureListFields(ListMapper $listMapper) { ... }
}

最后是admin.yml条目:

services:
    sonata.admin.car:
        class: MyNS\MyBundle\Admin\CarAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, label: "Car" }
        arguments:
            - ~
            - MyNS\MyBundle\Entity\Car
            - 'SonataAdminBundle:CRUD'
        calls:
            - [ setTranslationDomain, [MyNS\MyBundle]]
    sonata.admin.wheel:
        class: MyNS\MyBundle\Admin\WheelAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, label: "Wheel" }
        arguments:
            - ~
            - MyNS\MyBundle\Entity\Wheel
            - 'SonataAdminBundle:CRUD'
        calls:
            - [ setTranslationDomain, [MyNS\MyBundle]]

预期/必需行为:

  • 显示包含三个字段的表单:

    • car.color(必填)
    • car.owner(可选)
    • car.wheel.diameter(可选)
  • 如果car.wheel.diameter留空,则不应创建Wheel并且test_cars.leftFrontWheelId应保留在数据库中null

  • 如果输入car.wheel.diameter,则应创建Wheel并将其链接到Car(这似乎与现有配置一起使用)

问题:如何让此系统按上述方式运行?

2 个答案:

答案 0 :(得分:0)

这可能是由于缺少'required' => false,没有?

造成的
protected function configureFormFields(FormMapper $formMapper) {
    $formMapper
        ->add('color',              null, array('required' => true))
        ->add('owner',              null, array('required' => false))
        ->add('leftFrontWheel',     'sonata_type_admin', array('required' => false, 'delete' => false))
    ;
}

答案 1 :(得分:0)

更改您的Wheel表单字段,例如:

$formMapper
    // ...
    ->add('leftFrontWheel', 'sonata_type_admin', array(
        'delete' => false,
        'by_reference => true,
        'required' => false,
    ))
    // ...

请参阅by_reference documentation

如果还不够,请在父管理员类中使用prePersist挂钩并管理您存储的字段。即:

// Fire on submit, before the object persisting
public function prePersist($object)
    if ($wheel = $object->getLeftFrontWheel()) {
        if (!$wheel->getYourNonNullableField()) {
            $object->setLefTFrontWheel(null);
        }
    }
}
相关问题