Даже не взглянув на ваш код, вот мое мнение о реализации методов класса валидации:
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
Предполагается, что ActiveSupport существует, как и в среде Rails. Возможно, вы захотите расширить его, чтобы разрешить несколько ошибок для каждого атрибута, с instance.errors[attribute] << "the message"
, но я пропустил такие неясности, чтобы сделать этот короткий образец как можно более простым.
Вот краткий пример использования:
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