2013-08-10 11 views
15

Zunächst einmal, ich bin mir nicht sicher, ob dies ein Sonata-Problem oder eine Symfony2 ist, das ist das erste Mal, dass ich mit Sf2-Formularen zu bearbeiten bin Beziehung.Stop SonataAdmin/Symfony2 von der Erstellung leerer Objekte mit Sonata_type_admin Embedded Admins

Hier ist das Problem:

ich zwei Klassen haben, lasst sie uns die alten Favoriten nennen: Car und Wheel. Auto hat eine optionale Eins-zu-Eins-Beziehung mit Wheel (es ist für das Beispiel, geh einfach mit ...). Ich habe SonataAdmin mit einer Klasse eingerichtet, die eine WheelAdmin unter Verwendung sonata_type_admin einbettet und versucht, ein Auto zu erstellen, ohne irgendwelche Daten für Wheel einzugeben.

Aber am submit (irgendwo in $ form-> bind()/$ form-> submit() soweit ich verfolgen kann) Symfony und/oder Sonata ein Rad instanziert und versucht, es (mit allen seine Werte als null). Da das Rad einige Nicht-Null-Bedingungen hat, löst dies eine DBALException aus, die sich darüber beschwert, dass Sie kein Wheel mit null values ​​einfügen können.

Das ist unartig und ich würde es gerne stoppen. Wenn ich keine Details für Wheel eingegeben habe, möchte ich kein Phantom Wheel, das meinen Code und meine Datenbank bedroht. Was ich erwarte ist, dass, wenn ich keine Daten eingäbe, es nichts gibt, was man einfügen/persistieren könnte, so dass es in Ruhe gelassen wird. Aber das ist nicht, was passiert ... irgendwelche Ideen, wie dies in etwas Sinnvolles zu zähmen?


Hier ist die lange Version, mit Codeblöcken und alles:

Die ORM Definitionen zuerst:

# 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 

Dann werden die SonataAdmin Klassen:

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) { ... } 
} 

und

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) { ... } 
} 

und schließlich die admin.yml Einträge:

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]] 

Erwartete/erforderliches Verhalten:

  • Anzeige eine Form mit drei Feldern:

    • car.color (erforderlich)
    • Fahrzeugbesitzer (optional)
    • car.wheel.diameter (optional)
  • wenn car.wheel.diameter leer gelassen wird, dann sollte kein Rad erstellt werden und test_cars.leftFrontWheelId sollte null in der Datenbank

  • wenn car.wheel bleiben.Durchmesser eingegeben wird dann ein Rad sollte mit dem Auto erstellt und verknüpft wird (dies scheint mit der bestehenden Konfiguration zu funktionieren)

Die Frage: Wie bekomme ich dieses System, wie oben zu verhalten?

+4

Ich glaube, ich habe es geschafft, eine Abhilfe zu schaffen, aber es muss einen besseren Weg geben! (In CarAdmin habe ich die Methoden prePersist() und preUpdate() hinzugefügt, die prüfen, ob einem Wheel der Durchmesser fehlt. Ist dies der Fall, dann löscht '' car-> setLeftFrontWheel (null) '' die Beziehung und Stoppt den Versuch, ein leeres Rad zu halten.) – caponica

+0

Sonate ist anfällig für Fehler, die zufällig, aber ziemlich oft auftreten. Probieren Sie eine neue Version aus, weil das von Ihnen beschriebene Verhalten in meiner (alten) Version nicht auftritt. Viel Glück! – likeitlikeit

+0

Nun, ich benutze die neueste (dev-master) Version von SonataAdmin, also glaube ich nicht, dass es eine neuere gibt :) Nicht genug Erfahrung mit Symfony, um zu wissen, ob dies ein Symfony-Problem ist oder eine Sonate, wenn ich Ich bin mir sicher, dass ich das entsprechende Problem ansprechen werde. – caponica

Antwort

0

Es könnte durch eine fehlende 'required' => false, nein verursacht werden?

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

Ihr Wheel Formularfeld wie für etwas ändern:

$formMapper 
    // ... 
    ->add('leftFrontWheel', 'sonata_type_admin', array(
     'delete' => false, 
     'by_reference => true, 
     'required' => false, 
    )) 
    // ... 

Siehe by_referencedocumentation

Wenn es nicht ausreichend ist, einen PrePersist Haken in Ihren Eltern Admin-Klasse verwenden und verwalten, welche Feld Sie speichern . d. h .: