Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 与api平台的嵌入关系_Symfony_Symfony4_Api Platform.com - Fatal编程技术网

Symfony 与api平台的嵌入关系

Symfony 与api平台的嵌入关系,symfony,symfony4,api-platform.com,Symfony,Symfony4,Api Platform.com,我怀疑的是Api平台。() 我有两个实体。问答。我想打一个电话来创建一个只有一个答案的问题。我展示我的实体 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

我怀疑的是Api平台。() 我有两个实体。问答。我想打一个电话来创建一个只有一个答案的问题。我展示我的实体

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;
    }
}
和一个应答实体

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();
    }
}
现在,我可以从nelmio的仪表盘中创建一个问题并将其转化为一个答案。但在数据库中,我的回答没有保存与问题的关系

{
  "name": "my new question number 1",
  "answers": [
    {
          "id": "ddb66b71-5523-4158-9aa3-2691cae9d473",
          "name": "my answer 1 to question number 1"
    }
  ]
}
另一个问题是。。。我已通过guid更改了我的答案id,因为当我将问题和答案创建为没有id的问题时,会出现错误。我是否可以创建问题和答案而不指定id


提前感谢第一点,它应该可以毫无问题地保存在数据库中。无论如何,您可以为问题实体创建一个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;
    }
}

我在你的实体中看到了一些错误。。。首先,由于问答实体之间的关系是一个单一实体,您的Qestion实体应该实现此功能,即:

use ApiPlatform\Core\Annotation\ApiProperty;

//..... the rest of your code

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


public function __construct()
{
     //....

      $this->answers = new ArrayCollection();

     //...
}

public function addAnswer(Answer $answer): self
{
     if (!$this->answers->contains($answer)) {
           $this->answers[] = $answer;
           $answer->setQuestion($this) 
     }

     return $this;
}

public function removeAnswer(Answer $answer): self
{
    if ($this->answers->contains($answer)) {
        $this->answers->removeElement($answer);
    }
    return $this;
}
命令

PHP bin/console make:entity
允许您在关系类型的实体中创建字段,它为您创建这些方法,只需按照说明操作(创建两个实体后,使用命令更新问题实体…)

readableLink ApiProperty注释用于GET请求时查看嵌入对象,如果使用序列化组,则注释相同,如果将其设置为false,则响应如下所示:

{
  "name": "my new question number 1",
  "answers": [
    "/api/answers/1",
    "/api/answers/2",
    ....
  ]
}
它用于使响应更小(除其他外)。。。writableLink用于允许这样的POST请求(有关更多信息,请参见此示例):

当然,在每个实体中使用相应的序列化组。。。 在APIC平台中,嵌入式对象通过setters和getter方法持久化,但也可以为OneToMany关系添加和删除方法,剩下的工作由ORM完成。
让我知道这是否有帮助。干杯

答案正确保存,但答案数据库中的字段问题的值为NULL:/您找到解决方案了吗,我也有相同的问题。对象为persit,但关系id为Null。在这个问题上有什么进展?如果你有解决方案,请分享!
{
  "name": "my new question number 1",
  "answers": [
    {
          "id": "ddb66b71-5523-4158-9aa3-2691cae9d473",
          "name": "my answer 1 to question number 1"
    }
  ]
}