API-Platform - 如何更新和嵌入关系并持久化它的id。

问题描述 投票:0回答:1

我有两个内脏。

QuoteQuoteProduct 附带 OneToMany 之间的关系。

当我执行一个PUT请求来更新嵌入的QuoteProduct关系时,它总是删除所有的项目并添加它们,结果生成新的ID。

根据官方文档,我在更新嵌入式报价产品关系时,总是删除所有项目并添加它们,结果生成新的ID。https:/api-platform.comdocscoreserialization#denormalization。我应该可以通过他的id来更新一个特定的项目。

报价实体

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Ramsey\Uuid\Uuid;
use ApiPlatform\Core\Annotation\ApiResource;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;


/**
 * @ApiResource(
 *     normalizationContext={"groups"={"quote.read"}},
 *     denormalizationContext={"groups"={"quote.write"}},
 *     collectionOperations={
 *         "get"={"access_control"="is_granted('ROLE_USER')", "access_control_message"="You do not have the permission to get"},
 *         "post"={"access_control"="is_granted('ROLE_COMMERCIAL')", "access_control_message"="You do not have the permission to add"}
 *     },
 *     itemOperations={
 *         "get",
 *         "put"={"access_control"="is_granted('ROLE_COMMERCIAL')", "access_control_message"="You do not have the permission to update"},
 *         "delete"={"access_control"="is_granted('ROLE_COMMERCIAL')", "access_control_message"="You do not have the permission to delete."}
 *     },
 *     attributes={"force_eager"=false}
 * )
 * @ORM\Entity
 * @ORM\Table(name="`quotes`")
 */
class Quote
{


    public function __construct()
    {
        $this->id = Uuid::uuid4();
        $this->products = new ArrayCollection();
    }


    /**
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;



    /**
     * @var Collection|QuoteProduct[]
     *
     * @Groups({"quote.read", "quote.write"})
     * @ORM\OneToMany(targetEntity="App\Entity\QuoteProduct", mappedBy="quote", cascade={"persist"}, orphanRemoval=true)
     * @ORM\OrderBy({"code" = "ASC"})
     */
    private $products;




    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ----------------------------------------GETTER AND SETTER------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */


    public function getId()
    {
        return $this->id;
    }


    /**
     * @return Collection|QuoteProduct[]
     */
    public function getProducts(): Collection
    {
        return $this->products;
    }

    /**
     * @param QuoteProduct $product
     * @return Quote
     */
    public function addProduct(QuoteProduct $product): self
    {
        if(false === $this->products->contains($product))
        {
            $product->setQuote($this);
            $this->products->add($product);
        }
        return $this;
    }

    /**
     * @param QuoteProduct $product
     * @return Quote
     */
    public function removeProduct(QuoteProduct $product)
    {
        if(!$this->products->contains($product))
        {
            return;
        }
        $this->products->removeElement($product);
        $product->setQuote(null);
    }



}

?>

报价产品实体

<?php


namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Ramsey\Uuid\Uuid;
use ApiPlatform\Core\Annotation\ApiResource;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;


/**
 * @ApiResource(
 *     normalizationContext={"groups"={"quote-product.read"},"enable_max_depth"=true},
 *     denormalizationContext={"groups"={"quote-product.write"},"enable_max_depth"=true},
 *     attributes={"force_eager"=false}
 * )
 * @ORM\Entity
 * @ORM\Table(name="`quote_products`")
 */
class QuoteProduct
{

    /**
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Groups({"quote-product.read", "quote-product.write", "quote.read", "quote.write"})
     *
     */
    private $code;


    /**
     * @ORM\ManyToOne(targetEntity="Quote", cascade={"persist"}, inversedBy="products")
     * @Assert\Valid
     * @Groups({"quote-product.read", "quote-product.write", "quote.read", "quote.write"})
     */
    private $quote;




    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ----------------------------------------GETTER AND SETTER------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */


    public function __construct()
    {
        $this->id = Uuid::uuid4();
    }

    public function getId()
    {
        return $this->id;
    }






    public function getQuote(): ?Quote
    {
        return $this->quote;
    }

    public function setQuote(?Quote $quote)
    {
        $this->quote = $quote;

        return $this;
    }




    public function getCode(): ?string
    {
        return $this->code;
    }

    public function setCode(?string $code): self
    {
        $this->code = $code;

        return $this;
    }


}

获取报价请求fbe01952-2a23-4882-bb9f-970e8598f979。

结果。

{
  "@context": "\/contexts\/Quote",
  "@id": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979",
  "@type": "Quote",
  "products": [
    {
      "@id": "\/quote_products\/15216edd-dd5c-49d5-bf3f-39d389d804d6",
      "@type": "QuoteProduct",
      "code": "Code 1",
      "quote": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979"
    }
  ]
}

将请求发送到quotesfbe01952-2a23-4882-bb9f-970e8598f979,并附上JSON参数(请注意,我改变了报价产品代码属性的值)。

{
  "@context": "\/contexts\/Quote",
  "@id": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979",
  "@type": "Quote",
  "products": [
    {
      "@id": "\/quote_products\/15216edd-dd5c-49d5-bf3f-39d389d804d6",
      "@type": "QuoteProduct",
      "code": "A new code",
      "quote": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979"
    }
  ]
}

结果到了.com。

{
  "@context": "\/contexts\/Quote",
  "@id": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979",
  "@type": "Quote",
  "products": [
    {
      "@id": "\/quote_products\/865da321-dd74-4a39-82a3-e0e935555262",
      "@type": "QuoteProduct",
      "code": "A new code",
      "quote": "\/quotes\/fbe01952-2a23-4882-bb9f-970e8598f979"
    }
  ]
}

代码已经改变了预期,但它生成了一个新的@id。

php symfony api-platform.com
1个回答
-1
投票

经过几个小时和几个小时,我设法找到了答案,我张贴我的请求与参数。

Content-Type : application/json;charset=UTF-8

当我使用 Content-Type : application/ld+json 果然

根据API平台文档。https:/api-platform.comdocscorecontent-negotiation。 这是有道理的。不鼓励使用原始的JSON或原始的XML格式,更倾向于使用JSON-LD,它提供了更多的功能,并且易于使用。

© www.soinside.com 2019 - 2024. All rights reserved.