如何在 API 平台上保存与实体的嵌套关系 [英] How to save a Nested Relation with Entity on API Platform

查看:31
本文介绍了如何在 API 平台上保存与实体的嵌套关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体,QuestionAlternative,其中 Question 与 Alternative 有 OneToMany 关系,我正在尝试发送带有 嵌套文档的 JSON替代,通过 POST 到 Question API 平台.

I have two entities, Question and Alternative where Question has a OneToMany relation with Alternative and I'm trying to send a JSON with a nested document of Alternative on it via POST to Question API Platform.

API 平台返回以下错误:

The API Platform returns that error below :

Nested documents for "alternatives" attribute are not allowed. Use IRIs instead.

搜索它我发现有些人说这只能使用 IRI,而其他一些人说可以使用非规范化和规范化上下文来解决这个问题,但我找不到关于它的一些示例或教程.

Searching about it I've found some people saying that is only possible using IRIs and some other people saying that is possible to use Denormalization and Normalization contexts to solve this problem but I can't find some example or tutorial about it.

TL;DR;

有没有办法在不使用 IRI 的情况下将嵌套关系发送到 API 平台上的实体 POST 中?

Is there a way to send a nested relation into an entity POST on API Platform without using IRIs?

更新:

如所问,请参阅下面的问题和替代实体的两个映射.

As asked, please see below the two mappings of Question and Alternative entities.

问题

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\QuestionRepository")
 * @ApiResource()
 */
class Question implements CreatedAtEntityInterface, UpdatedAtEntityInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Token", inversedBy="questions")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotBlank()
     */
    private $token;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="question_versions")
     */
    private $question;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Question", mappedBy="question")
     */
    private $question_versions;

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     */
    private $version;

    /**
     * @ORM\Column(type="string", length=100)
     * @Assert\Length(max="100")
     * @Assert\NotBlank()
     *
     */
    private $name;

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     */
    private $type;

    /**
     * @ORM\Column(type="text", length=65535)
     * @Assert\NotBlank()
     * @Assert\Length(max="65535")
     */
    private $enunciation;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\Length(max="255")
     */
    private $material;

    /**
     * @ORM\Column(type="text", length=65535, nullable=true)
     * @Assert\Length(max="65535")
     */
    private $tags;

    /**
     * @ORM\Column(type="boolean")
     * @Assert\NotNull()
     */
    private $public;

    /**
     * @ORM\Column(type="boolean")
     * @Assert\NotNull()
     */
    private $enabled;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    private $createdAt;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    private $updatedAt;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Alternative", mappedBy="question")
     */
    private $alternatives;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\QuestionProperty", mappedBy="question")
     */
    private $properties;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\QuestionAbility", mappedBy="question")
     */
    private $abilities;

    /**
     * @ORM\OneToMany(targetEntity="QuestionCompetency", mappedBy="question")
     */
    private $competencies;
}

替代方案

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\AlternativeRepository")
 * @ORM\Table(name="alternatives")
 * @ApiResource()
 */
class Alternative implements CreatedAtEntityInterface, UpdatedAtEntityInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="alternatives")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotBlank()
     */
    private $question;

    /**
     * @ORM\Column(type="text", length=65535)
     * @Assert\NotBlank()
     * @Assert\Length(max="65535")
     */
    private $enunciation;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    private $createdAt;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     */
    private $updatedAt;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\AlternativeProperty", mappedBy="alternatives")
     */
    private $properties;
}

推荐答案

你可以尝试实现 反规范化

问题:

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\QuestionRepository")
 * @ApiResource(
 *     denormalizationContext={"groups"={"post"}}
 * )
 */
class Question implements CreatedAtEntityInterface, UpdatedAtEntityInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Token", inversedBy="questions")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotBlank()
     * @Groups({"post"})
     */
    private $token;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="question_versions")
     * @Groups({"post"})
     */
    private $question;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Question", mappedBy="question")
     * @Groups({"post"})
     */
    private $question_versions;

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     * @Groups({"post"})
     */
    private $version;

    /**
     * @ORM\Column(type="string", length=100)
     * @Assert\Length(max="100")
     * @Assert\NotBlank()
     * @Groups({"post"})
     */
    private $name;

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     * @Groups({"post"})
     */
    private $type;

    /**
     * @ORM\Column(type="text", length=65535)
     * @Assert\NotBlank()
     * @Assert\Length(max="65535")
     * @Groups({"post"})
     */
    private $enunciation;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\Length(max="255")
     * @Groups({"post"})
     */
    private $material;

    /**
     * @ORM\Column(type="text", length=65535, nullable=true)
     * @Assert\Length(max="65535")
     * @Groups({"post"})
     */
    private $tags;

    /**
     * @ORM\Column(type="boolean")
     * @Assert\NotNull()
     * @Groups({"post"})
     */
    private $public;

    /**
     * @ORM\Column(type="boolean")
     * @Assert\NotNull()
     * @Groups({"post"})
     */
    private $enabled;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     * @Groups({"post"})
     */
    private $createdAt;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     * @Groups({"post"})
     */
    private $updatedAt;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Alternative", mappedBy="question")
     * @Groups({"post"})
     */
    private $alternatives;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\QuestionProperty", mappedBy="question")
     * @Groups({"post"})
     */
    private $properties;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\QuestionAbility", mappedBy="question")
     * @Groups({"post"})
     */
    private $abilities;

    /**
     * @ORM\OneToMany(targetEntity="QuestionCompetency", mappedBy="question")
     * @Groups({"post"})
     */
    private $competencies;
}

替代方案:

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\AlternativeRepository")
 * @ORM\Table(name="alternatives")
 * @ApiResource()
 */
class Alternative implements CreatedAtEntityInterface, UpdatedAtEntityInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="alternatives")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotBlank()
     * @Groups({"post"})
     */
    private $question;

    /**
     * @ORM\Column(type="text", length=65535)
     * @Assert\NotBlank()
     * @Assert\Length(max="65535")
     * @Groups({"post"})
     */
    private $enunciation;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     * @Groups({"post"})
     */
    private $createdAt;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime()
     * @Groups({"post"})
     */
    private $updatedAt;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\AlternativeProperty", mappedBy="alternatives")
     * @Groups({"post"})
     */
    private $properties;
}

现在您可以在没有 IRI 的情况下将 JSON 发送到 POST/PUT:

Now you can this send JSON to POST/PUT without IRI:

{
    "token": "/api/tokens/1",
    "question": "string",
    "version": "string",
    "name": "string",
    "type": 0,
    "enunciation": "string",
    "public": true,
    "enabled": true,
    "alternatives": [
        {
            "enunciation": "String",
            "createdAt": "2018-01-01 11:11:11",
            "updatedAt": "2018-01-01 11:11:11"
        }
    ]
}

这篇关于如何在 API 平台上保存与实体的嵌套关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆