まず第一に、これが Sonata の問題なのか Symfony2 の問題なのかわかりません。関係を編集するために Sf2 フォームを操作するのはこれが初めてです。
問題は次のとおりです。
私は 2 つのクラスを持っていCar
ますWheel
。Car は、オプションで Wheel との 1 対 1 の関係を持ちます (これは例です。そのまま使用してください...)。私は使用CarAdmin
を埋め込むクラスでSonataAdmin をセットアップし、Wheel のデータを入力せずに Car を作成しようとしました。WheelAdmin
sonata_type_admin
ただし、送信時 (追跡できる限り $form->bind()/$form->submit() のどこか)、Symfony および/または Sonata は Wheel をインスタンス化し、それを永続化しようとしています (すべての値を としてnull
) . Wheel にはいくつかの非 null 制約があるため、null 値を持つ Wheel を INSERT できないことを訴える DBALException がスローされます。
これはやばいのでやめてほしいです。Wheel の詳細を入力しない場合、幻の Wheel が私のコードとデータベースを脅かすことは望ましくありません。私が期待しているのは、データを入力しない場合、挿入/保持するものがないため、そのままにしておくことです。しかし、これは起こっていることではありません...これを賢明なものに飼いならす方法はありますか?
コードブロックとすべてを含むロングバージョンは次のとおりです。
最初に ORM 定義:
# 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
次に、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) { ... }
}
と
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) { ... }
}
そして最後に 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]]
予想される/必要な動作:
3 つのフィールドを持つフォームを表示します。
- car.color (必須)
- car.owner (オプション)
- car.wheel.diameter (オプション)
car.wheel.diameter が空白のままの場合、ホイールは作成されず、データベースに
test_cars.leftFrontWheelId
残りますnull
car.wheel.diameter が入力されている場合は、Wheel を作成して Car にリンクする必要があります (これは既存の構成で問題なく動作するようです)。
質問:このシステムを上記のように動作させるにはどうすればよいですか?