FOSRestBundle обновляет только одно поле за раз, используя PUT

Некоторое время назад я задал тот же вопрос не содержит всех сопоставленных свойств объекта, и у меня есть решение #hack для решения проблемы, но когда форма более сложная, содержит варианты выбора (массивы) или сопоставленные объекты (объекты), решение больше не применимо. Поэтому я придумал очень грязные идеи, чтобы заставить его работать, например

        if(is_object($event->getForm()->getData())) $event->setData($event->getForm()->getData()->getId());
        if(is_array($event->getData()) && empty($event->getData()))
        {
            $event->setData([$event->getForm()->getData()]);
        }
        if($event->getForm()->getData() instanceof \DateTime) $event->setData($event->getForm()->getData()->format('Y-m-d H:i:s'));
        if(!is_array($event->getData()) && (is_string($event->getForm()->getData()) || is_integer($event->getForm()->getData())))
        {
            $event->setData($event->getForm()->getData());
        }

но он даже не работает идеально. Поэтому я должен еще раз спросить, есть ли лучшее решение для обновления только одного значения во время отправки ответа json, потому что, если я отправлю {"user":{"firstName":"John"}}, все остальные поля, принадлежащие форме пользователя, будут пустыми, и я не могу отправить весь ресурс. Я не могу найти никакого решения этой проблемы.

А вот Контроллер

/**
 * This endpoint updates an existing Client entity.
 *
 * @ApiDoc(
 *  resource=true,
 *  description="Updates an existing Client entity",
 * )
 * @ParamConverter("user", class="Software:User", options={"mapping": {"user": "guid"}})
 */
public function putAction(Request $request, $user)
{
    $form = $this->createForm(new UserType(['userType' => 'client', 'manager' => $this->getDoctrine()->getManager()]), $user, ['method' => 'PUT']);
    $form->handleRequest($request);

    if($form->isValid())
    {
        $manager = $this->getDoctrine()->getManager();
        $manager->flush();

        return $this->view([
            'user' => $user
        ]);
    }

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

person undefinedman    schedule 01.10.2015    source источник


Ответы (1)


Я собираюсь ответить на свой вопрос.

Ответ заключается в использовании метода PATCH вместо PUT. Вот измененный код:

/**
 * This endpoint updates an existing Client entity.
 *
 * @ApiDoc(
 *  resource=true,
 *  description="Updates an existing Client entity",
 * )
 * @ParamConverter("user", class="Software:User", options={"mapping": {"user": "guid"}})
 */
public function patchAction(Request $request, $user)
{
    $form = $this->createForm(new UserType(['userType' => 'client', 'manager' => $this->getDoctrine()->getManager()]), $user, ['method' => 'PATCH']);
    $form->handleRequest($request);

    if($form->isValid())
    {
        $manager = $this->getDoctrine()->getManager();
        $manager->flush();

        return $this->view([
            'user' => $user
        ]);
    }

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

См. ссылки: Symfony2 REST API — частичное обновление

http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/

http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/

Внимательно прочитайте главы PATCH и PUT.

person undefinedman    schedule 02.10.2015