Il y a une semaine de cela, Yehuda Katz a fait un article expliquant comment, dans Rails 3, obtenir les fonctionnalités de ActiveModel dans un modèle n’utilisant pas ActiveRecord.
Cela permet notamment de pouvoir utiliser les méthodes de sérialisation de Rails (export json et xml) et les validations.
C’est ce second point que je vais détailler aujourd’hui parce que c’est celui que je trouve le plus intéressant.
Notez que vous devez tout d’abord avoir le gem ActiveModel 3.0.pre installé sur votre machine.
Il est disponible sur gemcutter. Il vous suffit donc de faire
sudo gem install activemodel -v=3.0.pre -source=http://gemcutter.org
Prenons un fichier « test.rb », totalement intépendant de Rails. C’est juste du ruby pur et dur.
Mais parce qu’on y définit une classe, on souhaite pouvoir valider le format des données passées à celle-ci.
Voici donc le contenu de notre fichier test.rb
#
# Nous ne sommes pas dans Rails. Rubygems n'est donc pas inclus par défaut.
# ActiveModel ne l'est pas non plus. On doit donc les appeller.
#
require 'rubygems'
require 'active_model'
class Test
#
# On charge les validations de ActiveModel
#
include ActiveModel::Validations
#
# First Name et Last Name doivent absolument être présent
#
validates_presence_of :first_name, :last_name
#
# On définit les attributs First Name et Last Name
# Et on les initialise dans le constructeur
#
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name, @last_name = first_name, last_name
end
end
Vous noterez qu’il nous suffit d’inclure ActiveModel::Validations afin d’avoir accès à toutes ces méthodes de validations. Plutôt cool !
Dès à présent, nous pouvons tester si nos validations passent !
test = Test.new('Jane', 'Doe')
p test.valid?
Inévitablement, nos validations passent puisque nous vérifions simplement la présence de First Name et de Last Name et que sans ceux-ci, nous ne pourrions même pas instancier la classe.
Mais … Comme nous avons accès à toutes les méthodes de validation d’ActiveModel, nous pouvons créer notre propre validateur !
class Test
# ... Contenu de la classe définit précédemment dans l'article
#
# Et on ajoute une validation, empêchant quelqu'un de prendre le nom de famille "Doe"
#
validate do |t|
t.errors[:last_name] << 'You must know your own name. Doe is only for anonymous guys' if t.last_name == 'Doe'
end
end
Constatez le « validate » que nous avons ajouté et qui empêche quelqu’un de prendre le nom de famille « Doe ».
Maintenant, réexecutons notre code précédent. Notre méthode « valid? » nous retournera bien évidemment false.
Et si nous faisons un print de test.errors, nous constaterons que celui-ci est un Hash contenant chacune de nos erreurs.
#<OrderedHash {:last_name=>["You must know your own name. Doe is only for anonymous guys"]}>
N’oubliez pas bien évidemment de vérifier que la validation de vos données est correcte avant de sauvegarder celles-ci. Sans quoi l’utilité est particulièrement restreinte
Vous pouvez du coup, d’une manière similaire à ce que vous faites déjà avec vos modèles ActiveRecord, valider les données de tous vos objets Ruby en utilisant ActiveModel.
Par exemple si vous utilisez une solution NoSQL telle que CouchDB ou MongoDB.
Ou encore sur des modèles vous permettant de faire le lien avec une API distante (XML ou JSON par exemple).
Tous vos modèles utilisent ainsi la même API, celle d’ActiveModel. Ils sont tous homogènes et vous pouvez d’autant plus aisément manipuler ceux-ci.





