Symfony2表单无效,但实体仍会被保存


Symfony2 form is not valid but entity gets saved anyway?

我在web中找不到当前问题的解决方案。

我有一个公式和一个实体。如果公式无效($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公共函数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之间的数字的数字字段。但对于一些文件,我在控制器操作方法中使用了自己的验证方法,因为字段(大多数是复选框字段和属于该复选框的文本字段的组合)是相互依赖的。

我仍然不知道isValid有什么问题,也不知道为什么即使表单不是完全有效,这个表单后面的实体也会被保存。如果存在错误(correct),则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;

表单->bind实际上是用posted更新实体数据,而不管数据的有效性如何。你一定又脸红了在某个地方被踢飞。也许是听众?的正常工作流程$form->isValid()==false是用无效的数据和错误消息。再一次,你似乎叫$em->flush的东西-信用给@Cerad

您曾经尝试过验证器吗?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.'));
}

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