在api平台中验证嵌入式模型

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

我有这个Order模型:

<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * @ApiResource(
 *     itemOperations={
 *          "get"={
 *              "normalization_context"={
 *                  "groups"={"order:view"}
 *              }
 *          },
 *          "patch"={
 *              "normalization_context"={
 *                  "groups"={"order:view"}
 *              },
 *              "denormalization_context"={
 *                  "groups"={"upsert"}
 *              }
 *          },
 *          "delete"
 *     },
 *     collectionOperations={
 *          "get"={
 *              "normalization_context"={
 *                  "groups"={"order:index"}
 *              }
 *          },
 *          "post"={
 *              "normalization_context"={
 *                  "groups"={"order:view"}
 *              },
 *              "denormalization_context"={
 *                  "groups"={"order:create"}
 *              }
 *          }
 *     }
 * )
 * @ORM\Entity(repositoryClass="App\Repository\OrderRepository")
 * @ORM\Table(name="`order`")
 */
class Order
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"order:index", "order:view"})
     */
    private $id;
    /**
     * @ORM\Column(type="integer")
     * @Assert\PositiveOrZero()
     * @Groups({"order:index", "order:view"})
     */
    private $amount;
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\OrderItem", mappedBy="orderId")
     * @Groups({"order:index", "order:view", "order:create"})
     */
    private $orderItems;
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Merchant", inversedBy="orders")
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"order:index", "order:view"})
     */
    private $merchant;
    /**
     * Order constructor.
     */
    public function __construct()
    {
        $this->orderItems = new ArrayCollection();
    }
    /**
     * @return string
     */
    public function __toString(): string {
        return $this->id;
    }
    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }
    /**
     * @return int|null
     */
    public function getAmount(): ?int
    {
        return $this->amount;
    }
    /**
     * @param int $amount
     * @return Order
     */
    public function setAmount(int $amount): self
    {
        $this->amount = $amount;
        return $this;
    }
    /**
     * @Assert\Valid
     */
    public function getOrderItems()
    {
        return $this->orderItems->getValues();
    }
    /**
     * @param OrderItem $orderItem
     * @return Order
     */
    public function addOrderItem(OrderItem $orderItem): self
    {
        if (!$this->orderItems->contains($orderItem)) {
            $this->orderItems[] = $orderItem;
            $orderItem->setOrderId($this);
        }
        return $this;
    }
    /**
     * @param OrderItem $orderItem
     * @return Order
     */
    public function removeOrderItem(OrderItem $orderItem): self
    {
        if ($this->orderItems->contains($orderItem)) {
            $this->orderItems->removeElement($orderItem);
            // set the owning side to null (unless already changed)
            if ($orderItem->getOrderId() === $this) {
                $orderItem->setOrderId(null);
            }
        }
        return $this;
    }
    /**
     * @return Merchant|null
     */
    public function getMerchant(): ?Merchant
    {
        return $this->merchant;
    }
    /**
     * @param Merchant|null $merchant
     * @return Order
     */
    public function setMerchant(?Merchant $merchant): self
    {
        $this->merchant = $merchant;
        return $this;
    }
}

和此OrderItem模型

<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass="App\Repository\OrderItemRepository")
 */
class OrderItem
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"view", "order:view", "order:index"})
     */
    private $id;
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Product")
     * @ORM\JoinColumn(nullable=false)
     * @SerializedName("product")
     * @Assert\NotBlank()
     * @Groups({"view", "order:view", "order:index", "order:create"})
     */
    private $productId;
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Order", inversedBy="orderItems")
     * @SerializedName("order")
     * @ORM\JoinColumn(nullable=false)
     */
    private $orderId;
    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     * @Assert\PositiveOrZero()
     * @Groups({"view", "order:view", "order:index", "order:create"})
     */
    private $num;
    /**
     * @ORM\Column(type="integer")
     * @SerializedName("total_amount")
     * @Assert\PositiveOrZero()
     * @Groups({"view", "order:view", "order:index"})
     */
    private $totalAmount;
    /**
     * @return string
     */
    public function __toString(): string {
        return $this->id;
    }
    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }
    /**
     * @return Product|null
     */
    public function getProductId(): ?Product
    {
        return $this->productId;
    }
    /**
     * @param Product|null $productId
     * @return OrderItem
     */
    public function setProductId(?Product $productId): self
    {
        $this->productId = $productId;
        return $this;
    }
    /**
     * @return Order|null
     */
    public function getOrderId(): ?Order
    {
        return $this->orderId;
    }
    /**
     * @param Order|null $orderId
     * @return OrderItem
     */
    public function setOrderId(?Order $orderId): self
    {
        $this->orderId = $orderId;
        return $this;
    }
    /**
     * @return int|null
     */
    public function getNum(): ?int
    {
        return $this->num;
    }
    /**
     * @param int $num
     * @return OrderItem
     */
    public function setNum(int $num): self
    {
        $this->num = $num;
        return $this;
    }
    /**
     * @return int|null
     */
    public function getItemAmount(): ?int
    {
        return $this->itemAmount;
    }
    /**
     * @param int $itemAmount
     * @return OrderItem
     */
    public function setItemAmount(int $itemAmount): self
    {
        $this->itemAmount = $itemAmount;
        return $this;
    }
    /**
     * @return int|null
     */
    public function getTotalAmount(): ?int
    {
        return $this->totalAmount;
    }
    /**
     * @param int $totalAmount
     * @return OrderItem
     */
    public function setTotalAmount(int $totalAmount): self
    {
        $this->totalAmount = $totalAmount;
        return $this;
    }
}

我正在尝试使用嵌入式嵌套项目而不是项目IRI在单个发布请求中使用其项目创建订单。正如文档建议的那样,我在@Assert\Valid模型内为orderItems getter方法添加Order。但它不会验证post请求中的orderItem数据。

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

我可以解决。Valid约束仅是验证嵌入式模型本身,因此,如果您不提供嵌入式模型的密钥,或者只是设置一个空数组验证,则不会执行任何操作。因此,您需要为属性本身添加另一个验证。在这种情况下,因为我希望我的orderItems至少包含一项,所以我为此属性添加了Count验证约束,如下所示。

/**
 * @Assert\Count(
 *      min = "1",
 *      minMessage = "You must specify at least one OrderItem"
 * )
 * @Assert\Valid()
 */
public function getOrderItems()
{
    return $this->orderItems;
}

因此它强制请求将其包含在列表中的一个OrderItem中

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