Prima di tutto, non sono sicuro che si tratti di un problema di Sonata o di Symfony2, questa è la prima volta che lavoro con i moduli Sf2 per modificare un relazione.Arresta SonataAdmin/Symfony2 dalla creazione di oggetti vuoti con gli amministratori incorporati sonata_type_admin
Ecco il problema:
Ho due classi, chiamiamoli i favoriti anziani: Car
e Wheel
. L'auto ha una relazione uno-a-uno opzionale con Wheel (è per l'esempio, seguitela ...). Ho impostato SonataAdmin con una classe CarAdmin
che incorpora unutilizzando sonata_type_admin
e provo a creare un'auto senza immettere dati per Wheel.
Tuttavia, su submit (da qualche parte in $ form-> bind()/$ form-> submit() per quanto posso rintracciare) Symfony e/o Sonata sta creando un'istanza di una ruota e cercando di mantenerla (con tutto i suoi valori come null
). Poiché la ruota presenta alcuni vincoli non nulli, ciò genera un'eccezione DBALE che lamenta che non è possibile INSERIRE una ruota con vla null.
Questo è cattivo e vorrei fermarlo. Se non inserisco alcun dettaglio per la ruota, non voglio che una ruota fantasma minacci il mio codice e il mio database. Quello che mi aspetto è che se non inserisco alcun dato non c'è nulla da inserire/persistere quindi è lasciato in pace. Ma questo non è quello che sta succedendo ... qualche idea su come domare questo in qualcosa di sensato?
Ecco la versione lunga, con blocchi di codice e tutto il resto:
Le definizioni ORM prima:
# 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
Poi le classi 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) { ... }
}
e
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) { ... }
}
e, infine, le voci 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]]
atteso/comportamento richiesto:
visualizzare un modulo con tre campi:
- car.color (richiesto)
- car.owner (opzionale)
- car.wheel.diameter (opzionale)
se car.wheel.diameter viene lasciato vuoto quindi non ruota deve essere creato e
test_cars.leftFrontWheelId
dovrebbe rimanerenull
nel databasese car.wheel.diametro viene inserita poi una rotella dovrebbe essere creato e collegato al Car (questo sembra funzionare bene con la configurazione esistente)
La domanda: Come faccio ad avere questo sistema si comporti come sopra?
Penso di essere riuscito a creare una soluzione alternativa per questo, ma ci deve essere un modo migliore! (In CarAdmin ho aggiunto i metodi prePersist() e preUpdate() che controllano se a una ruota manca il diametro. Se è (cioè non è valido) allora '' $ car-> setLeftFrontWheel (null) '' cancella la relazione e smette di cercare di mantenere una ruota vuota.) – caponica
Sonata è soggetta a bug che appaiono casualmente, ma ragionevolmente spesso. Prova a provare una nuova versione, perché il comportamento che descrivi non si verifica nella mia (vecchia) versione. In bocca al lupo! – likeitlikeit
Bene, sto usando la versione più recente (dev-master) di SonataAdmin quindi non penso che ce ne sia una nuova :) Non ancora abbastanza esperto con Symfony per sapere se si tratta di un problema di Symfony o di Sonata, quando so per certo che solleverò la questione appropriata. – caponica