Символьная форма Поле Атрибут empty_data Игнорируется

Согласно документации Symfony 2.4 , любое поле формы, которое не требуется, но представлено без какого-либо значения (значение по умолчанию для полей выбора или пустое значение для текстовых полей), будет сохранено в сущности со значением NULL. Поэтому, если ваше поле объекта определено как NOT NULL (например, не nullable = true), когда вы сохраняете объект, вы получите неприятную ошибку:

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

Поэтому в документации говорится, что если вы не хотите использовать значение NULL в качестве значения по умолчанию, вы можете указать атрибут empty_data в текстовом поле или в поле выбора. Однако это не работает для меня.

Поле Entity (не может быть недействительным):

 /** * @ORM\Column(type="string") */ protected $shell = ''; 

Form Builder (необязательно):

 ->add('shell', 'choice', array( 'label' => 'Shell', 'choices' => array('shell' => 'Fancy Pants'), 'required' => false, 'empty_data' => '' )) 

Я не понимаю этот атрибут empty_data ? Я пропустил некоторые важные настройки в другом месте? Каков рекомендуемый способ сделать это?

ОБНОВИТЬ

Этот билет Github объясняет, что это был вопрос еще в 2012 году, и он еще не исправлен.

Это означает, что каждый, кто использует построитель форм, вынужден сделать любое поле, которое не требуется в поле с нулевым значением? Это кажется довольно упрямым для рамки … есть много причин, по которым мы не хотим использовать NULL, когда значение по умолчанию '' или 0 не имеет уникального значения, и нам не нужен NULL. Для многих запросов необходимо проверить наличие обоих полей = 0 ИЛИ field = NULL, это боль.

Есть ли лучшее решение, которое используют другие люди?

Я делаю это так, как предлагалось, но задает значение по умолчанию в классе Entity. Поэтому, чтобы установить значение null, Entity фиксирует, что он устанавливает 0 или что-то другое.

 public function __construct() { $this->shell = 0; } 

Или вы можете позаботиться об этом в сеттере:

 public function setShell($shell) { $this->shell = $shell; if ( !is_numeric($shell) ) { $this->shell = 0; } return $this; } 

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

Другим возможным обходным DataTransfromer является создание простого DataTransfromer и DataTransfromer его к требуемому полю. Пример:

 <?php namespace Interprac\Bundle\UtilityBundle\Form\DataTransformer; use Symfony\Component\Form\DataTransformerInterface; class NullToEmptyTransformer implements DataTransformerInterface { /** * Does not transform anything * * @param string|null $value * @return string */ public function transform($value) { return $value; } /** * Transforms a null to an empty string. * * @param string $value * @return string */ public function reverseTransform($value) { if (is_null($value)) { return ''; } return $value; } } 

Прикрепите трансформатор к одному полю:

 $nameSuffix = $builder->create('name_suffix', 'choice', array( 'label' => 'Name Suffix', 'choices' => PR::getSMSFSuffixes(), ))->addModelTransformer(new NullToEmptyTransformer()); $builder->add($nameSuffix); 

Вы можете начиная с версии 2.6 использовать комбинацию заполнительных и пустых данных в вашем классе формы.

  $builderInterface->add('gender', 'choice', array( 'required' => false, 'choices' => array( 'M' => 'Male', 'F' => 'Female', 'I' => 'I dont want to specify' ), 'placeholder' => 'Choose Gender', 'empty_data' => 'I' ));