Cet épisode aborde les conditions de la méthode find
. Ci-dessous, quelques lignes de script/console
, affiché avec le SQL qu'elles génèrent.
Task.find(:all, :conditions => ["completed = ? AND priority = ?", false, 2])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority = 2)
Chercher toutes les tâches incomplètes avec une priorité de 2.
L'exemple ci-dessus fonctionne mais si nous cherchons les tâches qui ont une priorité qui vaut nil
?
Task.find(:all, :conditions => ["completed = ? AND priority = ?", false, nil])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority = NULL)
Rechercher des valeurs nulles génère du SQL incorrect.
Le SQL généré ci-dessus est incorrect. Quand on recherche des valeurs nulles la syntaxe correcte serait priority IS NULL
, pas priority = NULL
. De la même façon, si nous recherchons plus d'une priorité en utilisant un tableau ou un ensemble défini nous devons changer la chaine de la méthode find
pour utiliser IN
plutôt que =
, et mettre des parenthèses autour du deuxième point d'interrogation pour s'assurer que le SQL généré soit correct.
Task.find(:all, :conditions => ["completed = ? AND priority IN (?)", false, [1,3]])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority IN (1,3))
Depuis Rails 1.2, il y a une meilleure façon de passer des conditions : en utilisant un hash. Utiliser un hash de conditions assure que Rails utilise les conditions correctes en interrogeant la base de données.
Task.find(:all, :conditions => { :completed => false, priority => [1,3] }
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority IN (1,3)
Utilisation d'un hash de conditions avec un tableau comme paramètre.
Task.find(:all, :conditions => {:completed => false, priority => 2..4})
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 2 AND 4 AND "tasks"."completed" = 'f')
Donner un ensemble de chiffres et BETWEEN
sera utilisé dans le SQL.
Utilisation avec des finds dynamiques
Dans l'épisode 2, nous utilisions des méthodes find_by
dynamiques. Elles peuvent aussi prendre des arguments nil
, array
ou des espaces de nombres.
Task.find_by_priority(1..5)
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 1 AND 5) LIMIT 1
En utilisant un hash de conditions, nous nous assurons que Rails génère le SQL correctement quelques soient les arguments qu'on lui donne.