yii2 - заполнить таблицу данными из двух таблиц из базы данных - PullRequest
0 голосов
/ 27 апреля 2020

Я использовал Yii и Yii2 несколько раз ... и каждый раз, когда я использую его, я теряюсь с этим фреймворком. На самом деле, Yii очень мощный, он многое для вас делает, но иногда вы теряетесь из-за этого, вы не знаете, что происходит и как делать какие-то простые вещи. Сейчас я пытаюсь заполнить таблицу данными из 2 связанных таблиц. Я читал форумы Yii, темы от StackOverflow, YouTube ... и ничего не работает. Моя конфигурация Yii2 advanced.

В postgres у меня есть две таблицы:

  • таблица 'tools' с полями 'id (int)' и 'tool_name (varchar)'.
  • таблица 'options' с полями 'id (int)', 'tool_id (int - внешний ключ от инструментов)', 'option_name (varchar)', 'type (int) ».

Дело в том, что в моих настройках / индексе я хочу показать имя инструмента в таблице следующим образом (GridView?):

| Имя инструмента | Option_name | Тип |

Другим вариантом может быть фильтрация таблицы через DropDownList, где я могу выбрать инструмент и обновить таблицу. Если инструмент не выбран, отображаются все данные. Я не знаю, какой вариант может быть проще, оба действительны для меня.

Может кто-нибудь показать мне свет, пожалуйста? Я ценю это ... Спасибо !!

Ответы [ 3 ]

1 голос
/ 27 апреля 2020

Лучший способ сделать это - использовать отношения, реализованные в активной модели.

1) Определить отношения в ваших моделях

Если вы использовали Gii для генерации классов вашей модели из тогда в вашей БД отношения, вероятно, уже определены.

Это должно выглядеть следующим образом

class Option extends \yii\db\ActiveRecord
{
    public function getTool()
    {
        return $this->hasOne(Tool::class, ['id' => 'tool_id']);
    }

    //... other code of the model
}

Определение отношения в классе модели позволит вам получить доступ к связанной модели как свойству этого объекта. Например, метод, определенный выше, позволит вам сделать что-то вроде $option->tool->tool_name.

2) Принудительная загрузка для отношения

По умолчанию в отношениях в Yii используется «отложенная загрузка». Это означает, что связанная модель не загружается из БД до тех пор, пока к ней нет доступа в первый раз. Это хорошо, когда вы работаете с одной моделью, потому что вы можете или не можете использовать эту связанную модель. Но если вы собираетесь вывести несколько моделей в таблицу, и каждая из них получит доступ к связанной модели, ленивая загрузка вызовет дополнительный запрос для каждой строки таблицы. Чтобы избежать этого, мы хотим сказать ActiveQuery, что он должен загружать все связанные модели для нашего отношения tool при загрузке моделей option. Это называется «нетерпеливая загрузка». Для этого необходимо использовать метод with() при создании запроса для поставщика данных.

Например, например:

$query = Option::find()
  ->with('tool'); //the param is name of relation

3) Добавить столбец из связанной модели в GridView

Теперь вы можете просто добавить столбец из связанной модели как relation.column, в вашем случае это будет tool.tool_name.

Пример:

<?= yii\grid\GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        'tool.tool_name',
        'option_name',
        'type',
    ]
]);
0 голосов
/ 27 апреля 2020

Вы ищете отношения .

Что будет hasMany в вашей модели инструмента:

public function getOptions() {
  return $this->hasMany(Options::className(), ['tool_id' => 'id']);
}

И hasOne в вашей модели опций:

public function getTool() {
  return $this->hasOne(Tools::className(), ['id' => 'tool_id']);
}

Теперь $model = Tools::find()->all() также предоставит вам соответствующие данные через $model->options. И наоборот для опций.

Поскольку вам, вероятно, нужны все инструменты со всеми опциями, ваш $ dataProvider будет опциями, а не инструментами. И для каждого варианта вы получите соответствующий инструмент.

Соответствующие данные могут быть показаны в виде таблицы с помощью

 [
 'attribute' => 'tools',
 'value' => 'tools.tool_name'
 ],

См. эту статью для справки.

Кроме того, Gii создает эти отношения для вас, если вы создаете свои модели с ним. (Обратите внимание, что вам нужно будет указать свой IP-адрес в разрешенных IP-адресах, если вы не работаете с localhost или он не будет отображаться.)

0 голосов
/ 27 апреля 2020

В модель параметров необходимо добавить следующее

    public function getTools()
    {
        return $this->hasOne(Options::className(), ['id' => 'tool_id']);
    }


    public function getToolName() {
        return $this->tools->tool_name;
    }

Тогда в сетке вида toolName

появится полезное поле
...