15

まず第一に、これが Sonata の問題なのか Symfony2 の問題なのかわかりません。関係を編集するために Sf2 フォームを操作するのはこれが初めてです。

問題は次のとおりです。

私は 2 つのクラスを持っていCarますWheel。Car は、オプションで Wheel との 1 対 1 の関係を持ちます (これは例です。そのまま使用してください...)。私は使用CarAdminを埋め込むクラスでSonataAdmin をセットアップし、Wheel のデータを入力せずに Car を作成しようとしました。WheelAdminsonata_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 にリンクする必要があります (これは既存の構成で問題なく動作するようです)。

質問:このシステムを上記のように動作させるにはどうすればよいですか?

4

2 に答える 2

0

Wheelフォーム フィールドを次のように変更します。

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

ドキュメントを見るby_reference

十分でない場合は、親の admin クラスで prePersist フックを使用し、保存するフィールドを管理します。すなわち:

// Fire on submit, before the object persisting
public function prePersist($object)
    if ($wheel = $object->getLeftFrontWheel()) {
        if (!$wheel->getYourNonNullableField()) {
            $object->setLefTFrontWheel(null);
        }
    }
}
于 2016-02-07T11:02:32.047 に答える
0

の欠落が原因である可能性があり'required' => falseますね。

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))
    ;
}
于 2014-02-18T14:42:40.200 に答える