与api平台的嵌入关系

Chr*_*eel 5 symfony api-platform.com symfony4

我的疑问是关于 Api 平台的。( https://api-platform.com ) 我有两个实体。问题和答案。我想要进行一次 POST 调用来创建一个只有一个答案的问题。我展示我的实体。

namespace App\Entity;

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

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"question"}},
 *     denormalizationContext={"groups"={"question"}})
 * @ORM\Entity
 */
class Question
{
    /**
     * @Groups({"question"})
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @Groups({"question"})
     * @ORM\Column
     * @Assert\NotBlank
     */
    public $name = '';

    /**
     * @Groups({"question"})
     * @ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist"})
     */
    private $answers;

    public function getAnswers()
    {
        return $this->answers;
    }

    public function setAnswers($answers): void
    {
        $this->answers = $answers;
    }


    public function __construct() {
        $this->answers = new ArrayCollection();
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getId(): int
    {
        return $this->id;
    }
}
Run Code Online (Sandbox Code Playgroud)

和一个应答实体

namespace App\Entity;

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

/**
 *
 * @ApiResource
 * @ORM\Entity
 */
class Answer
{
    /**
     * @Groups({"question"})
     * @ORM\Id
     * @ORM\Column(type="guid")
     */
    public $id;

    /**
     * @Groups({"question"})
     * @ORM\Column
     * @Assert\NotBlank
     */
    public $name = '';

    /**
     * @ORM\ManyToOne(targetEntity="Question", inversedBy="answers")
     * @ORM\JoinColumn(name="question_id", referencedColumnName="id")
     */
    public $question;

    public function getQuestion()
    {
        return $this->question;
    }

    public function setQuestion($question): void
    {
        $this->question = $question;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

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

    public function __toString()
    {
        return $this->getName();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以从 nelmio 的仪表板创建一个问题并生成答案。但在数据库中,我的答案没有保存与问题的关系。

{
  "name": "my new question number 1",
  "answers": [
    {
          "id": "ddb66b71-5523-4158-9aa3-2691cae9d473",
          "name": "my answer 1 to question number 1"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

其他问题是...我已经通过 guid 更改了我的答案 id,因为当我创建并回答没有 id 的问题时,我收到错误。我可以创建问题和答案而不指定 id 吗?

提前致谢

Ayt*_*Nzt 0

对于第一点,它应该毫无问题地保存在数据库中。无论如何,您可以为 Question 实体创建一个 PostValidateSubscriber 并检查关系是否存在。

<?php /** @noinspection PhpUnhandledExceptionInspection */

namespace App\EventSubscriber;

use ApiPlatform\Core\EventListener\EventPriorities;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

final class QuestionPostValidateSubscriber implements EventSubscriberInterface
{
    private $tokenStorage;

    public function __construct(
        TokenStorageInterface $tokenStorage
    ) {
        $this->tokenStorage = $tokenStorage;
    }
    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::VIEW => ['checkQuestionData', EventPriorities::POST_VALIDATE]
        ];
    }

    /**
     * @param GetResponseForControllerResultEvent $event
     */
    public function checkQuestionData(GetResponseForControllerResultEvent $event)
    {
        $bid = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();

        if (!$question instanceof Question || (Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method))
            return;

        $currentUser = $this->tokenStorage->getToken()->getUser();
        if (!$currentUser instanceof User)
            return;
    }
}
Run Code Online (Sandbox Code Playgroud)

并执行 echo 或使用 xdebug 检查问题。

对于第二点,您可以为实体的 id 添加这些注释,以便 id 会自行生成。

  • @ORM\GenerateValue()
  • @ORM\Column(类型=“整数”)