[英]Stop SonataAdmin / Symfony2 from creating empty objects with sonata_type_admin embedded admins
First of all, I'm not sure if this is a Sonata issue or a Symfony2 one, this is the first time I'm working with Sf2 forms to edit a relationship. 首先,我不确定这是Sonata问题还是Symfony2问题,这是我第一次使用Sf2表单来编辑关系。
Here's the problem: 这是问题所在:
I have two classes, let's call them the old favourites: Car
and Wheel
. 我有两个课程,让我们称之为旧的最爱: Car
和Wheel
。 Car has an optional one-to-one relationship with Wheel (it's for the example, just go with it...). Car与Wheel有一个可选的一对一关系(例如,它就是它......)。 I have set up SonataAdmin with a CarAdmin
class which embeds a WheelAdmin
using sonata_type_admin
and try to create a Car without entering any data for Wheel. 我已成立了SonataAdmin与CarAdmin
中嵌入一个类WheelAdmin
使用sonata_type_admin
和尝试不输入任何数据的轮创造了一辆车。
However, on submit (somewhere in $form->bind()/$form->submit() as far as I can trace) Symfony and/or Sonata is instantiating a Wheel and trying to persist it (with all its values as null
). 但是,在提交时(在$ form-> bind()/ $ form-> submit()的某个地方,我可以跟踪)Symfony和/或Sonata实例化一个Wheel并试图保持它(其所有值为null
)。 Since the Wheel has some non-null constraints this throws a DBALException complaining that you cannot INSERT a Wheel with null vlaues. 由于Wheel具有一些非null约束,因此抛出DBALException,抱怨您无法使用null值来插入Wheel。
This is naughty and I'd like to stop it happening. 这很顽皮,我想阻止它发生。 If I don't enter any details for Wheel I don't want a phantom Wheel menacing my code and database. 如果我没有输入Wheel的任何细节,我不希望幻影轮对我的代码和数据库造成威胁。 What I expect is that if I enter no data there is nothing to insert/persist so it's left alone. 我期望的是,如果我没有输入任何数据,就没有任何内容可以插入/保留,所以它不会被单独存在。 But this is not what's happening... any ideas how to tame this into something sensible? 但这不是正在发生的事情...... 任何想法如何将其驯服成合情合理的东西?
Here's the long version, with code blocks and everything: 这是长版本,包含代码块和所有内容:
The ORM definitions first: 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
Then the SonataAdmin classes: 然后是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) { ... }
}
and 和
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) { ... }
}
and finally the admin.yml entries: 最后是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]]
Expected/required behaviour: 预期/要求的行为:
Display a form with three fields: 显示包含三个字段的表单:
if car.wheel.diameter is left blank then no Wheel should be created and test_cars.leftFrontWheelId
should remain null
in the database 如果car.wheel.diameter留空,则不应创建Wheel,并且test_cars.leftFrontWheelId
应在数据库中保持为null
if car.wheel.diameter is entered then a Wheel should be created and linked to the Car (this seems to work fine with the existing config) 如果输入car.wheel.diameter,则应创建一个Wheel并链接到Car(这似乎与现有配置一起使用)
The question: How do I get this system to behave as above? 问题: 我如何让这个系统表现如上?
It might be caused by a missing 'required' => false
, no ? 它可能是由于缺少'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))
;
}
Change your Wheel
form field for something like : 更改您的Wheel
表单字段,例如:
$formMapper
// ...
->add('leftFrontWheel', 'sonata_type_admin', array(
'delete' => false,
'by_reference => true,
'required' => false,
))
// ...
See by_reference
documentation 请参阅by_reference
文档
If it's not sufficient, use a prePersist hook in your parent admin class and manage which field you store. 如果还不够,请在父管理员类中使用prePersist挂钩并管理您存储的字段。 ie : 即:
// Fire on submit, before the object persisting
public function prePersist($object)
if ($wheel = $object->getLeftFrontWheel()) {
if (!$wheel->getYourNonNullableField()) {
$object->setLefTFrontWheel(null);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.