我有一个3层的表格: First Layer是游戏的容器:
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>');
但表单输入仍然保留在数据库中。
所以我的两个问题:
如果验证失败,如果投注失败,我如何得到错误(我不希望整个表格无效,因为3个投注中只有1个无效)。< / p>
为什么即使我不打电话给$em-persist($bet)
,赌注仍然存在,这是绑定时发生的一些魔力吗?
答案 0 :(得分:3)
要回答您的第二个问题,您可能已宣布OneToMany
和User
实体之间存在双向Bet
关系,并在cascade={"persist"}
侧设置User
这种关系。因此,实体管理器会在下一个Bet
操作中自动标记flush
实体对象以进行插入/更新。同时将$em->flush();
行移出循环。当flush
方法发出db查询时,它会在每次代码进入循环时连接到db。如果$em->flush();
在循环之外,则实体将使用包含在单个事务中的所有已更改的sql查询一次。
答案 1 :(得分: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
));
答案 2 :(得分:0)
我很确定你应该坚持game
实体,而不是bet
实体。
对于验证检查是否存在某些验证组设置,可能是它无法正确验证的原因。