web-dev-qa-db-fra.com

yii2 BaseActiveRecord findAll () conditions supérieures ou inférieures à

J'ai une table de base de données par pays (comme dans le guide ) que je teste yii2 application de développement. J'ai le champ population et je veux créer une méthode publique dans le modèle Country pour renvoyer tous les pays de limites de population spécifiques. c'est-à-dire renvoyer tous les pays de population entre x et y.

J'ai essayé ce qui suit:

// models/Country.php
....

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

}

Dans le CountryController:

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

Il retourne un tableau vide i, e Array ()

Maintenant, je dois savoir comment définir la condition de findAll pour qu'elle ressemble à la condition SQL ... Where population >= 20000 AND population <= 40000000 I.e Comment ajouter une comparaison à la condition en utilisant un tableau?!

Une autre question -ou facultative-, Pourquoi dans Country.php lors de l'appel de findAll comme suit:

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

    }

Il renvoie une erreur:

Méthode inconnue - yii\base\UnknownMethodException

Appel d'une méthode inconnue: app\controllers\CountryController :: findAll ()

En d'autres termes, pourquoi faut-il l'appeler statiquement?

12
SaidbakR

Utilisez le module de débogage pour voir la requête SQL générée.

Dans votre cas, ce sera:

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

Comme vous pouvez le voir, c'est définitivement faux.

Consultez la documentation pour findAll () , il ne convient pas à une telle condition. Utilisez à la place find().

1)

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

Notez que dans ce cas, les guillemets et les échappements ne seront pas appliqués.

2)

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

Modifiez également la déclaration de la méthode en static car elle ne dépend pas de l'instance d'objet.

Veuillez lire les sections this et this de la documentation officielle pour comprendre comment where une partie de la requête est construite.

Il est peut-être préférable de mettre cette méthode dans une classe de requête personnalisée. Vous pouvez en lire plus ici .

La réponse à votre question supplémentaire: vous ne devez pas appeler findAll() dans le contexte de l'objet car c'est une méthode statique par la conception du framework.

Vérifiez le yii\db\BaseActiveRecord:

public static function findAll($condition)
33
arogachev