2012-08-26 107 views
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, 
     )); 
    } 
} 

第二层是游戏本身,因为我不打算改变游戏,但在其上的赌注,它只包括用于下注的形式:

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, 
     )); 
    } 
} 

而第三层是用于下注的形式:

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', 
     )); 
    } 

} 

的问题是,如果有第三级验证约束,根形式始终是有效的,但如果我专门验证赌实体,我得到了我的控制器正确违反列表:

// 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>'); 

但形式输入仍然保存到数据库中描述的输出。

所以我的两个问题:

  1. 我如何得到错误,如果验证失败对赌失败到窗体(我不想整个形式是无效的,因为只有能3次投注中有1次无效)。

  2. 即使我不打电话给$em-persist($bet),为什么赌注仍然存在,这是否与绑定发生了一些魔术?

+0

好心也提供类AbstractType – Vineet1982

+0

其Symfony2的默认AbstractType:https://github.com/symfony/symfony/blob/master/src /Symfony/Component/Form/AbstractType.php – m0c

回答

3

要回答你的第二个问题,你可能已经宣告UserBet实体之间的双向OneToMany关系和关系的User侧设置cascade={"persist"}。所以实体管理器在下一个flush操作中自动标记Bet实体对象以进行插入/更新。同时将$em->flush();行移出循环。由于flush方法发出db查询,它每次代码进入循环时都会连接到db。而如果$em->flush();在循环之外,则实体将使用在单个事务中包装的所有更改的sql进行一次查询。

+0

我有一个双方关系,但不是cascade = {坚持]双方。冲洗在循环之外,也许我错了。 – m0c

0

我敢肯定,你应坚持game实体,而不是一个bet

验证检查是否有验证组设置,可能是验证不正确的原因。

+0

在这个表格中只有投注被提交,游戏已经存在并且没有改变。并没有验证组。 – m0c

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 
));