Формы Symfony2 интерпретируют пустые строки как нули

У меня есть форма Symfony2 с различными полями, включая одно необязательное текстовое поле под названием recap.

Это поле recap отлично сохраняется, когда в нем есть текст, но когда поле остается пустым, я получаю эту ошибку:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'recap' cannot be null

Это право - столбец recap не может быть null. Я назначил это специально. null означает неизвестный. Когда пользователь оставляет recap пробел, значение recap не является неизвестным; оно пустое.

Мой вопрос заключается в том, как заставить Symfony сохранять recap как '', когда он пуст, а не null.

Ответы

Ответ 1

Перейдите к своему объекту и перейдите к объявлению переменных.

/**
 * @var string $name
 *
 * @ORM\Column(type="string", length=50)
 */
public $recap = '';

вы можете присвоить значение по умолчанию для $recap.

Или иначе, когда у вас есть функция setRecap, вы можете проверить, пуст или не установлен, и установить ожидаемое значение.

public function setRecap($recap) {
   $this->recap = !isset($recap) ? '': $recap;
}

Или вы устанавливаете значение по умолчанию в своей форме. Тип - '', но я думаю, что это не то, что вы ожидаете.

Ответ 2

Правда, потерял много часов на этом;-( "преобразование" жестко закодировано в компоненте Form.php line 1113!

private function viewToNorm($value)
{
    $transformers = $this->config->getViewTransformers();

    if (!$transformers) {
        return '' === $value ? null : $value;
    }

    for ($i = count($transformers) - 1; $i >= 0; --$i) {
        $value = $transformers[$i]->reverseTransform($value);
    }

    return $value;
}

По-моему, это большая ошибка (потому что это роль DataTransformer, а не Form). Таким образом, решение состоит в том, чтобы создать собственный DataTransformer и связать его с типом текста. В настоящее время я теряю так много времени с Symfony2, всегда ищу в источниках этот вид маленького взлома; - (

Ответ 3

У меня есть другое решение для этой проблемы:

создать фиктивный класс

class EmptyString {
    public function __toString() {
        return '';
    }
}

и установите

$builder->add('recap', 'text', [
    'empty_data' => new EmptyString(),
]);

Когда объект будет сохранен в БД, он автоматически преобразуется в пустую строку.

Ответ 4

Я думаю, что вы неправильно делаете проблему: когда пользователь оставляет декларацию пустой, значение неизвестно, потому что не указано. Например, вы не говорите, что пустое поле даты рождения означает, что дата рождения равна "", но дата рождения неизвестна. То же самое касается адресов и т.д.

Итак, если ваш пользователь не обязан заполнять это поле, кажется, что наиболее релевантный ответ на самом деле означает, что ваше поле является нулевым.

Ответ 5

Только что встретила аналогичную ошибку в Symfony2:

Моя сущность:

/**
 * @ORM\Column(type="boolean")
 */
protected $Valid;

Моя форма:

$builder->add('Valid', 'hidden');

Теперь для истинных значений поле отображается правильно со значением = "1", но для поля ложных значений отображается value = "", что приводит к:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Valid' cannot be null

Хотя я ожидаю, что это будет отображаться как value = "0".

Конечно, метод setValid() может быть расширен для установки правильного значения:

public function setValid($valid)
{
    $this->Valid = ($valid ? true : false);
}

Какая проблема вокруг проблемы, а не исправляет ее.

Ответ 6

В Формах вы можете:

$builder
->add('optionalField', TextType::class, ['required'=>false, 'empty_data'=>''])

Ответ 7

Я также столкнулся с этой проблемой. И мне было предложено изящное решение: сделать это определение @ORM\Column(type="string", length=50, nullable=true)