2012-08-26 7 views
12

ich ein Formular mit drei Schichten: Erste Schicht der Behälter für die Spiele ist:Cascade Validation funktioniert nicht auf dritte Schicht eines Formulars

class GameListType extends AbstractType { 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder->add('games', 'collection', array(
      'required' => false, 
      'allow_add' => true, 
      'prototype' => true, 
      'by_reference' => false, 
      'type' => new GameBetType(), 
     )) 
     ; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) { 
     parent::setDefaultOptions($resolver); 
     $resolver->setDefaults(array(
      'cascade_validation' => true, 
     )); 
    } 
} 

Zweite Schicht ist das Spiel selbst, da ich nicht tun beabsichtigen, das Spiel zu ändern, aber die Wette darauf, es enthält nur die Form für die Wette:

class GameBetType extends AbstractType { 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder->add('bet', new BetType()); 
    } 

    public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) { 
     parent::setDefaultOptions($resolver); 
     $resolver->setDefaults(array(
      'data_class' => 'Strego\TippBundle\Entity\Game', 
      'cascade_validation' => true, 
     )); 
    } 
} 

und die dritte Schicht ist die Form für die Wette:

class BetType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

     $builder->add('scoreT1' , 'text') 
       ->add('scoreT2' , 'text'); 
     ; 
    } 


     public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) { 
     parent::setDefaultOptions($resolver); 
     $resolver->setDefaults(array(
      'data_class' => 'Strego\TippBundle\Entity\Bet', 
     )); 
    } 

} 

Das Problem ist, dass, wenn es Validierungseinschränkungen auf der dritten Ebene sind, die Stammform immer gültig ist, aber wenn ich die Wette Einheit speziell bestätigen, ich habe die richtige Verletzung Liste in meinem Controller erhalten:

// Form processing 
$form = $this->createForm(new GameListType(), $entity); 
$request = $this->getRequest(); 

if ($request->getMethod() == 'POST') { 
    $form->bind($request); 
    $entity = $form->getData(); 

    if ($form->isValid()) { 
     foreach ($entity->getGames() as $game) {     
      if($game->hasBet()){ 
       $bet = $game->getBet(); 
       $bet->setUser($user); 
       $validator = $this->container->get('validator'); 
       $errors = $validator->validate($bet); 
       var_dump($errors) //<-- i see there are errors 
       if(count($errors) == 0){ 
        print($bet. ' gets persisted<br>'); 
        $em->persist($bet); 
       } 
      }    
     } 
    $em->flush(); 
    } 
} 

Ein weiteres Problem ist, dass, selbst wenn ich $em->persist($bet) nicht aufrufen, die Entitäten persistiert werden. Ich sehe die in der Zeile

beschriebene Ausgabe nicht, aber der Formulareingang bleibt weiterhin in der Datenbank erhalten.

Also meine zwei Fragen:

  1. Wie kann ich die Fehler, wenn die Validierung fehlschlägt auf die Wette auf das Formular nicht (ich will nicht die ganze Form für ungültig, da konnte es nur 1 von 3 Wetten ist ungültig.

  2. Warum bleibt die Wette bestehen, auch wenn ich nicht $em-persist($bet) anrufe, ist das eine Magie, die mit der Bindung passiert?

+0

freundlicherweise zur Verfügung stellen auch die Klasse Abstract – Vineet1982

+0

sein die Symfony2 Standardabstract hinzuzufügen: https://github.com/symfony/symfony/blob/master/src /Symfony/Component/Form/AbstractType.php – m0c

Antwort

3

Ihre zweite Frage zu beantworten, Sie OneToMany Beziehung zwischen User und Bet Einheit bi-direktionale erklärt haben und setzen cascade={"persist"} auf User Seite der Beziehung. Daher markiert der Entitätsmanager automatisch Bet Entitätsobjekte für das Einfügen/Aktualisieren in der nächsten Operation flush. Verschieben Sie auch $em->flush(); Zeile aus der Schleife. Als flush Methode Probleme DB Abfrage, es verbindet sich zu Db jedes Mal Code in die Schleife eintritt. Wenn sich $em->flush(); außerhalb der Schleife befindet, fragt die Entität einmal nach allen geänderten sql ab, die in einer einzigen Transaktion eingeschlossen sind.

+0

Ich habe eine bidirektionale Beziehung, aber keine Kaskade = {persist] auf keiner der beiden Seiten. Die Flush ist außerhalb der Schleife, vielleicht habe ich es falsch kopiert. – m0c

0

Ich bin mir ziemlich sicher, dass Sie die Einheit beibehalten sollten und nicht die bet eins.

Für die Validierungsprüfung, ob eine Validierungsgruppe eingerichtet wurde, könnte dies der Grund sein, warum sie nicht richtig validiert wird.

+0

In dieser Form werden nur Wetten abgegeben, die Spiele haben vorher existiert und werden nicht geändert.Und es gibt keine Validierungsgruppen. – m0c

1

Sie vergessen nur cascade_validation Spiele collection Typ

$builder->add('games', 'collection', array(
    'required' => false, 
    'allow_add' => true, 
    'prototype' => true, 
    'by_reference' => false, 
    'type' => new GameBetType(), 
    'cascade_validation' => true 
));