Symfony + FOSRestBundle - 如何允许 NULL 值到配置有自定义表单类型的字段?

Posted

技术标签:

【中文标题】Symfony + FOSRestBundle - 如何允许 NULL 值到配置有自定义表单类型的字段?【英文标题】:Symfony + FOSRestBundle - How to allow NULL value to a field configured with a custom form type? 【发布时间】:2019-10-10 02:50:07 【问题描述】:

我有一个使用 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 就会以 JSON 形式返回实体。它应该看起来完全一样,除了它有一个 ID。问题是我得到了这段 JSON 作为回报:


  "id": 21,
  "name": "HEP9H",
  "sentences": [
    
      "name":  "Sentence",
      "tirettes": [
        
          "chain": 
            "name": null
          
        ,
        
          "chain": 
            "name": "Chaîne 1"
          
        
      ]
    
  ]

如您所见,问题在于我的属性"chain": null 变为"chain": "name": null。我猜这是由于表单类型配置错误造成的。在我验证表单之后和第一次持久化实体之前,数据结构会立即发生变化。

这是TietteType:

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 );
    

我没有基础数据类和基础实体(根实体Exercise 除外)。

到目前为止我已经尝试过:

"required" => false 添加到“链”字段,不会改变任何内容 将"empty_data" => NULL 设置为“链”字段,这也不起作用并将任何数据覆盖为NULL

我是不是完全错过了什么?

谢谢!

【问题讨论】:

【参考方案1】:

我找到了问题的答案。由于我的字段 chain 没有基础数据类,如果表单有一个 null 值作为输入,它只会给我一个带有默认值的数组。

解决方案是使用数据转换器 (https://symfony.com/doc/current/form/data_transformers.html)。我必须检查这样一个空结构,如果找到,返回 null 而不是给定的值。

$builder->get ( 'chain' )->addModelTransformer ( new CallbackTransformer(
    function ( $originalInput ) 
        return $originalInput;
    ,
    function ( $submittedValue ) 
        return $submittedValue["name"] === null ? $submittedValue : null;
    
) );

我不认为检查空属性是最干净的方法,但我的情况很简单,所以我不会花更多时间在这个上。

希望这对某人有所帮助。

【讨论】:

以上是关于Symfony + FOSRestBundle - 如何允许 NULL 值到配置有自定义表单类型的字段?的主要内容,如果未能解决你的问题,请参考以下文章

在 Symfony 4 和 FOSRestBundle 下限制登录尝试

如何轻松登录、Symfony2 Security、FOSUserBundle、FOSRestBundle?

Symfony + FOSRestBundle - 如何允许 NULL 值到配置有自定义表单类型的字段?

使用 Symfony 5 中的 FOSRestBundle 转换单个属性以进行响应

带有 RESTful 身份验证的 Symfony2 应用程序,使用 FOSRestBundle 和 FOSUserBundle

无法使用 FOSRestBundle