Symfony表单字段属性empty_data忽略

时间:2014-07-16 23:03:03

标签: php forms symfony doctrine-orm doctrine

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

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

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

实体字段(不可为空):

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

表单构建器(不是必需的):

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

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

更新

Github ticket解释说这是2012年的一个问题,尚未修复。

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

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

3 个答案:

答案 0 :(得分:5)

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

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

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

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

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

也许不是最好的做法,但它的作用是没有可以为空的值。

答案 1 :(得分:4)

另一种可行的解决方法是创建一个简单的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 :(得分:1)

  1. 请勿使用empty_data选项。
  2. 并使用占位符属性。
  3. 例如:
    array(
       'label' => 'textExample',
        'required' => false,
        'disabled' => false,
        'read_only' => true,
        'attr' => array('placeholder' => 'DefaultValue')
        )