GridView вывод полей из таблиц не связанных напрямую

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Arkadii
Сообщения: 3
Зарегистрирован: 2019.12.22, 23:20

GridView вывод полей из таблиц не связанных напрямую

Сообщение Arkadii »

Привет всем!
Пытаюсь собрать запрос в gridview, по полям из нескольких таблиц, не все из которых связанны напрямую.

Схема данных следующая - Изображение https://ibb.co/31HZqS4

Никак не могу понять как отобразить данные из таблицы tickets_sold.
Нужно сделать геттер? Если да, то как? Я читал про viaTable, но все примеры были для связей Многие-Ко-Многим, чего у меня нет.
Буду очень признателен за совет, и крайне рад если он будет подкреплен примером :)

Модель

Код: Выделить всё

<?php

namespace app\models;

use Yii; 

class Q6 extends \yii\db\ActiveRecord
{
    public $ticket;
    public $owner;
    public $age;
    public $gender;
    public $baggage;

    public static function tableName()
    {
        return 'schedule';
    }

    public function rules()
    {
        return [
            [['depature', 'route_id', 'train_id'], 'required'],
            [['depature'], 'safe'],
            [['route_id', 'train_id'], 'integer'],
            [['route_id'], 'exist', 'skipOnError' => true, 'targetClass' => Routes::className(), 'targetAttribute' => ['route_id' => 'id']],
            [['train_id'], 'exist', 'skipOnError' => true, 'targetClass' => Trains::className(), 'targetAttribute' => ['train_id' => 'id']],
        ];
    } 

    public function attributeLabels()
    {
        return [
            'depature' => 'Дата отправления',
            'route_id' => 'Маршрут',
            'train_id' => 'Номер поезда',
            'ticket' => 'Номер билета',
            'owner' => 'Пассажир',
            'age' => 'Возраст',
            'gender' => 'Пол',
            'baggage' => 'Багаж',
        ];
    }

    public function getRoute()
    {
        return $this->hasOne(Routes::className(), ['id' => 'route_id']);
    }

    public function getTrain()
    {
        return $this->hasOne(Trains::className(), ['id' => 'train_id']);
    }

    public function getTickets()
    {
        return $this->hasMany(Tickets::className(), ['schedule_id' => 'id']);
    }
}
Модель поиска

Код: Выделить всё

<?php

namespace app\models;

use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Q6;

class Q6Search extends Q6
{

    public function rules()
    {
        return [
            [['depature', 'route_id', 'train_id', 'ticket', 'owner', 'gender', 'age', 'baggage'], 'safe'],
        ];
    }

    public function search($params)
    {

        $query = Q6::find()
        ->innerJoin('routes', 'routes.id = schedule.route_id')
        ->innerJoin('trains', 'trains.id = schedule.train_id')
        ->innerJoin('tickets', 'schedule.id = tickets.schedule_id')
        ->innerJoin('tickets_sold', 'tickets.id = tickets_sold.ticket_id');
        

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $dataProvider->setSort([
            'attributes' => [
              'depature',
                'route_id',
                'train_id',
                'ticket',
            ]
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        $query->andFilterWhere(['like', Routes::tableName().'.name', $this->route_id])
        ->andFilterWhere(['like', Trains::tableName().'.number', $this->train_id])
        ->andFilterWhere(['like', 'depature', $this->depature]);

        return $dataProvider;
    }
}
Представление

Код: Выделить всё

<?php

use yii\helpers\Html;
use yii\grid\GridView;

$this->title = 'Пассажиры';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="q6-index">

    <h1><?= Html::encode($this->title) ?></h1>


    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
          ['class' => 'yii\grid\SerialColumn'],
          'depature',
          [
            'attribute' => 'route_id',
            'value' => 'route.name'
          ],
          [
            'attribute' => 'train_id',
            'value' => 'train.number'
          ],
          [
            'attribute' => 'ticket',
            'value' => function($model) {
              return implode(\yii\helpers\ArrayHelper::map($model->tickets, 'id', 'number'));
            },
          ]
        ],
    ]); ?>


</div>

yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: GridView вывод полей из таблиц не связанных напрямую

Сообщение yiiliveext »

Если вы хотите вывести пассажиров и фильтровать их по маршруту, номеру поезда, дате отправления, то модель поиска у вас должна быть от tickets.
Ну и смысла в таблице tickets_sold я не вижу, но если надо, то пусть будет, это не мешает.
Arkadii
Сообщения: 3
Зарегистрирован: 2019.12.22, 23:20

Re: GridView вывод полей из таблиц не связанных напрямую

Сообщение Arkadii »

Добрый день!
Если я изменю модель поиска вопрос останется прежним.
Сейчас я не могу понять как добраться до поля tickets_sold.owner , а в другом случае не смогу добраться до routes.name и trains.number.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: GridView вывод полей из таблиц не связанных напрямую

Сообщение yiiliveext »

Суть не в этом, а в том что связь у schedule с tickets один к многим. Если вы возьмете за модель поиска tickets, то в гриде можно будет вывести так

Код: Выделить всё

 [
            'attribute' => 'route_name',
            'value' => function($model) {
              return = $model->schedule->route->name;
            },
          ],
           [
            'attribute' => 'train_number',
            'value' => function($model) {
              return = $model->schedule->train->number;
            },
          ]
Arkadii
Сообщения: 3
Зарегистрирован: 2019.12.22, 23:20

Re: GridView вывод полей из таблиц не связанных напрямую

Сообщение Arkadii »

Спасибо, это то что нужно :)
Ответить