Согласно документации 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' ));