我熟悉使用 Laravel 创建多对多关系。
在我的示例中,我有许多
resources
共享许多 activities
。我已经能够在各自的模型中成功创建这种关系:
// Activity.php
public function resources(): BelongsToMany
{
return $this->belongsToMany(Resource::class)->withTimestamps();
}
// Resource.php
public function activities(): BelongsToMany
{
return $this->belongsToMany(Activity::class)->withTimestamps()
->using(new class extends Pivot {
use HasUuids;
});
}
然后我将使用
sync
方法来创建关系。
$Ids = ['9a4cf36f-7683-4656-9653-9a01e1edbca1', '9a5225f0-31f6-40be-8863-6e8de61ef29f'];
$resource->activities()->sync($activityIds);
我正在尝试使用 Laravel JSON:API 包创建相同的关系。
我的
ActivitySchema
看起来像这样:
return [
...
BelongsToMany::make('resources')->readOnly(),
...
我的
ResourceSchema
看起来像这样:
return [
...
ArrayList::make('activities'),
...
BelongsToMany::make('activities')->readOnly(),
...
使用Postman,在创建或更新资源时,我的请求正文如下所示:
"attributes": {
"activities": ["9a4cf36f-7683-4656-9653-9a01e1edbca1", "9a5225f0-31f6-40be-8863-6e8de61ef29f"]
...
我当前在创建新资源时遇到的错误是:
"detail": "字段活动不是受支持的属性。",
通常这意味着我缺少模式中的字段。我已经验证了它的存在,所以我想知道这是不是因为关系?
我尝试过使用枢轴模型,但也没有成功。我需要创建一个自定义控制器来处理这个逻辑吗?我没有找到任何关于如何
sync
模型的说明。
如何使用 JSON:API 包创建/同步关系?
您需要查看教程,因为它有一个多对多关系的示例;帖子 -- 标签。
除了要在资源中更新的“属性”之外,您还需要包含关系。
例如,您的资源
PATCH
请求正文将如下所示:
{
"data": {
"type": "resources",
"id": "676110ee-c302-4239-8eac-1f9e87ebaae8",
"attributes": {
"some_id": "01b77de1-d524-4794-af90-88f64dd68999",
"name": "My Resource",
"description": "This is some updated text!"
},
"relationships": {
"activities": {
"data": [
{
"type": "activities",
"id": "9a4cf36f-7683-4656-9653-9a01e1edbca1"
},
{
"type": "activities",
"id": "9a5225f0-31f6-40be-8863-6e8de61ef29f"
}
]
}
}
}
}
现在在发回的响应中,您将看到关系。
除了上述内容之外,您还需要更新资源请求以允许
toMany
规则:
public function rules(): array
{
return [
...
'name' => 'required|string|max:255',
'description' => 'required',
'activities' => JsonApiRule::toMany(),
];
}
如果您遵循该关系,您现在应该会看到正确返回的数据。
"relationships": {
"activities": {
"links": {
"related": "http://my.api.test/api/v1/resources/9a528648-37e9-4f58-b37c-f4e3a6cb478d/activities",
"self": "http://my.api.test/api/v1/resources/9a528648-37e9-4f58-b37c-f4e3a6cb478d/relationships/activities"
}
}
}
如果您传入
included
查询,API将在响应中发回所请求的关系。
/api/v1/resources/:resource_id?include=activities
...
"included": [
{
"type": "activities",
"id": "9a4cf36f-7683-4656-9653-9a01e1edbca1",
"attributes": {...}