У меня есть простой Symfony API, который использует 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}. Я предполагаю, что это связано с плохой конфигурацией типа формы. Структура данных меняется сразу после проверки формы и до того, как я впервые сохраняю сущность.
Вот ТиретТип:
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Я что-то совсем упустил?
Спасибо!




Я нашел ответ на свой вопрос. Поскольку у моего поля 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;
}
) );
Я не думаю, что проверка нулевых свойств — самый чистый способ сделать это, но мой случай очень прост, поэтому я не буду тратить на него больше времени.
Надеюсь, это поможет кому-то.