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 rester null dans la base de données

  • si 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?

15
demandé sur caponica 2013-08-10 04:31:14

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))
    ;
}
0
répondu LaurentG 2014-02-18 14:42:40

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);
        }
    }
}
0
répondu chalasr 2016-02-07 11:10:53