andFilterWhere для полей связанных таблиц

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Закрыто
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

andFilterWhere для полей связанных таблиц

Сообщение zingeon »

Использую такой запрос:

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

Questionnaire::find()->with("customer", "account", "statuses", "status", "creditProduct", "currentStatus")
К нему мне нужно прикрутить фильтрацию, использую для этого andFilterWhere. Но когда пытаюсь отфильтровать данные по связанной таблице:

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

Questionnaire::find()->with("customer", "account",  "status", "creditProduct", "currentStatus")->andFilterWhere(['like', 'customer.first_name', 'иван'])
мне выводит ошибку:

Database Exception – yii\db\Exception

SQLSTATE[42703]: Undefined column: 7 ERROR: column "first_name" does not exist
LINE 1: SELECT COUNT(*) FROM "questionnaires" WHERE "first_name" LIK...
^
The SQL being executed was: SELECT COUNT(*) FROM "questionnaires" WHERE "first_name" LIKE '%иван%'


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

Поступаю иным образом:

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

Questionnaire::find()->with(["customer"=> function ($query) {
                                $query
                                        ->andFilterWhere(['like', 'first_name', 'иван']);
                            }, "account", "status", "creditProduct", "currentStatus"]);
ошибки нету, зато теперь из этой таблицы данные вообще не выводятся (с остальными связями все нормально).


Подскажите, пожалуйста, как мне решить данную проблему? Как извлечь данные из связанных таблиц с помощью andFilterWhere?
Аватара пользователя
Roksalana
Сообщения: 215
Зарегистрирован: 2014.01.14, 09:34

Re: andFilterWhere для полей связанных таблиц

Сообщение Roksalana »

Используйте joinWith вместо with для этой таблицы, тогда можно будет фильтровать так, как вы делали в первом случаи

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

Questionnaire::find()
->joinWith("customer")
->with( "account",  "status", "creditProduct", "currentStatus")
->andFilterWhere(['like', 'customer.first_name', 'иван'])
 
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

Re: andFilterWhere для полей связанных таблиц

Сообщение zingeon »

Roksalana писал(а):Используйте joinWith вместо with для этой таблицы
просто при joinWith я не смогу использовать поля из связанных таблиц - а мне это нужно. А если использовать и то, и то, получается, будет происходить по 2 практически одинаковых запросов, что некорректно
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

Re: andFilterWhere для полей связанных таблиц

Сообщение zingeon »

еще заметил - если добавить к запросу метод ->all(), то все ок. Но мне этот результат запроса нужен для пагинации - класса Pagination, который выдает ошибки, если в него кинуть результат запроса с методом ->all()

какая-то безысходность
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: andFilterWhere для полей связанных таблиц

Сообщение zelenin »

zingeon писал(а): просто при joinWith я не смогу использовать поля из связанных таблиц - а мне это нужно
почему? joinWith просто джойнит эти данные, делая жадный запрос
и исопльзуйте массивы внутри with/joinWith (joinWith(['...', '...']))
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: andFilterWhere для полей связанных таблиц

Сообщение zelenin »

zingeon писал(а):еще заметил - если добавить к запросу метод ->all(), то все ок. Но мне этот результат запроса нужен для пагинации - класса Pagination, который выдает ошибки, если в него кинуть результат запроса с методом ->all()

какая-то безысходность
верно. all() добавляется в самом провайдере. Провайдер для того и нужен, чтобы внутри себя делать сортировку, фильтрацию, а в конце добавлять all() и выбирать строки из БД.
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

Re: andFilterWhere для полей связанных таблиц

Сообщение zingeon »

zelenin писал(а):верно. all() добавляется в самом провайдере. Провайдер для того и нужен, чтобы внутри себя делать сортировку, фильтрацию, а в конце добавлять all() и выбирать строки из БД.
тогда подскажите, как такой результат запроса использовать с классом Pagination?
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

Re: andFilterWhere для полей связанных таблиц

Сообщение zingeon »

Roksalana писал(а):Используйте joinWith вместо with для этой таблицы, тогда можно будет фильтровать так, как вы делали в первом случаи

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

Questionnaire::find()
->joinWith("customer")
->with( "account",  "status", "creditProduct", "currentStatus")
->andFilterWhere(['like', 'customer.first_name', 'иван'])
не работает такой вариант, выдает ошибку:

Database Exception – yii\db\Exception

SQLSTATE[42P01]: Undefined table: 7 ERROR: missing FROM-clause entry for table "customer"
LINE 1: ...ionnaires"."customer_id" = "customers"."id" WHERE "customer"...
^
The SQL being executed was: SELECT COUNT(*) FROM "questionnaires" LEFT JOIN "customers" ON "questionnaires"."customer_id" = "customers"."id" WHERE "customer"."first_name" LIKE '%иван%'
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: andFilterWhere для полей связанных таблиц

Сообщение zelenin »

у вас таблица customers, а поле customer.first_name. Урок: называй все (модель и таблицу) в единственном числе, это общепризнанная практика.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: andFilterWhere для полей связанных таблиц

Сообщение zelenin »

и исправь with/joinWith как я указал joinWith(['...', '...']) - это нагляднее и однозначно.
zingeon
Сообщения: 16
Зарегистрирован: 2015.04.20, 18:21

Re: andFilterWhere для полей связанных таблиц

Сообщение zingeon »

zelenin писал(а):и исправь with/joinWith как я указал joinWith(['...', '...']) - это нагляднее и однозначно.
я пишу так:

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

->joinWith(['customer' => function ($query) {
                                        $query->andFilterWhere(['between', 'children_amount', 2, 6]);
  }]) 
и все действительно огонь. Спасибо!
Закрыто