Symfony2表单无效但实体仍然保存?

时间:2014-09-14 17:22:41

标签: php forms validation symfony

我无法找到解决当前网络问题的解决方案。

我有一个公式和一个实体。 如果公式无效($ form-> isValid()返回false),则无论如何都会使用无效数据保存实体。我看到表单错误,这是正确的。但是如果表单无效,我的实体不应该更新。这里出了什么问题? 我的实体得到了一个完整的字段和与额外字段的多对多关系。

我可以向您展示一些代码部分:

$entry = $em->getRepository('MyAppBundle:Entry')->find($id);

// ...

$form = $this->createForm(new EntryType($this->getUser(), $entry), $entry);

$request = $this->getRequest();

if ($request->getMethod() == 'POST') {

    $form->bind($request);

// ...

// i set custom errors here by myself!

if ($entry->getDeadlineEnable() && NULL === $entry->getDeadlineAt()) {
    $form->get('deadline_at')->addError(new FormError('Please enter a date.'));
}

// ...

if ($form->isValid()) {

    $em->merge($entry);
    $em->flush();

    // ...

    return $this->redirect($this->generateUrl('MyAppBundle_homepage'));

正如您所看到的,我使用isValid检查表单,这是正确的。如果存在表单错误,则返回false,例如

$form->get('deadline_at')->addError(new FormError('Please enter a date.'));

但是,无论如何,权利都会在此处更新:

if ($form->isValid()) {

这是为什么? 这是一个非常糟糕的问题。我不知道为什么会这样。

感谢您的任何建议。


编辑:

更多信息:

对于条件简单的所有领域,我也使用验证器。 我在EntryType.php @ public function buildForm(FormBuilderInterface $ builder,array $ options)中执行此操作,例如:

$builder->add('min_commitments', null, array(
    'label' => 'Zusagen mindestens',
    'attr' => array(
        'class' => 'form-control',
        'placeholder' => 'Ab wievielen findet\'s statt?',
        'min' => 0,
        'max' => 100,
    ),
    'required' => false,
    'invalid_message' => 'Das ist keine gütige Angabe.',
    'constraints' => array(
        new Range(array(
            'minMessage' => 'Mindestens 1.',
            'maxMessage' => 'Maximal 100.',
            'min' => 1,
            'max' => 100,
        )),
    ),
));

这是一个数字字段,用于输入1到100之间的数字。 但对于某些文件我在控制器操作方法中使用我自己的验证direclty,因为字段(大多数是复选框字段和属于此复选框的文本字段的组合),因为许多字段是相互依赖的。

我仍然不知道isValid有什么问题以及为什么这个表单背后的实体会被保存,即使表单不完全有效。如果存在错误(正确),则isValid在那里返回false。

这可能是由多对多关系引起的吗? 我实现了这样一种关系,允许用户选择许多复选框,其中每个复选框代表一个用户。关系行保存在关系表EntryUser中。 这是表单定义中的多对多字段(Entry.php):

/**
 * @ORM\OneToMany(targetEntity="EntryUser", mappedBy="entry", cascade={"all"}, orphanRemoval=true)
 */
protected $entry_users; // One more thing: this is a one to many but it is a many to many relationship at all because i created a relationship table with extra fields so it bacame a own entity. on the other side, the file User.php got the oppsite part of the many-to-many relationship with:

user.php的:

/**
 * @ORM\OneToMany(targetEntity="EntryUser" , mappedBy="user" , cascade={"all"} , orphanRemoval=true)
 */
protected $entry_users;

2 个答案:

答案 0 :(得分:2)

  

form-> bind是实际更新已发布的实体的内容   数据无论数据的有效性如何。你必须有另一个同花顺   在某个地方被踢开了。也许是听众?正常的工作流程   $ form-> isValid()=== false是重新显示带有无效的表单   数据和错误消息。再一次,看起来你有   调用$ em-> flush.-的东西   归功于@Cerad

答案 1 :(得分:1)

你有没有试过验证器? http://symfony.com/doc/current/book/validation.html

如果您的附加代码来自您的控制器 - 问题是您的情况有误。

if ($entry->getDeadlineEnable() && NULL === $entry->getDeadlineAt()) {
    $form->get('deadline_at')->addError(new FormError('Please enter a date.'));
}

控制器不是最好的地方。您如何重用表单的验证器?