2009-04-22 4 views
1

Je travaille sur un framework de test pour le logiciel que mon entreprise écrit. Notre produit est basé sur le Web et après avoir exécuté une demande RESTful je veux traiter les résultats. Je veux être capable d'avoir des validations de type activationecord dans chaque classe de commande afin qu'après son exécution, les résultats soient automatiquement testés par rapport à toutes les "validations". Cependant, je ne suis pas sûr de savoir comment faire cela. Mon code ressemble à ceci (simplifié pour montrer les parties importantes).Comment créer des validations de style activerecord en dehors de activeecord?

class CodesecureCommand 
    def execute 
    result = RestClient.post("http://#{codesecure.host_name_port}#{path}", post_data) 

    return parse(result) #parse simple returns a Hpricot document 
    end 
end 

class RunScan < CodesecureCommand 

    #What I have now 
    #I have to override the execute function so that it calls the local success method 
    #to see if it failed or not. 
    def execute() 
    result = super() 

    if success(result) 
     return true 
    else 
    end 

    end 

    def success(result) 
    result.search('div.transaction-message') do |message| 
     if message.innerHTML.scan(/Configure abuse setting for domain users successfully\./).length == 1 
     return true 
     end 
    end 
    end 



    #What I would like is to be able to call execute (without having to override it). 
    #then after it runs it calls back to this class to check 

    #if the regex matches the command was successful and returns true 
    test_success /regex/ 

    #if test_success fails then these are called 
    #the idea being that I can use the regex to identify errors that happened then 
    #report them to the user 
    identify_error /regex/, "message" 
    identify_error /regex/, "message" 
    end 
end 

Ce que je veux est que, après la méthode d'exécution est appelée test_success et identify_error sont appelés automatiquement comme les validations dans activerecord. Quelqu'un peut-il me dire comment faire cela? Merci

Répondre

3

Sans avoir regardé beaucoup votre code, voici mon avis sur la mise en œuvre des méthodes de classe de validation:

module Validations 
    def self.included(base) 
    base.extend ClassMethods 
    end 

    def validate 
    errors.clear 
    self.class.validations.each {|validation| validation.call(self) } 
    end 

    def valid? 
    validate 
    errors.blank? 
    end 

    def errors 
    @errors ||= {} 
    end 

    module ClassMethods 
    def validations 
     @validations ||= [] 
    end 

    def validates_presence_of(*attributes) 
     validates_attributes(*attributes) do |instance, attribute, value, options| 
     instance.errors[attribute] = "cant't be blank" if value.blank? 
     end 
    end 

    def validates_format_of(*attributes) 
     validates_attributes(*attributes) do |instance, attribute, value, options| 
     instance.errors[attribute] = "is invalid" unless value =~ options[:with] 
     end 
    end 

    def validates_attributes(*attributes, &proc) 
     options = attributes.extract_options! 

     validations << Proc.new { |instance| 
     attributes.each {|attribute| 
      proc.call(instance, attribute, instance.__send__(attribute), options) 
     } 
     } 
    end 
    end 
end 

Il suppose que ActiveSupport est autour, ce qui est dans un environnement Rails. Vous pourriez vouloir l'étendre pour permettre plusieurs erreurs par attribut, avec instance.errors[attribute] << "the message", mais j'ai omis des obscurités comme celle-ci afin de garder cet échantillon court aussi simple que possible.

Voici un court exemple d'utilisation:

class MyClass 
    include Validations 

    attr_accessor :foo 
    validates_presence_of :foo 
    validates_format_of :foo, :with => /^[a-z]+$/ 
end 

a = MyClass.new 
puts a.valid? 
# => false 

a.foo = "letters" 
puts a.valid? 
# => true 

a.foo = "Oh crap$(!)*#" 
puts a.valid? 
# => false 
+0

Merci pour la réponse c'est ce que je cherche merci. Une question, qu'est-ce que cela nécessite ActiveSupport? Merci. –

+0

Il utilise 'Hash # blank?' (Dans la méthode 'valid?'). Mais c'est à peu près tout, hein. Ne devrait pas être trop difficile de laisser tomber active_support. J'ai juste supposé qu'il était déjà là, parce que vous êtes dans le contexte des rails de toute façon. –

+0

Il utilise aussi Array # extract_options !, mais c'est assez simple pour dupliquer/extraire. –

2

Vous voulez Validatable: sudo gem install validatable

class Person 
    include Validatable 
    validates_presence_of :name 
    attr_accessor :name 
end 

En outre, Validatable n'a pas de dépendance à l'égard ActiveSupport.

+0

Je préfère cette réponse. Beaucoup plus sec et moins dépendant. –

Questions connexes