В предыдущей статье, посвящённой связанным таблицам, мы рассмотрели общий механизм работы с ними на достаточно простом примере. Однако в реальных проектах встречаются и более сложные ситуации.
Допустим у нас есть следующая структура таблиц.
Она представляет собой список задач (таблица tasks) в котором помимо всего прочего фиксируется создатель и исполнитель задачи (таблица users).
На первый взгляд ничего сложного здесь нет. Но если внимательно присмотреться к приведённой схеме можно заметить, что на таблицу users ссылаются целых два поля таблицы tasks.
В результате, если мы попытаемся добавить сортировку или поиск так, как мы это делали раньше, написав что-то наподобие такого:
1 |
$query->joinWith(['users']); |
Мы получим ошибку, т.к. Yii 2 самостоятельно не может корректно обработать подобную структуру таблиц и будет для обоих связанных полей использовать одно и то же имя таблицы, что неизбежно приведёт к ошибке выполнения SQL запроса.
Для того чтобы решить эту задачу нам потребуется в методе joinWith задать псевдоним таблицы users для каждого поля при помощи метода from объекта ActiveQuery. Как это можно сделать показано на примере ниже.
1 2 3 4 5 6 |
$query->joinWith(['creator'=>function($query){ $query->from(Users::tableName().' creatorUser'); }, 'worker'=>function($query){ $query->from(Users::tableName().' workerUser'); }]); |
Как обычно в метод joinWith передаётся массив. Но, в отличие от примера, рассмотренного нами в предыдущей статье, здесь массив ассоциативный. В нём ключ – связываемое поле, значение функция внутри которой выполняется определение псевдонима таблицы users для каждого поля.
Определить псевдоним просто. Нужно в вышеописанной функции вызвать метод from объекта ActiveQuery передав ему в качестве параметра строку, которая состоит из имени таблицы и собственно псевдонима через пробел, как это показано выше.
Теперь мы можем добавить сортировку и поиск для создателя и исполнителя задачи используя вместо имени таблицы соответствующие псевдонимы.
Добавление сортировки:
1 2 3 4 5 6 7 8 |
$dataProvider->sort->attributes['creatorName'] = [ 'asc' => ['creatorUser.fio' => SORT_ASC], 'desc' => ['creatorUser.fio' => SORT_DESC], ]; $dataProvider->sort->attributes['workerName'] = [ 'asc' => ['workerUser.fio' => SORT_ASC], 'desc' => ['workerUser.fio' => SORT_DESC], ]; |
Добавление поиска:
1 2 |
$query->andFilterWhere(['like', 'creatorUser.fio', $this->creatorName]) ->andFilterWhere(['like', 'workerUser.fio', $this->workerName]); |
Мы рассмотрели использование псевдонимов связанных таблиц в Yii 2 на примере добавления сортировки и поиска для GridView. Однако принцип, описанный в данной статье, на самом деле может применяться и к любым задачам, в которых используются подобные выборки данных.
Добавить комментарий