Symfony + FOSRestBundle - Как разрешить значение NULL для поля, настроенного с пользовательским типом формы? - PullRequest
0 голосов
/ 23 мая 2019

У меня есть простой API Symfony, который использует FOSRestBundle. У меня есть 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. Он должен выглядеть точно так же, за исключением того, что у него есть идентификатор. Проблема в том, что я получаю этот кусок 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 );
    }
}

У меня нет базового класса данных и базового объекта (кроме корневого объекта Exercise).

Что я пробовал до сих пор:

  • добавление "required" => false в поле 'цепочка', это ничего не меняет
  • установка "empty_data" => NULL в поле 'цепочка', это также не работает и переопределяет любые данные в NULL

Я что-то упустил?

Спасибо!

1 Ответ

0 голосов
/ 24 мая 2019

Я нашел ответ на свой вопрос. Поскольку в моем поле 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;
    }
) );

Я не думаю, что проверка на нулевые свойства - самый чистый способ сделать это, но мой случай очень прост, поэтому я не буду тратить на это больше времени.

Надеюсь, это кому-нибудь поможет.

...