According to the Symfony 2.4 Documentation, any form field that is not required, but submitted without any value (default value for choice fields or empty value for text fields), will be saved to the entity with a NULL value. So if your entity field is defined as NOT NULL (e.g. not nullable=true), when you persist the entity you will get a nasty error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'shell' cannot be null
So the documentation says that if you don't want it to use NULL as the default value, you can kindly specify the empty_data
attribute on a text or choice field. However, this is not working for me.
Entity Field (not nullable):
/**
* @ORM\Column(type="string")
*/
protected $shell = '';
Form Builder (not required):
->add('shell', 'choice', array(
'label' => 'Shell',
'choices' => array('shell' => 'Fancy Pants'),
'required' => false,
'empty_data' => ''
))
Am I misunderstanding this empty_data
attribute? Am I missing some important setting elsewhere? What is the recommended way of doing this?
This Github ticket explains that this was an issue back in 2012, and it hasn't been fixed yet.
That means that everyone who is using the form builder, is forced to make any field that is not required into a nullable field? That seems pretty opinionated for the framework... there are lots of reasons we don't want to use NULL when a default '' or 0 doesn't have unique meaning and we don't need a NULL. For many queries, having to check for the presence of both field=0 OR field=NULL, is a pain.
Is there some better solution other people are using?
array(
'label' => 'textExample',
'required' => false,
'disabled' => false,
'read_only' => true,
'attr' => array('placeholder' => 'DefaultValue')
)
I do it the way suggested, but sets a default value in the Entity class. So insted of setting null the Entity is fixing that it sets 0 or something others.
public function __construct() {
$this->shell = 0;
}
Or, you can take care of it in the setter:
public function setShell($shell) {
$this->shell = $shell;
if ( !is_numeric($shell) ) {
$this->shell = 0;
}
return $this;
}
Maybe not the best practice, but It works to not have nullable values.
Another possible workaround is to create a simple DataTransfromer
and attach it to the required field.
Example:
<?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;
}
}
Attach the transformer to a single field:
$nameSuffix = $builder->create('name_suffix', 'choice', array(
'label' => 'Name Suffix',
'choices' => PR::getSMSFSuffixes(),
))->addModelTransformer(new NullToEmptyTransformer());
$builder->add($nameSuffix);
You can since 2.6, use a combination of placeholder and empty data in your form class.
$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'
));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With