如何在 yii2 中让 many-to-many 休息 API

How make a many-to-many rest API in yii2

我正在尝试建立 many-to-may 关系,但我做不到。

我有一个包含 3 个 table 的数据库:usersfavoritesvideos。收藏夹 table 包含 2 个 foreign keys 指向用户 table 和视频 table.

目前我有:

用户模型:

public function getVideos()
{
    return $this->hasMany(Video::class, ['id' => 'video_id'])->viaTable(UserFavorites::tableName(), ['favorite_id' => 'id']);
}

视频模型:

public function getUsers()
{
    return $this->hasMany(User::class, ['id' => 'user_id'])->via(UserFavorites::tableName());
}

视频控制器:(主动控制器)

public function actions()
{
    $actions = parent::actions();
    $actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];
    return $actions;
}

public function prepareDataProvider()
{
    $user = User::findOne('1=1');
    return new ActiveDataProvider([
       'query' => $user->getVideos()
    ]);
}

按照他们所做的:
但这没有用。我也试过 extraFieldsexpand 没有运气。

我该怎么做才能使结果看起来像这样:

[{
    "id": 1, 
    "name": "video name",
    "likes": 69,
    "user": [{
        "id": 1,
        "name": "John"
    }]
},
...
]

您需要更新几个地方的代码。

REST 活动控制器

看起来您正在尝试获取 一个 用户喜欢的视频,您应该使用查看操作,而不是索引操作,它应该用于获取视频列表,您可以使用基本 view 操作,无需覆盖它,它会按照您的需要工作。

在controller里面,设置模型应该就够了。

use yii\rest\ActiveController;

class VideoController extends ActiveController
{    
    public $modelClass = Video::class;
}

考虑设置 $_verbsactionOptions 如果您需要它们不是默认值。

型号.

您应该使用 extraFields 将方法公开为字段。

use yii\db\ActiveRecord;

class Video extends ActiveRecord
{
    // Other methods here...

    public function getUsers()
    {
        return $this->hasMany(User::class, ['id' => 'user_id'])
            ->viaTable(UserFavorites::tableName(), [
                'video_id' => 'id'
            ]);
    }

    public function extraFields()
    {
        return [
            'users'
        ];
    }
}

如果您想对 API 调用使用与函数相同的名称,即 API 调用使用 expand=users 并且调用方法 getUsers() 您可以在 expandFields 上使用 users 快捷方式,如果名称不同,则可以使用扩展格式,即 'likes' => 'users'

然后,通过以下方式查询您的 API:

https://apiv1.example.com/videos/45?expand=users

应该会像 post

中那样给您预期的结果
[{
    "id": 1, 
    "name": "video name",
    "likes": 69,
    "users": [{
        "id": 1,
        "name": "John"
    }]
},
...
]

请注意,用户数组将被称为 'users' 而不是 'user' 如果您以相同的方式配置,您可以使用 extraFields 中的扩展符号更改它。