"andFilterWhere" работает правильно с "joinWith ()", но не с "with ()" в yii2 - PullRequest
1 голос
/ 09 апреля 2020

Я работаю в yii2.

В таблице employee и company сотрудника содержится company_id.

У меня правильно работает поиск по фильтру, если я использую joinWith()

  $query = Employee::find();
  $query->joinWith(['company']);

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


    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

  //and below is the filterwhere
 $query->andFilterWhere(['like', 'company.name', $this->company_id]);

Но проблема возникла, когда я выполняю запрос, используя with()

$query = Employee::find()->with(['company']);

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


    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

//when query contain with() then this filter is not working.
$query->andFilterWhere(['like', 'company.name', $this->company_id]);

Это выдает ошибку при использовании with()

Database Exception – yii\db\Exception
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'company.name' in 'where clause'
The SQL being executed was: SELECT COUNT(*) FROM `employee` WHERE `company`.`name` LIKE '%1%'

Вот отношение сотрудника с компанией:

public function getCompany(){
    return $this->hasOne(Company::className(),  ['id'=> 'company_id']);
}

Кто-нибудь может мне помочь или подсказать, как правильно фильтровать данные, используя with() в запросе? Спасибо.

1 Ответ

3 голосов
/ 10 апреля 2020

Вы не можете поменять методы joinWith() и with(), если вам нужно выполнить фильтрацию по столбцу из связанной таблицы. Это потому, что эти методы делают совершенно разные вещи.

Такие методы, как joinWith() и join(), фактически изменяют запрос, добавляя часть "JOIN" к запросу SQL. with in joinWith позволяет указать объединенную таблицу по определению отношения в модели. Стремительная загрузка в joinWith является только побочным эффектом, и вы даже можете отключить его, передав false в качестве второго параметра.

Когда вы выполните:

Employee::find()->joinWith(['company'])->all();

Запущенный запрос выглядит например:

SELECT * FROM employee LEFT JOIN company ON (...)

С другой стороны, метод with() не изменяет сам запрос. Это только заставляет нетерпеливо загружать связанные модели. На самом деле второй запрос используется для предварительной загрузки связанных записей. Когда вы делаете:

Employee::find()->with(['company'])->all();

На самом деле он выполняет запросы, подобные этим:

SELECT * FROM employee;

SELECT * FROM company WHERE id IN (...company ids selected in first query...);

Поэтому, когда вы пытаетесь сделать:

$query = Employee::find()
    ->with(['company'])
    ->andFilterWhere(['like', 'company.name', $this->company_id])
    ->all();

Сгенерированный запрос

SELECT * FROM employee WHERE company.name LIKE ...
...