Donnez de petits noms à vos requêtes SQL avec Rails 2.1
Je ne sais pas pour vous, mais chaque fois qu’une nouveauté arrive dans Ruby on Rails, je me dis : “impossible de faire mieux que ce qui existe déjà”. Et chaque fois, ils trouvent le moyen de m’impressionner.
Cette fois, Ryan Daigle (en anglais) parle de la nouvelle fonction named_scope dans son article “Nouveautés d’Edge Rails : les fonctions de Has Finder (source d’origine indisponible)” (en anglais).
Elle permet, en substance, de définir des méthodes sur vos objets ActiveRecord pour simplifier les futures requêtes. Si vous n’avez pas encore pris le train Rails en marche, imaginez simplement un objet ActiveRecord comme une abstraction d’une table de base de données : ses champs deviennent des propriétés et les requêtes SQL sont facilitées. C’est depuis longtemps un acquis dans la communauté Rails.
Ce qu’ajoute named_scope, c’est un moyen de définir des requêtes sous forme de méthodes. Regardons l’exemple de Ryan pour en mesurer la puissance :
class User < ActiveRecord::Base
named_scope :active, :conditions => {:active => true}
named_scope :inactive, :conditions => {:active => false}
named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
end
# Standard usage
User.active # same as User.find(:all, :conditions => {:active => true})
User.inactive # same as User.find(:all, :conditions => {:active => false})
User.recent # same as User.find(:all, :conditions => ['created_at > ?', 1.week.ago])
# They're nest-able too!
User.active.recent
N’est-ce pas une excellente façon de construire des requêtes simples ou plus complexes ? Voici quelques avantages que j’y vois :
- Une meilleure lisibilité et une meilleure maintenabilité : les requêtes sont séparées du code.
- La sécurité, puisqu’on peut examiner rapidement tous les modèles pour repérer d’éventuelles requêtes dangereuses.
- La simplicité : comment ne pas aimer la syntaxe
User.active.recentpour demander les utilisateurs actifs les plus récents !
Même si, une fois de plus, je n’imagine pas les têtes pensantes de Rails faire encore mieux, je serai assez prudent pour garder cette idée pour moi !