Как сделать API-интерфейс «многие ко многим» в yii2

Я пытаюсь заставить работать отношение «многие к маю», но не могу заставить его работать.

У меня есть база данных с 3 таблицами: users, favorites и videos. Таблица избранного содержит 2 foreign keys, которые указывают на таблицу пользователей и таблицу видео.

В настоящее время у меня есть следующее:

Модель пользователя:

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()
    ]);
}

После того, что они сделали в: Отношение «многие ко многим» в yii2 activedataprovider
но это не сработало. Я также пробовал с extraFields и expand безуспешно.

Как мне сделать так, чтобы результат выглядел примерно так:

[{
    "id": 1, 
    "name": "video name",
    "likes": 69,
    "user": [{
        "id": 1,
        "name": "John"
    }]
},
...
]
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
195
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно обновить код в нескольких местах.

Активный контроллер REST.

Похоже, вы пытаетесь получить одно видео с пользователем, которому оно понравилось, вы должны использовать действие просмотра, а не действие индекса, которое следует использовать для получения списка видео, вы можете использовать базовое действие view, нет нужно переопределить его, он будет работать так, как вам нужно.

В контроллере должно быть достаточно настройки модели.

use yii\rest\ActiveController;

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

Попробуйте установить $_verbs и actionOptions, если вам нужно, чтобы они не использовались по умолчанию.

Модель.

Вы должны использовать 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(), вы можете использовать ярлык users на expandFields, если имена разные, вы можете использовать расширенный формат, то есть 'likes' => 'users'

Затем запросите ваш API с помощью:

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

Должен дать вам ожидаемые результаты, как в вашем посте

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

Обратите внимание, что массив пользователей будет называться «пользователи», а не «пользователь», если вы настроили таким же образом, вы можете изменить это, используя расширенную нотацию внутри extraFields.

Спасибо за объяснение того, как точки связаны; Я изменил имя метода на getUsers и имя дополнительного поля на users. Теперь я получаю сообщение об ошибке «не имеет отношения с именем ...».

NS - Not the train 10.12.2020 12:19

Я только что заметил, что вы используете via, но даете ему имя таблицы вместо имени отношения. Проверьте документацию по этому вопросу в Yii docs Один из способов исправить это — использовать viaTable Я обновлю ответ.

Raul Sauco 10.12.2020 14:23

Другие вопросы по теме