http://sishen.lifegoo.com/?p=42
I don’t know whether there exists a builtin validation that can check
the
number range. I think the requirement is normal, but indeed, i can’t
find
it. So i wrote a custome validation: validates_number_range, whose
prototype is validates_length_of. If there already exists one, pls tell
me,
The code is below, welcome to give me any advice on my blog. And also,
more
details information on the blog,
module ActiveRecord
module Validations
module ClassMethods
def validates_number_range(*attrs)
validates_numericality_of attrs.first
options = {
:too_big => “is too big (maximum is %d)”,
:too_small => “is too small (minimum is %d)”,
:wrong_number => “is the wrong number (should be %d)”
}.merge(DEFAULT_VALIDATION_OPTIONS)
options.update(attrs.pop.symbolize_keys) if
attrs.last.is_a?(Hash)
# Ensure that one and only one range option is specified.
range_options = ALL_RANGE_OPTIONS & options.keys
case range_options.size
when 0
raise ArgumentError, 'Range unspecified. Specify the
:within,
:maximum, :minimum, or :is option.’
when 1
# Valid number of options; do nothing.
else
raise ArgumentError, ‘Too many range options specified.
Choose
only one.’
end
# Get range option and value.
option = range_options.first
option_value = options[range_options.first]
case option
when :within, :in
raise ArgumentError, ":#{option} must be a Range" unless
option_value.is_a?(Range)
too_small = options[:too_small] % option_value.begin
too_big = options[:too_big] % option_value.end
validates_each(attrs, options) do |record, attr, value|
if value.nil? or value < option_value.begin
record.errors.add(attr, too_small)
elsif value > option_value.end
record.errors.add(attr, too_big)
end
end
when :is, :minimum, :maximum
raise ArgumentError, ":#{option} must be a nonnegative
Integer"
unless option_value.is_a?(Integer) and option_value >= 0
# Declare different validations per option.
validity_checks = { :is => "==", :minimum => ">=", :maximum =>
“<=” }
message_options = { :is => :wrong_number, :minimum =>
:too_small,
:maximum => :too_big }
message = (options[:message] ||
options[message_options[option]])
% option_value
validates_each(attrs, options) do |record, attr, value|
record.errors.add(attr, message) unless !value.nil? and
value.method(validity_checks[option])[option_value]
end
end
end
end
end
end