Символьная форма Поле Атрибут 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
? Я пропустил некоторые важные настройки в другом месте? Каков рекомендуемый способ сделать это?
UPDATE
Этот билет Github объясняет, что это была проблема еще в 2012 году, и она еще не исправлена.
Это означает, что все, кто использует построитель форм, вынуждены делать любое поле, которое не требуется в поле с нулевым значением? Это кажется довольно упрямым для рамки... есть много причин, по которым мы не хотим использовать NULL, когда значение по умолчанию '' или 0 не имеет уникального значения, и нам не нужен NULL. Для многих запросов необходимо проверить наличие обоих полей = 0 ИЛИ field = NULL, это боль.
Есть ли лучшее решение, которое используют другие люди?
Ответы
Ответ 1
Я делаю это так, как предлагалось, но задает значение по умолчанию в классе 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;
}
Может быть, не лучшая практика, но она работает, чтобы не иметь значений с нулевым значением.
Ответ 2
Другим возможным обходным решением является создание простого 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);
Ответ 3
Вы можете начиная с версии 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'
));
Ответ 4
- Не используйте опцию empty_data.
- И используйте атрибут placeholder.
- Пример:
array(
'label' => 'textExample',
'required' => false,
'disabled' => false,
'read_only' => true,
'attr' => array('placeholder' => 'DefaultValue')
)