Yii2: как показать данные из двух связанных таблиц?

У меня есть таблица persons(id_person, name_person, id_color) и таблица colors(id_color, name_color).

Мне нужно показать имена людей и имя цвета каждого человека внутри компонента Select2.

Я использую компонент Select2, очень похожий на kartik-v/yii2-widget-select2 и 2amigos/yii2-select2-widget.

Я могу сделать это, создав массив с помощью SQL-запроса, но я хотел бы знать, предоставляет ли Yii2 лучшее и простое решение.


person Roby Sottini    schedule 19.04.2018    source источник
comment
это отношение one-to-one или one-to-many к таблице colors означает, что человеку может быть назначен один цвет или несколько   -  person Muhammad Omer Aslam    schedule 19.04.2018
comment
Это один ко многим.   -  person Roby Sottini    schedule 19.04.2018
comment
в своем ответе вы используете findOne(), а не findAll(), чтобы получить цвет против person_id, что показывает, что против человека сохранен только один цвет? Я добавил ответ ниже, посмотрите, поможет ли это.   -  person Muhammad Omer Aslam    schedule 19.04.2018
comment
я надеюсь, что вы не сохраняете значение, разделенное запятыми, в id_color в таблице persons, иначе у вас должна быть соединительная таблица, чтобы иметь отношение один ко многим, если я не ошибаюсь   -  person Muhammad Omer Aslam    schedule 19.04.2018


Ответы (2)


Это решение работает, но я не думаю, что оно лучшее:

public function personsList()
{
    $persons = \app\models\Persons::find()->orderBy('name_person')->all();
    $personsList = yii\helpers\ArrayHelper::map($persons, 'id_person', function($persons) {
        $color = \app\models\Colors::findOne(['id_color' => $persons->id_color]);
        $name_color = $color->name_color;
        return $persons->name_person . ' - ' . $name_color;
    });

    return $personsList;
}

Я надеюсь, что кто-то может улучшить его.

person Roby Sottini    schedule 19.04.2018

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

Я предполагаю, что вы связаны с именем getColor() внутри вашей модели Persons. Измените свою функцию personsList() на следующую.

public function personsList() {
     $persons = rsons::find()->with('color')->orderBy('name_person')->all();
     return ArrayHelper::map($persons, 'id_person', function($persons) {
          return $persons->name_person . ' - ' . $persons->color->name_color;
     });
}

Вышеприведенное вернет вам массив, как показано ниже

{
    "1": "omer aslam - red",
    "2": "irfan ashraf - blue",
    "3": "shaban khan - pink",
    "4": "rana touqeer - red",
    "5": "sajjad - blue"
}

РЕДАКТИРОВАТЬ

Если вы сохраняете несколько цветов для человека, который выглядит иначе, поскольку у вас нет соединительной таблицы, а цвет сохраняется для person в таблице persons, но в любом случае, если это one-to-many, измените функцию обратного вызова внутри ArrayHelper::map() на ниже так что он показывает вам все цвета, связанные с человеком.

function($persons) {
    return $persons->name_person . '-' . implode(",",\yii\helpers\ArrayHelper::getColumn($persons->color, 'name_color'));
}
person Muhammad Omer Aslam    schedule 19.04.2018