问题描述
我有一个具有多对多自引用关系的用户实体。它给了我 2 个属性: myFriends 和friendsWithMe(如Doctrine 文档中所述)以及addFriendsWithMe、removeFriendsWithMe、...等方法。
两个属性都是数组集合。
在 Api 平台中,如果我在更新我的用户实体(补丁 Api/users/1)时做这样的事情:
{
"friendsWithMe": [
"api/users/2"
]
}
它正在工作,但如果我想用同样的方式将另一个用户 (api/users/3) 添加到用户 1 的friendsWithMe,它不会添加到数组中,而是删除用户/2 并将其替换为用户/3 .
在常规的 Symfony 控制器中,如果我这样做:
$user->addFriendsWithMe($otherUser);
感觉就像使用 Api 平台,它不会检测 add* 方法,而是使用 remove 和 insert。
对此有什么想法吗?
感谢您的帮助。
解决方法
您需要使用加法器和移除器而不是 getter/setter(尽管您仍然需要一个 getter)。
假设你有:
// Annotation
private array $friends;
public function __construct()
{
$this->friends = new ArrayCollection();
}
“通常”您会创建一个 getter (return $this->friends
) 和一个 setter ($this->friends = $friends
)。
但是,使用 array
(ArrayCollection),您将希望能够添加/删除单个记录。
所以,删除 setter,用加法器和移除器替换它。
一切都变成了:
// Annotation
private array $friends;
public function __construct()
{
$this->friends = new ArrayCollection();
}
public function getFriends(): array
{
return $this->friends->toArray();
}
public function addFriend(Friend $friend): void
{
if(! $this->friends->contains($friend) {
$this->friends->add($friend);
}
}
public function removeFriend(Friend $friend): void
{
if($this->friends->contains($friend) {
$this->friends->removeElement($friend);
}
}
查看 Doctrine Many To Many 文档。
还阅读了 Api-Platform 的 Handling Relations。
确保避免为集合/项目端点设置序列化配置以序列化无限循环。 (所以只允许在端点(例如拥有方)单向包含整个实体以避免朋友->朋友->朋友->朋友->无限循环)
,这似乎是 Api 平台的一个常见问题,实际上,对任何 OneToMany 或 ManyToMany 关系的补丁和放置请求被视为替代(因此它不会只是附加新关系)。
试试这些:
- 您可能想要创建一个自定义操作(一个实际上确实附加您的新关系的自定义端点,例如对
/api/users/{id}/friends
的 POST 请求,其正文包含新的“朋友”要附加的 IRI)。 - 或者您可以尝试建立反向关系(嗯,在您的情况下,我认为它可能不会成功,因为它是多对多关系,但下次您有单对多或多对一关系时,您可能想要这样做)。
API 平台提出修复这个问题会很棒,但恐怕它不是真正传入(并且不是真的错误,只是一个不同的观点)。