Symfony + FOSRestBundle - 如何允许 NULL 值配置为自定义表单类型的字段?
Symfony + FOSRestBundle - How to allow NULL value to a field configured with a custom form type?
我有一个使用 FOSRestBundle 的简单 Symfony API。我有一个 Exercise
实体,其中包含一个字段 sentences
。该字段的类型为 json @ORM\Column(type="json")
,并填充了一些嵌套的 json。该实体保存在 MySQL 数据库中。
我使用 Symfony 表单验证来自 SPA 的传入数据。这是 SPA 在端点 /exercise
:
上发送的数据
{
"name": "HEP9H",
"sentences": [
{
"name": "Sentence",
"tirettes": [
{
"chain": null
},
{
"chain": {
"name": "Chain 1"
}
}
]
}
]
}
一旦持久化,API 就会 return 成为 JSON 的实体。它应该看起来完全一样,只是它有一个 ID。问题是我在 return:
中得到了这条 JSON
{
"id": 21,
"name": "HEP9H",
"sentences": [
{
"name": "Sentence",
"tirettes": [
{
"chain": {
"name": null
}
},
{
"chain": {
"name": "Chaîne 1"
}
}
]
}
]
}
如您所见,问题是我的 属性 "chain": null
变成了 "chain": {"name": null}
。我想这是由于错误的表单类型配置造成的。数据结构在我验证我的表单之后和我第一次保留实体之前立即发生变化。
这是 TiretteType:
class TiretteType extends AbstractType {
public function buildForm ( FormBuilderInterface $builder, array $options ) {
$builder
->add ( 'chain', ChainType::class, [
"required" => false
] );
}
}
这是 ChainType:
class ChainType extends AbstractType {
public function buildForm ( FormBuilderInterface $builder, array $options ) {
$builder->add ( 'name', TextType::class );
}
}
我没有基础数据 class 也没有基础实体(除了根实体 Exercise
)。
到目前为止我尝试过的:
- 将
"required" => false
添加到 'chain' 字段,它不会改变任何东西
- 将
"empty_data" => NULL
设置为 'chain' 字段,这也不起作用并将任何数据覆盖为 NULL
我是不是漏掉了什么?
谢谢!
我找到了问题的答案。由于我的字段 chain
没有基础数据 class,如果表单有一个 null
值作为输入,它只会给我一个带有默认值的数组。
解决方案是使用数据转换器 (https://symfony.com/doc/current/form/data_transformers.html)。我必须检查这样一个空结构,如果找到,return 返回 null
而不是给定值。
$builder->get ( 'chain' )->addModelTransformer ( new CallbackTransformer(
function ( $originalInput ) {
return $originalInput;
},
function ( $submittedValue ) {
return $submittedValue["name"] === null ? $submittedValue : null;
}
) );
我不认为检查 null 属性是执行此操作的最简洁方法,但我的情况非常简单,因此我不会在这方面花费更多时间。
希望这对某人有所帮助。
我有一个使用 FOSRestBundle 的简单 Symfony API。我有一个 Exercise
实体,其中包含一个字段 sentences
。该字段的类型为 json @ORM\Column(type="json")
,并填充了一些嵌套的 json。该实体保存在 MySQL 数据库中。
我使用 Symfony 表单验证来自 SPA 的传入数据。这是 SPA 在端点 /exercise
:
{
"name": "HEP9H",
"sentences": [
{
"name": "Sentence",
"tirettes": [
{
"chain": null
},
{
"chain": {
"name": "Chain 1"
}
}
]
}
]
}
一旦持久化,API 就会 return 成为 JSON 的实体。它应该看起来完全一样,只是它有一个 ID。问题是我在 return:
中得到了这条 JSON{
"id": 21,
"name": "HEP9H",
"sentences": [
{
"name": "Sentence",
"tirettes": [
{
"chain": {
"name": null
}
},
{
"chain": {
"name": "Chaîne 1"
}
}
]
}
]
}
如您所见,问题是我的 属性 "chain": null
变成了 "chain": {"name": null}
。我想这是由于错误的表单类型配置造成的。数据结构在我验证我的表单之后和我第一次保留实体之前立即发生变化。
这是 TiretteType:
class TiretteType extends AbstractType {
public function buildForm ( FormBuilderInterface $builder, array $options ) {
$builder
->add ( 'chain', ChainType::class, [
"required" => false
] );
}
}
这是 ChainType:
class ChainType extends AbstractType {
public function buildForm ( FormBuilderInterface $builder, array $options ) {
$builder->add ( 'name', TextType::class );
}
}
我没有基础数据 class 也没有基础实体(除了根实体 Exercise
)。
到目前为止我尝试过的:
- 将
"required" => false
添加到 'chain' 字段,它不会改变任何东西 - 将
"empty_data" => NULL
设置为 'chain' 字段,这也不起作用并将任何数据覆盖为 NULL
我是不是漏掉了什么?
谢谢!
我找到了问题的答案。由于我的字段 chain
没有基础数据 class,如果表单有一个 null
值作为输入,它只会给我一个带有默认值的数组。
解决方案是使用数据转换器 (https://symfony.com/doc/current/form/data_transformers.html)。我必须检查这样一个空结构,如果找到,return 返回 null
而不是给定值。
$builder->get ( 'chain' )->addModelTransformer ( new CallbackTransformer(
function ( $originalInput ) {
return $originalInput;
},
function ( $submittedValue ) {
return $submittedValue["name"] === null ? $submittedValue : null;
}
) );
我不认为检查 null 属性是执行此操作的最简洁方法,但我的情况非常简单,因此我不会在这方面花费更多时间。
希望这对某人有所帮助。