我尝试通过主实体更新相关实体。例如,我有产品和优惠。我执行POST
到/products
{
"name": "sample product",
"offers": [
{
"description": "sample offer"
}
]
}
我得到的回应是
{
"@context": "/contexts/Product",
"@id": "/products/1",
"@type": "Product",
"name": "sample product",
"offers": [
{
"@id": "/offers/1",
"@type": "https://schema.org/Offer",
"description": "sample offer"
}
]
}
到目前为止一切顺利。现在,我想在/products/1
上执行PUT
操作
{
"name": "product updated",
"offers": [
{
"@id": "/offers/1",
"description": "offer updated"
}
]
}
并得到这个错误
执行查询时出现异常:数据库状态[23000]:完整性约束冲突:1048列'产品ID'不能为空
如果我从Offer.php中删除#[ORM\JoinColumn(nullable:false)]
,它可以工作,但是product_id
被设置为null
(行的其余部分保留),并且插入了一个新行。
我想要的是得到行更新(只是更新描述字段)。这是可能的吗?
我使用www.example.com上给出的例子,做了一些小的修改(见评论)https://api-platform.com/docs/core/getting-started/#mapping-the-entities with some minor modifications (see comments)
我的代码是:
- 产品. php**
<?php
// api/src/Entity/Product.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Serializer\Annotation\Groups; //ADDED THIS
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
#[ApiResource(
normalizationContext: ["groups" => ["products"]],
denormalizationContext: ["groups" => ["products"]],
)]
class Product // The class name will be used to name exposed resources
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
/**
* A name property - this description will be available in the API documentation too.
*
*/
#[ORM\Column]
#[Assert\NotBlank]
#[Groups(["products"])] //ADDED THIS
public string $name = '';
// Notice the "cascade" option below, this is mandatory if you want Doctrine to automatically persist the related entity
/**
* @var Offer[]|ArrayCollection
*
*/
#[ORM\OneToMany(targetEntity: Offer::class, mappedBy: 'product', cascade: ['persist'])]
#[Groups(["products"])] //ADDED THIS
public iterable $offers;
public function __construct()
{
$this->offers = new ArrayCollection(); // Initialize $offers as a Doctrine collection
}
public function getId(): ?int
{
return $this->id;
}
// Adding both an adder and a remover as well as updating the reverse relation is mandatory
// if you want Doctrine to automatically update and persist (thanks to the "cascade" option) the related entity
public function addOffer(Offer $offer): void
{
$offer->product = $this;
$this->offers->add($offer);
}
public function removeOffer(Offer $offer): void
{
$offer->product = null;
$this->offers->removeElement($offer);
}
// ...
//ADDED THIS SET AND GET
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
}
- 提供. php**
<?php
// api/src/Entity/Offer.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups; //ADDED THIS
use Symfony\Component\Validator\Constraints as Assert;
/**
* An offer from my shop - this description will be automatically extracted from the PHPDoc to document the API.
*
*/
#[ORM\Entity]
#[ApiResource(types: ['https://schema.org/Offer'])]
class Offer
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
#[ORM\Column(type: 'text')]
#[Groups(["products"])] //ADDED THIS
public string $description = '';
#[ORM\Column]
#[Assert\Range(minMessage: 'The price must be superior to 0.', min: 0)]
public float $price = 1.0; //MODIFIED THIS
#[ORM\ManyToOne(targetEntity: Product::class, inversedBy: 'offers')]
#[ORM\JoinColumn(nullable:false)] //ADDED THIS
public ?Product $product = null;
public function getId(): ?int
{
return $this->id;
}
//ADDED THIS SET AND GET
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function getDescription()
{
return $this->description;
}
}
1条答案
按热度按时间dgtucam11#
尝试使用
PATCH
方法而不是PUT
,并将Content-Type头设置为application/merge-patch+json
PUT
方法需要填充每个已知属性,否则它将认为该属性已被删除,因此将其设置为null
。这就是为什么您的id
设置为null
。PATCH
方法只编辑json
中属性。不要忘记执行以下操作:https://api-platform.com/docs/core/content-negotiation/#configuring-patch-formats
您可以阅读:为了得到适当的解释,这是我们都犯的错误,哈哈