如何使用 Laravel JSON:API 创建belongsToMany 关系?

问题描述 投票:0回答:1

我熟悉使用 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 包创建/同步关系?

laravel json-api laravel-api
1个回答
0
投票

您需要查看教程,因为它有一个多对多关系的示例;帖子 -- 标签。

除了要在资源中更新的“属性”之外,您还需要包含关系。

例如,您的资源

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": {...}
© www.soinside.com 2019 - 2024. All rights reserved.