我有两个内脏。
Quote
和 QuoteProduct
附带 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。
经过几个小时和几个小时,我设法找到了答案,我张贴我的请求与参数。
Content-Type : application/json;charset=UTF-8
当我使用 Content-Type : application/ld+json
果然
根据API平台文档。https:/api-platform.comdocscorecontent-negotiation。 这是有道理的。不鼓励使用原始的JSON或原始的XML格式,更倾向于使用JSON-LD,它提供了更多的功能,并且易于使用。