2013-08-10 11 views
15

まずソナタの問題かSymfony2のどちらかとは分かりませんが、私はSf2フォームを使って編集するのは初めてです。関係。ここでSonataAdmin/Symfony2がsonata_type_adminを組み込んだ空のオブジェクトを作成しないようにしてください

が問題だ:CarWheel

私は2つのクラスを持っている、のは、昔のお気に入りにそれらを呼びましょう。車はホイールとオプションの1対1の関係を持っています(これは例のためだけですが...)。 sonata_type_adminを使用してWheelAdminを埋め込んだCarAdminクラスのSonataAdminをセットアップし、Wheelのデータを入力せずに車を作成しようとしました。

しかし、symfonyやSonataはWheelをインスタンス化して、それを永続化しようとしています(すべてを使って、$ form-> bind()/ $ form-> submitその値はnullとなります)。 Wheelにはnull以外の制約がいくつか存在するため、ヌル値を持つWheelをINSERTできないというDBALExceptionがスローされます。

これはいたずらであり、私はそれをやめています。私はホイールの詳細を入力しない場合、私はファントムホイールが私のコードとデータベースを脅かすことは望ましくありません。私が期待しているのは、データを入力しなければ、挿入/保持するものは何もないので、それだけで済むということです。しかし、これは何が起こっているかではありません... 任意のアイデアをどのように賢明な何かに飼いならす方法?

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

予想される/必要な行動:

  • 表示三つのフィールドを持つフォーム:

    • car.color(必須)
    • car.owner(オプション)
    • car.wheel.diameter(オプション)
  • car.wheel.diameterが空白のままであれば、いかなるホイールが作成されるべきではないとtest_cars.leftFrontWheelId

  • car.wheelならデータベースにnullのままであるべきです。直径はその後、ホイールが作成され、車にリンクされなければならない入力された

質問を(これは、既存の設定で正常に動作するようです):はどのように私は、このシステムは、上記のように動作するのですか?

+4

私はこれの回避策を形成することができたと思いますが、より良い方法が必要です。 (CarAdminで)ホイールに直径がないかどうかを調べるprePersist()メソッドとpreUpdate()メソッドを追加しました。もしそれが無効ならば、 '' $ car-> setLeftFrontWheel(null) ''は関係をクリアし、空のホイールを持続しようとするのを止める) – caponica

+0

ソナタはバグがランダムに現れる傾向がありますが、合理的に頻繁に表示されます。私の(古い)バージョンでは、あなたが説明している動作が起こらないので、新しいバージョンをチェックアウトしてみてください。がんばろう! – likeitlikeit

+0

まあ、最新の(dev-master)バージョンのSonataAdminを使用していますので、新しいバージョンはないと思います:) Symfonyの問題かSonataの問題か、私は適切な問題を提起することを確かに知っている。 – caponica

答えて

0

これは、紛失した'required' => falseが原因である可能性があります。それは十分ではない場合、あなたは格納するフィールドあなたの親管理クラスにprePersistフックを使用して管理by_referencedocumentation

を参照してください

$formMapper 
    // ... 
    ->add('leftFrontWheel', 'sonata_type_admin', array(
     'delete' => false, 
     'by_reference => true, 
     '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)) 
    ; 
} 
0
のようなもののためにあなたの Wheelフォームフィールドを変更します

。すなわち:

// Fire on submit, before the object persisting 
public function prePersist($object) 
    if ($wheel = $object->getLeftFrontWheel()) { 
     if (!$wheel->getYourNonNullableField()) { 
      $object->setLefTFrontWheel(null); 
     } 
    } 
} 
関連する問題