2014-09-14 3 views
0

Я не смог найти решение для моей текущей проблемы в Интернете.Форма Symfony2 недействительна, но сущность все равно сохраняется?

Я получил формуляр и сущность. Если формуляр недействителен ($ 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.')); 

Но entitiy обновляется именно здесь, в этой строке все равно:

if ($form->isValid()) { 

Почему это? Это очень плохая проблема. Я не знаю, почему это происходит.

Спасибо за любой совет.


EDIT:

Дополнительная информация:

Я использую валидаторы тоже для всех полей Wich имеет простые условия. Я делаю это в EntryType.php @ публичной функции buildForm (FormBuilderInterface $ строителем, массив $ вариантов), например:

$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 и почему сущность, стоящая за этой формой, сохраняется даже в том случае, если форма не является полной. 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; 
+0

добавить $ form-> getErrors() в заявлении? – user1954544

+2

Form-> bind - это то, что фактически обновляет объект с опубликованными данными независимо от действительности данных. У вас должен быть еще один флеш. Может быть, слушатель? Обычный рабочий процесс для $ form-> isValid() === false - это повторное отображение формы с недопустимыми данными и сообщениями об ошибках. Еще раз, похоже, что у вас есть что-то, вызывающее $ em-> flush. – Cerad

+0

Cerad. Я нашел это. Это вызвано слушателем, вы получили право! В методе ControllerLister, onKernelController, я всегда обновляю текущий объект пользователя и обновляю его поле «activity_at»! Так как текущий пользователь ВСЕГДА прикреплен к объекту в моем сценарии, он запускает цепочку промывки и, наконец, объект получает обновление. Поэтому, если вы напишете свой комментарий в качестве официального ответа, я могу отметить его как решение. Но позвольте мне задать еще один вопрос: как я могу обновить timestamp activity_at лучше и работать? – titanbird

ответ

2

Форма-> привязка - это то, что фактически обновляет объект с размещенными данными независимо от действительности данных. У вас должен быть еще один флеш . Может быть, слушатель? Обычный рабочий процесс для $ form-> isValid() === false - это повторное отображение формы с недопустимыми данными и сообщениями об ошибках . Опять же, казалось бы, что у вас есть что-то призывающего $ em-> flush.- Кредита @Cerad

+0

Просто для информации: у меня был флеш в слушателе. Он вызывался каждый раз, когда я обновлял страницу. вы получили право! Удалены/исправлены флеш-вызов, и все в порядке. – titanbird

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

Контролер - не лучшее место для няни.Как вы собираетесь повторно использовать валидатор для формы?

+0

Спасибо за ответ. Да, я тоже использую валидаторы. Я обновил свой вопрос, чтобы показать вам некоторые фрагменты кода. Я использую валидаторы для полей, которые имеют простые условия. Но «deadline_enable» - это флажок (boolean, checked = true), а deadline_at (datetime) должен быть только проверен, если этот флажок установлен пользователем. Так что это filds с взаимозависимыми. Но я видел, что эта строка if ($ entry-> getDeadlineEnable() && NULL === $ entry-> getDeadlineAt()) {отлично работает. Поэтому мне все еще интересно, почему объект получает сохранение в базу данных при вызове isValid(). – titanbird

+1

Прочтите это http://symfony.com/blog/new-in-symfony-2-4-a-better-callback-constraint и отправьте подтверждение от контроллера к модели. Добавить die ('die'); в блок вашего условия if и скажите мне, что случилось! –

+0

Спасибо. Я только что прочитал его, и я его реализую. Я расскажу вам, как это работает. Должен ли я переместить ВСЕ валидации в Модель (включая проверки, которые в настоящее время находятся в методе public function buildForm (...)? Или это нормально оставить там простые проверки и просто переместить «сложные» проверки из контроллер для модели? – titanbird

Смежные вопросы