请求中不存在的字段在实体中设置为null

时间:2019-06-25 15:25:01

标签: symfony

我制作rest api控制器。我有一个SliderApiType表单,在其中传递要编辑的字段。如果我仅传递一个字段,例如'label',则仅此字段将被更改,并且此表单中的所有其他字段将为空。

Му形式:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('label', TextType::class, ['label' => 'Заголовок', 'required' => false])
            ->add('description', TextType::class, ['label' => 'Описание', 'required' => false])
            ->add('serialNumber', IntegerType::class, ['label' => 'Номер', 'required' => false])
            ->add('picture', IntegerType::class, [
                'invalid_message' => 'picture is not a valid',
            ])
            ->add('send', SubmitType::class, ['label' => 'Отправить'])
        ;

        $builder->get('picture')
            ->addModelTransformer($this->transformer);
    }

我在其中执行编辑操作的控制器:

    public function edit(Slider $slideId, Request $request, EntityManagerInterface $em)
    {
        $form = $this->createForm(SliderApiType::class, $slideId);
        $data = json_decode($request->getContent(), true);
        $form->submit($data);
        if (!($form->isSubmitted() && $form->isValid())) {
            return $this->handleView($this->view($form->getErrors(true)));
        }

        $em = $this->getDoctrine()->getManager();
        $em->persist($slideId);
        $em->flush();

        $context = new Context();
        $context->addGroup('slider_create');
        $view = $this->view($slideId);
        $view->setContext($context);

        return $this->handleView($view);
    }

如果在json中传递此字段:

{
  "label": "string",
  "description": "string",
  "picture": 1
}

一切正常!

但是如果我传递这个json:

{
  "label": "string"
}

字段“ label”设置“字符串”的方式,而字段“ description”和“ picture”设置为null。

如何进行设置,以便在我通过该字段时仅对其进行了编辑,而其他两个字段都不为空?

2 个答案:

答案 0 :(得分:1)

我还没有编写任何其他api,但是经过很少的搜索,看来您可以使用Submit函数的第二个参数:

$form->submit($data, false);

这假设您的函数仅用于更新现有实体数据(PATCH / PUT方法)-如果要在同一操作中支持多个方法,则需要检查请求方法类型:

$clearMissing = $request->getMethod() != 'PATCH';
$form->submit($data, $clearMissing);

答案 1 :(得分:0)

我建议您将此逻辑直接放在您的实体中。这样,您有信心,只要更新相同的信息,它将应用相同的逻辑,而不仅仅是在控制器中。每个字段都类似这样:

public function setField(string $newValue)
{
    if (!empty($newValue)) {
        $this->field = $newValue;
    }

    return $this;
}