Empêcher SonataAdmin / Symfony2 de créer des objets vides avec Sonata type admin admins imbriqués
tout d'Abord, je ne suis pas sûr si c'est une Sonate ou Symfony2, c'est la première fois que je travaille avec Sf2 formulaires pour modifier une relation.
Voici le problème:
j'ai deux classes, appelons-les vieux favoris: Car
et Wheel
. Voiture a une relation facultative un-à-un avec la roue (c'est pour l'exemple, il suffit d'aller avec elle...). J'ai mis en place SonataAdmin avec un CarAdmin
classe qui intègre un WheelAdmin
en utilisant sonata_type_admin
et essayer de créer des une voiture sans entrer de données pour la roue.
Toutefois, sur "soumettre" (quelque part dans $form->bind()/$form->submit() pour autant que je peux laisser de traces) Symfony et/ou d'une Sonate est l'instanciation d'une Roue et d'essayer de persister (avec toutes ses valeurs null
). Puisque la roue a quelques contraintes non-null cela jette une DBALException se plaindre que vous ne pouvez pas insérer une roue avec null vlaues.
C'est méchant et j'aimerais arrêter ce qui se passe. Si je ne saisissez pas Je ne veux pas qu'une roue fantôme Menace mon code et ma base de données. Ce que j'attends c'est que si je n'entre pas de données il n'y a rien à insérer/persister donc il est laissé seul. Mais ce n'est pas ce qui se passe... avez-vous des idées pour apprivoiser ceci en quelque chose de sensé?
Voici la version longue, avec des blocs de code et tout:
L'ORM définitions d'abord:
# MyNSMyBundleResourcesConfigDoctrineCar.orm.yml
MyNSMyBundleEntityCar:
type: entity
repositoryClass: MyNSMyBundleEntityRepositoriesCarRepository
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
# MyNSMyBundleResourcesConfigDoctrineWheel.orm.yml
MyNSMyBundleEntityWheel:
type: entity
repositoryClass: MyNSMyBundleEntityRepositoriesWheelRepository
table: test_wheels
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
diameter:
type: integer
length: 5
puis la SonataAdmin classes:
namespace MyNSMyBundleAdmin
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) { ... }
}
et
namespace MyNSMyBundleAdmin;
use ...
class WheelAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('diameter', null, array('required' => false))
;
}
protected function configureListFields(ListMapper $listMapper) { ... }
}
et enfin l'admin.entrées yml:
services:
sonata.admin.car:
class: MyNSMyBundleAdminCarAdmin
tags:
- { name: sonata.admin, manager_type: orm, label: "Car" }
arguments:
- ~
- MyNSMyBundleEntityCar
- 'SonataAdminBundle:CRUD'
calls:
- [ setTranslationDomain, [MyNSMyBundle]]
sonata.admin.wheel:
class: MyNSMyBundleAdminWheelAdmin
tags:
- { name: sonata.admin, manager_type: orm, label: "Wheel" }
arguments:
- ~
- MyNSMyBundleEntityWheel
- 'SonataAdminBundle:CRUD'
calls:
- [ setTranslationDomain, [MyNSMyBundle]]
comportement attendu/requis:
Afficher un formulaire avec trois champs:
- voiture.couleur (obligatoire)
- voiture.propriétaire (facultatif)
- voiture.roue.diamètre (en option)
si la voiture.roue.le diamètre est laissé vide alors aucune roue ne doit être créée et
test_cars.leftFrontWheelId
doit resternull
dans la base de donnéessi la voiture.roue.diamètre de l'entrée puis une Roue doit être créé et lié à la Voiture (ce qui semble bien fonctionner avec la config)
la question: Comment faire pour que ce système se comporte comme ci-dessus?
2 réponses
C'est peut-être causé par un manque 'required' => false
, non ?
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))
;
}
Modifier Wheel
champ de formulaire pour quelque chose comme :
$formMapper
// ...
->add('leftFrontWheel', 'sonata_type_admin', array(
'delete' => false,
'by_reference => true,
'required' => false,
))
// ...
Voir by_reference
documentation
si ce n'est pas suffisant, utilisez un crochet prePersist dans votre classe d'admin parent et gérez le champ que vous stockez. i.e.:
// Fire on submit, before the object persisting
public function prePersist($object)
if ($wheel = $object->getLeftFrontWheel()) {
if (!$wheel->getYourNonNullableField()) {
$object->setLefTFrontWheel(null);
}
}
}