12

私は3つのレイヤーを持つフォームを持っています:最初のレイヤーはゲームのコンテナです:

class GameListType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('games', 'collection', array(
            'required' => false,
            'allow_add' => true,
            'prototype' => true,
            'by_reference' => false,
            'type' => new GameBetType(),
        ))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'cascade_validation' => true,
        ));
    }  
}

2 番目のレイヤーはゲームそのものです。ゲームを変更するつもりはありませんが、それに賭けるので、賭けのフォームのみが含まれます。

class GameBetType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {   
        $builder->add('bet', new BetType());
    }

    public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'data_class' => 'Strego\TippBundle\Entity\Game',
            'cascade_validation' => true,
        ));
    }  
}

3 番目の層は、賭けのフォームです。

class BetType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('scoreT1' , 'text')
                ->add('scoreT2' , 'text');
        ;
    }


        public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'data_class' => 'Strego\TippBundle\Entity\Bet',
        ));
    }

}

問題は、第 3 レベルに検証制約がある場合、ルート フォームは常に有効ですが、ベット エンティティを具体的に検証すると、コントローラーで正しい違反リストを取得することです。

// Form processing
$form = $this->createForm(new GameListType(), $entity);
$request = $this->getRequest();

if ($request->getMethod() == 'POST') {
    $form->bind($request);
    $entity = $form->getData();

    if ($form->isValid()) {
        foreach ($entity->getGames() as $game) {                  
            if($game->hasBet()){
                $bet = $game->getBet();
                $bet->setUser($user);
                $validator = $this->container->get('validator');
                $errors = $validator->validate($bet);
                var_dump($errors)  //<-- i see there are errors
                if(count($errors) == 0){
                    print($bet. ' gets persisted<br>');
                    $em->persist($bet);
                } 
            }             
        }
    $em->flush();
    }
}

$em->persist($bet)別の問題は、エンティティを呼び出さなくても永続化されることです。行に記述されている出力が表示されません

print($bet.'gets persisted<br>'); 

ただし、フォーム入力は引き続きデータベースに保持されます。

だから私の2つの質問:

  1. ベットの検証がフォームに失敗した場合にエラーを取得するにはどうすればよいですか (3 つのベットのうち 1 つだけが無効になる可能性があるため、フォーム全体を無効にしたくありません)。

  2. コールしなくてもベットが持続するのはなぜ$em-persist($bet)ですか? これはバインディングで起こる魔法ですか?

4

3 に答える 3

3

2 番目の質問に答えるために、エンティティとの間の双方向のOneToMany関係を宣言し、関係の側に設定した可能性があります。そのため、エンティティ マネージャは、次の操作で挿入/更新するエンティティ オブジェクトを自動的にマークします。また、行をループの外に移動します。メソッドは db クエリを発行するため、コードがループに入るたびに db に接続します。ifがループの外にある場合、エンティティは、変更されたすべての SQL が 1 つのトランザクションにラップされた状態で 1 回クエリを実行します。UserBetcascade={"persist"}UserBetflush$em->flush();flush$em->flush();

于 2012-09-01T22:55:31.300 に答える
1

cascade_validationゲームcollectionの種類に追加するのを忘れるだけです

$builder->add('games', 'collection', array(
    'required' => false,
    'allow_add' => true,
    'prototype' => true,
    'by_reference' => false,
    'type' => new GameBetType(),
    'cascade_validation' => true
));
于 2013-12-12T03:31:22.393 に答える
0

gameエンティティではなく、エンティティを永続化する必要があると確信していますbet

検証グループが設定されているかどうかの検証チェックでは、それが正しく検証されない理由である可能性があります。

于 2013-03-14T12:21:22.173 に答える