如何解决如何在 Symfony 和 api-platform 中正确关联组实体
我收到错误:
nested documents for attribute "players" are not allowed. Use IRIs instead.
所以,我知道我需要使用序列化程序创建组。
我在做什么;我使用 symfony 5、doctrine(sqlite) 和 api-platform。
我正在制作一款游戏,一款游戏需要玩家。所以当我在数据库中添加游戏时,我也想添加玩家。两者都有自己的实体; Game.PHP 和 Player.PHP(也在实体文件夹中)。
由于某种原因,我无法正确链接 2 个实体,我做错了什么?
我使用API-platform来执行这个json;
{
"active": 0,"hints": 0,"players": [
{
"game": 1,"nickname": "string","code": "string"
}
],"price": "345","gameMap": "/api/game_maps/2","uidGame": "4","teamName": "3","secretKey": "fdgfdg","startTime": "2021-03-11T11:38:45.923Z","lastActionOnTime": "2021-03-11T11:38:45.923Z","endTime": "2021-03-11T11:38:45.923Z","penaltyTime": "g","testGame": 0
}
游戏实体:
<?PHP
namespace App\Entity;
use App\Repository\GameRepository;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(normalizationContext={ "groups": {"boost"} })
* @ORM\Entity(repositoryClass=GameRepository::class)
*/
class Game
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"boost"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=GameMap::class,inversedBy="games",cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
* @Groups({"boost"})
*/
private $game_map;
/**
* @ORM\Column(type="string",length=255)
*/
private $uid_game;
/**
* @ORM\Column(type="string",length=255)
*/
private $team_name;
/**
* @ORM\Column(type="string",length=255)
*/
private $secret_key;
/**
* @ORM\Column(type="datetime")
*/
private $start_time;
/**
* @ORM\Column(type="datetime")
*/
private $last_action_on_time;
/**
* @ORM\Column(type="smallint")
*/
private $active;
/**
* @ORM\Column(type="datetime")
*/
private $end_time;
/**
* @ORM\Column(type="integer")
*/
private $hints;
/**
* @ORM\Column(type="bigint")
*/
private $penalty_time;
/**
* @ORM\Column(type="json")
*/
private $progress = [];
/**
* @ORM\Column(type="string",length=255)
*/
private $price;
/**
* @ORM\Column(type="smallint")
*/
private $test_game;
/**
* @ORM\OnetoMany(targetEntity=Player::class,mappedBy="game",orphanRemoval=true,cascade={"persist"})
* @Groups({"boost"})
*/
private $players;
/**
* @ORM\OnetoMany(targetEntity=UserGame::class,cascade={"persist"})
* @Groups({"boost"})
*/
private $userGames;
}
和 Player 实体:
<?PHP
namespace App\Entity;
use App\Repository\PlayerRepository;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource()
* @ORM\Entity(repositoryClass=PlayerRepository::class)
*/
class Player
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"boost"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Game::class,inversedBy="players")
* @ORM\JoinColumn(nullable=false)
* @Groups({"boost"})
*/
private $game;
/**
* @ORM\Column(type="string",length=255)
* @Groups({"boost"})
*/
private $nickname;
/**
* @ORM\Column(type="string",length=255)
* @Groups({"boost"})
*/
private $code;
}
解决方法
因此,您的情况有两个不同的问题。
-
使用不同的规范化和非规范化上下文。将 Game 和 Player 中所有需要的字段添加到非规范化组中:
/** * @ApiResource( * normalizationContext={ "groups": {"boost"} },* denormalizationContext={ "groups": {"write"} } * ) * @ORM\Entity() */ class Game { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") * @Groups({"boost"}) */ private $id; ... /** * @ORM\OneToMany(targetEntity=Player::class,mappedBy="game",orphanRemoval=true,cascade={"persist"}) * @Groups({"boost","write"}) */ private $players; }
还有:
/**
* @ApiResource()
* @ORM\Entity()
*/
class Player
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @Groups({"boost"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Game::class,inversedBy="players")
* @ORM\JoinColumn(nullable=false)
*/
private $game;
/**
* @ORM\Column(type="string",length=255)
*
* @Groups({"boost","write"})
*/
private $nickname;
/**
* @ORM\Column(type="string","write"})
*/
private $code;
- 在您的 POST /api/games 中,您在正文请求中使用 game: 1,在 players 嵌套集合中。这很糟糕,因为您实际上运行了创建游戏 请求。在这种情况下,如何将玩家链接到已经存在的游戏? Game 和 Player 之间的关系是 OneToMany。你明白我的意思吗?
经过这些更改和 POST /api/games 正文
{
"active": 0,"hints": 0,"players": [
{
"nickname": "string","code": "string"
}
],"price": "345","uidGame": "4","teamName": "3","secretKey": "fdgfdg","startTime": "2021-03-11T11:38:45.923Z","lastActionOnTime": "2021-03-11T11:38:45.923Z","endTime": "2021-03-11T11:38:45.923Z","penaltyTime": "9","testGame": 0
}
我在 GET /api/games 上得到了响应:
[
{
"id": 1,"startTime": "2021-03-11T11:38:45+00:00","lastActionOnTime": "2021-03-11T11:38:45+00:00","active": 0,"endTime": "2021-03-11T11:38:45+00:00","progress": [],"testGame": 0,"players": [
{
"id": 1,"nickname": "string","code": "string"
}
]
}
]
你期待吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。