aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/validations/length.rb
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-01-08 08:34:44 +0100
committerJosé Valim <jose.valim@gmail.com>2010-01-08 21:36:04 +0100
commitfa14d6d51ed89acde66b49e8d3a6423396c3d553 (patch)
treebc7c7804f70c72d51580a44d5214610fe818a15a /activemodel/lib/active_model/validations/length.rb
parent188d52165bc9184a143a468ee951981d159dbea6 (diff)
downloadrails-fa14d6d51ed89acde66b49e8d3a6423396c3d553.tar.gz
rails-fa14d6d51ed89acde66b49e8d3a6423396c3d553.tar.bz2
rails-fa14d6d51ed89acde66b49e8d3a6423396c3d553.zip
Compile length validator options still at the class level, so whenever the validator is called, it just needs to check for :maximum, :minimum and :is values.
Diffstat (limited to 'activemodel/lib/active_model/validations/length.rb')
-rw-r--r--activemodel/lib/active_model/validations/length.rb66
1 files changed, 24 insertions, 42 deletions
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb
index f41ce34328..871f589af9 100644
--- a/activemodel/lib/active_model/validations/length.rb
+++ b/activemodel/lib/active_model/validations/length.rb
@@ -1,36 +1,43 @@
module ActiveModel
module Validations
class LengthValidator < EachValidator
- OPTIONS = [ :is, :within, :in, :minimum, :maximum ].freeze
MESSAGES = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }.freeze
CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
- attr_reader :type
def initialize(options)
- @type = (OPTIONS & options.keys).first
+ if range = (options.delete(:in) || options.delete(:within))
+ raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
+ options[:minimum], options[:maximum] = range.begin, range.end
+ options[:maximum] -= 1 if range.exclude_end?
+ end
+
super(options.reverse_merge(:tokenizer => DEFAULT_TOKENIZER))
end
def check_validity!
- ensure_one_range_option!
- ensure_argument_types!
+ keys = CHECKS.keys & options.keys
+
+ if keys.empty?
+ raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
+ end
+
+ keys.each do |key|
+ value = options[key]
+
+ unless value.is_a?(Integer) && value >= 0
+ raise ArgumentError, ":#{key} must be a nonnegative Integer"
+ end
+ end
end
def validate_each(record, attribute, value)
- checks = options.slice(:minimum, :maximum, :is)
- value = options[:tokenizer].call(value) if value.kind_of?(String)
-
- if [:within, :in].include?(type)
- range = options[type]
- checks[:minimum], checks[:maximum] = range.begin, range.end
- checks[:maximum] -= 1 if range.exclude_end?
- end
+ value = options[:tokenizer].call(value) if value.kind_of?(String)
- checks.each do |key, check_value|
+ CHECKS.each do |key, validity_check|
+ next unless check_value = options[key]
custom_message = options[:message] || options[MESSAGES[key]]
- validity_check = CHECKS[key]
valid_value = if key == :maximum
value.nil? || value.size.send(validity_check, check_value)
@@ -38,33 +45,8 @@ module ActiveModel
value && value.size.send(validity_check, check_value)
end
- record.errors.add(attribute, MESSAGES[key], :default => custom_message, :count => check_value) unless valid_value
- end
- end
-
- protected
-
- def ensure_one_range_option! #:nodoc:
- range_options = 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
- end
-
- def ensure_argument_types! #:nodoc:
- value = options[type]
-
- case type
- when :within, :in
- raise ArgumentError, ":#{type} must be a Range" unless value.is_a?(Range)
- when :is, :minimum, :maximum
- raise ArgumentError, ":#{type} must be a nonnegative Integer" unless value.is_a?(Integer) && value >= 0
+ next if valid_value
+ record.errors.add(attribute, MESSAGES[key], :default => custom_message, :count => check_value)
end
end
end