首先,我不确定这是Sonata问题还是Symfony2问题,这是我第一次使用Sf2表单来编辑关系。
问题在于:
我有两个课程,我们称之为旧版:Car
和Wheel
。 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.wheel.diameter留空,则不应创建Wheel并且test_cars.leftFrontWheelId
应保留在数据库中null
如果输入car.wheel.diameter,则应创建Wheel并将其链接到Car(这似乎与现有配置一起使用)
问题:如何让此系统按上述方式运行?
答案 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);
}
}
}