N
N
Nikita Gushchin2015-09-04 14:47:27
symfony
Nikita Gushchin, 2015-09-04 14:47:27

How to change entities without forms?

I'm trying to implement changing entities. The controller looks like this:

/**
     * @param Product $slug
     * @param Product $updatedProduct
     * @return Product
     *
     * @Rest\Route(requirements={"slug" = "\d+"})
     * @ParamConverter(
     *      name="updatedProduct",
     *      converter="fos_rest.request_body",
     *      class="FiveToFive\ergil\DomainBundle\Entity\Product"
     * )
     * @Rest\View(serializerGroups={ "Default", "product_details", "product_categories_list", "image_details" })
     */
    public function putAction(Product $slug, Product $updatedProduct)
    {
        $productService = $this->get("product.service");
        return $productService->update($updatedProduct);
    }

If an id is passed in the request body, then slug and updatedProduct are the same entity, the title is updated, the rest of the fields are old ... profit:
// PUT http://my-api-uyl/api/products/1
{
    "id": 1,
    "title": "Updated some sort of macgick"
}

But it looks very ugly! If you remove "id" in the request body, then it turns out that slug is an entity from the database, and updatedProduct is a new entity, in which all fields except title are null and how to combine it with slug is extremely unclear.
Is there any way to merge two entities into one?
Or is it possible to somehow force the param converter to take the id from the request url?
The following option doesn't work:
@ParamConverter(
      name="updatedProduct",
      converter="fos_rest.request_body",
      class="FiveToFive\ergil\DomainBundle\Entity\Product",
      options= { "id" = "slug" }
)

I use FOSRestBundle, JMSSerializerBundle

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey, 2015-09-04
@iNikNik

The correct way is to not use entities in controllers at all, and never feed them to JMS Serializers or forms.
A more or less correct way is to define your own Object Constructor for the JMS Serializer to make it possible to specify which object to shove data into.

D
Denis, 2015-09-04
@prototype_denis

If you remove "id" in the request body
...then the PUT method should create the resource. Therefore, we return the result of the postAction method
public function putAction(Product $slug, Product $updatedProduct)
{
    if (!$updatedProduct->getId()) {
        return $this->postAction(/* $slug | $updatedProduct */);
    }
    
    return $this->get('product.service')->update($updatedProduct);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question