Yii2 BaseActiveRecord findAll() условия больше или меньше

У меня есть таблица базы данных в стране (например, в руководстве), что я тестирую yii2 приложение для разработки. У меня есть поле population, и я хочу создать общедоступный метод в модели Country, чтобы вернуть все страны конкретных пределов населения. верните все страны с населением между x и y.

Я попробовал следующее:

// models/Country.php
....

public function getPopulationBetween($lower, $upper)
{
  return Country::findAll(['population' => [">=".$lower, "<=".$upper]]);

}

В CountryController:

public function actionGetBetween($lower, $upper)
    {
      print_r(Country::getPopulationBetween($lower, $upper));
    }

Он возвращает пустой массив i, e Array ()

Теперь мне нужно знать, как установить условие findAll как условие SQL ... Where population >= 20000 AND population <= 40000000 i.e Как добавить сравнение с условием с использованием массива?!

Другая сторона - или необязательно - вопрос: почему в Country.php при вызове findAll выглядит следующим образом:

public function getPopulationBetween($lower, $upper)
    {
      return $this->findAll(['population' => [">=".$lower, "<=".$upper]]);

    }

Он возвращает ошибку:

Неизвестный метод - yii\base\UnknownMethodException

Вызов неизвестного метода: app\controllers\CountryController:: findAll()

Иными словами, почему он должен статически ставить?

Ответ 1

Используйте модуль отладки, чтобы просмотреть сгенерированный SQL-запрос.

В вашем случае это будет:

SELECT * FROM `countries` WHERE `population` IN ('>=20000', '<=40000000')

Как вы видите, это определенно неправильно.

Проверьте документацию findAll(), она не подходит для такого условия. Вместо этого используйте find().

1)

public static function getPopulationBetween($lower, $upper)
{
    return Country::find()
        ->where(['and', "population>=$lower", "id<=$upper"])
        ->all();
}

Обратите внимание, что в этом случае цитирование и экранирование не будут применяться.

2)

public static function getPopulationBetween($lower, $upper)
{
    return Country::find()
        ->where(['>=', 'population', $lower])
        ->andWhere(['<=', 'population', $upper])
        ->all();
}

Также измените объявление метода на static, так как оно не зависит от экземпляра объекта.

Пожалуйста, прочтите этот и этот раздел официальной документации чтобы понять, как построена часть запроса where.

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

Ответ на ваш дополнительный вопрос: вы не должны вызывать findAll() в контексте объекта, потому что он статический метод по дизайну структуры.

Проверьте yii\db\BaseActiveRecord:

public static function findAll($condition)