Symfony表单字段属性empty_data忽略

Cha*_*yer 11 php forms doctrine symfony doctrine-orm

根据Symfony 2.4文档,任何不需要但没有任何值(选择字段的默认值或文本字段的空值)提交的表单字段将保存到具有NULL值的实体.因此,如果您的实体字段被定义为NOT NULL(例如,不是nullable = true),当您持久保存实体时,您将收到一个令人讨厌的错误:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'shell' cannot be null
Run Code Online (Sandbox Code Playgroud)

所以文档说如果你不希望它使用NULL作为默认值,你可以empty_data在文本或选择字段上指定属性.但是,这对我不起作用.

实体字段(不可为空):

/**
 * @ORM\Column(type="string")
 */
protected $shell = '';
Run Code Online (Sandbox Code Playgroud)

表单生成器(不是必需的):

->add('shell', 'choice', array(
    'label' => 'Shell',
    'choices' => array('shell' => 'Fancy Pants'),
    'required' => false,
    'empty_data' => ''
))
Run Code Online (Sandbox Code Playgroud)

我误解了这个empty_data属性吗?我在别处错过了一些重要的设置吗?这样做的推荐方法是什么?

UPDATE

这张Github门票解释说这是2012年的问题,尚未修复.

这意味着每个使用表单构建器的人都被迫在可空字段中创建任何不需要的字段?对于框架来说,这似乎很自然......当默认的''或0不具有唯一含义而我们不需要NULL时,有很多原因我们不想使用NULL.对于许多查询,必须检查是否存在field = 0 OR field = NULL,这很痛苦.

是否有其他人使用的更好的解决方案?

小智 5

我按照建议的方式进行,但在Entity类中设置默认值.因此设置为null的实体正在修复它设置0或其他的东西.

public function __construct() { 
      $this->shell = 0;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以在setter中处理它:

public function setShell($shell) {
      $this->shell = $shell;

      if ( !is_numeric($shell) ) {
             $this->shell = 0;
      }
      return $this;
}
Run Code Online (Sandbox Code Playgroud)

也许不是最好的做法,但它的作用是没有可空的价值.


b.b*_*4rd 5

另一种可能的解决方法是创建一个简单的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

将变压器连接到单个字段:

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

$builder->add($nameSuffix);
Run Code Online (Sandbox Code Playgroud)