我有一个包含各种字段的Symfony2表单,包括一个名为recap
的可选文本字段。
当recap
字段中包含一些文本时,它会完美保存,但当字段留空时,我会收到此错误:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'recap' cannot be null
没错 - 专栏recap
不能是null
。我是故意这样设定的。 Null
意味着未知。当用户将recap
留空时,recap
的值不为人知;它是空白的。
我的问题是如何让Symfony将recap
保存为''
,而不是null
。
答案 0 :(得分:15)
转到您的实体并转到变量声明。
/**
* @var string $name
*
* @ORM\Column(type="string", length=50)
*/
public $recap = '';
您可以为$ recap分配默认值。
或者,当你有函数setRecap时,你可以检查是否为空,并设置你想要的值。
public function setRecap($recap) {
$this->recap = !isset($recap) ? '': $recap;
}
或者您将表单中的默认值类型设置为'',但我认为它不是您所期望的。
答案 1 :(得分:11)
是的,在它上面浪费了很多时间;-(“转换”在组件Form.php第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上失去了这么多时间,总是在源头寻找这种小黑客; - (
答案 2 :(得分:7)
我有另一个解决此问题的方法:
创建虚拟课程
class EmptyString {
public function __toString() {
return '';
}
}
并设置
$builder->add('recap', 'text', [
'empty_data' => new EmptyString(),
]);
当实体将存储到DB时,它将自动转换为空字符串。
答案 3 :(得分:5)
我认为你错误地解决了这个问题:当用户留下空白时, 值是未知的,因为没有提供。例如,你没有说空的生日字段意味着生日数字等于'',但生日数是未知的。地址等也一样......
因此,如果您的用户不需要填写此字段,那么似乎最相关的响应实际上是将您的字段设置为可为空的
答案 4 :(得分:2)
在Symfony2中遇到类似的错误:
我的实体:
/**
* @ORM\Column(type="boolean")
*/
protected $Valid;
我的表格:
$builder->add('Valid', 'hidden');
现在对于真值,使用value =“1”正确渲染字段,但对于false值,字段使用value =“”呈现,这导致:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Valid' cannot be null
虽然我希望它会被渲染为value =“0”。
当然可以增强setValid()方法来设置正确的值:
public function setValid($valid)
{
$this->Valid = ($valid ? true : false);
}
哪个解决了这个问题,而不是修复它。
答案 5 :(得分:2)
在表格中,你可以这样做:
$builder
->add('optionalField', TextType::class, ['required'=>false, 'empty_data'=>''])
答案 6 :(得分:-1)
我也遇到过这个问题。我建议优雅的解决方案是:制定这个定义@ORM\Column(type="string", length=50, nullable=true)