From 39a1751d52f315254d03af52c530e688eb35c28a Mon Sep 17 00:00:00 2001 From: Michael Schuerig Date: Sun, 4 May 2008 12:46:46 +0200 Subject: [PATCH] Added a :level option, defaulting to :error, to validations. When a validation fails, it adds its failure notice to the Errors object indicated by the level. At this time only the level :error is supported. --- activerecord/lib/active_record/validations.rb | 46 ++++++++++++++++--------- 1 files changed, 30 insertions(+), 16 deletions(-) diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 50db327..1e6f75c 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -391,11 +391,12 @@ module ActiveRecord def validates_confirmation_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) attr_accessor(*(attr_names.map { |n| "#{n}_confirmation" })) validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation") + record.send(level).add(attr_name, configuration[:message]) unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation") end end @@ -425,6 +426,7 @@ module ActiveRecord def validates_acceptance_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) db_cols = begin column_names @@ -435,7 +437,7 @@ module ActiveRecord attr_accessor(*names) validates_each(attr_names,configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless value == configuration[:accept] + record.send(level).add(attr_name, configuration[:message]) unless value == configuration[:accept] end end @@ -464,11 +466,12 @@ module ActiveRecord def validates_presence_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:blank], :on => :save } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) # can't use validates_each here, because it cannot cope with nonexistent attributes, # while errors.add_on_empty can send(validation_method(configuration[:on]), configuration) do |record| - record.errors.add_on_blank(attr_names, configuration[:message]) + record.send(level).add_on_blank(attr_names, configuration[:message]) end end @@ -513,6 +516,8 @@ module ActiveRecord }.merge(DEFAULT_VALIDATION_OPTIONS) options.update(attrs.extract_options!.symbolize_keys) + level = validation_level(options) + # Ensure that one and only one range option is specified. range_options = ALL_RANGE_OPTIONS & options.keys case range_options.size @@ -538,9 +543,9 @@ module ActiveRecord validates_each(attrs, options) do |record, attr, value| value = value.split(//) if value.kind_of?(String) if value.nil? or value.size < option_value.begin - record.errors.add(attr, too_short) + record.send(level).add(attr, too_short) elsif value.size > option_value.end - record.errors.add(attr, too_long) + record.send(level).add(attr, too_long) end end when :is, :minimum, :maximum @@ -554,7 +559,7 @@ module ActiveRecord validates_each(attrs, options) do |record, attr, value| value = value.split(//) if value.kind_of?(String) - record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value] + record.send(level).add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value] end end end @@ -598,6 +603,7 @@ module ActiveRecord def validates_uniqueness_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken], :case_sensitive => true } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) validates_each(attr_names,configuration) do |record, attr_name, value| # The check for an existing value should be run from a class that @@ -656,7 +662,7 @@ module ActiveRecord found = results.any? { |a| a[attr_name.to_s] == value } end - record.errors.add(attr_name, configuration[:message]) if found + record.send(level).add(attr_name, configuration[:message]) if found end end end @@ -688,11 +694,12 @@ module ActiveRecord def validates_format_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp) validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless value.to_s =~ configuration[:with] + record.send(level).add(attr_name, configuration[:message]) unless value.to_s =~ configuration[:with] end end @@ -718,13 +725,14 @@ module ActiveRecord def validates_inclusion_of(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) enum = configuration[:in] || configuration[:within] raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?") validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message] % value) unless enum.include?(value) + record.send(level).add(attr_name, configuration[:message] % value) unless enum.include?(value) end end @@ -752,11 +760,12 @@ module ActiveRecord configuration.update(attr_names.extract_options!) enum = configuration[:in] || configuration[:within] + level = validation_level(configuration) raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?") validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message] % value) if enum.include?(value) + record.send(level).add(attr_name, configuration[:message] % value) if enum.include?(value) end end @@ -794,9 +803,10 @@ module ActiveRecord def validates_associated(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save } configuration.update(attr_names.extract_options!) + level = validation_level(configuration) validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless + record.send(level).add(attr_name, configuration[:message]) unless (value.is_a?(Array) ? value : [value]).inject(true) { |v, r| (r.nil? || r.valid?) && v } end end @@ -830,7 +840,7 @@ module ActiveRecord def validates_numericality_of(*attr_names) configuration = { :on => :save, :only_integer => false, :allow_nil => false } configuration.update(attr_names.extract_options!) - + level = validation_level(configuration) numericality_options = ALL_NUMERICALITY_CHECKS.keys & configuration.keys @@ -845,7 +855,7 @@ module ActiveRecord if configuration[:only_integer] unless raw_value.to_s =~ /\A[+-]?\d+\Z/ - record.errors.add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[:not_a_number]) + record.send(level).add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[:not_a_number]) next end raw_value = raw_value.to_i @@ -853,7 +863,7 @@ module ActiveRecord begin raw_value = Kernel.Float(raw_value.to_s) rescue ArgumentError, TypeError - record.errors.add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[:not_a_number]) + record.send(level).add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[:not_a_number]) next end end @@ -861,11 +871,11 @@ module ActiveRecord numericality_options.each do |option| case option when :odd, :even - record.errors.add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[option]) unless raw_value.to_i.method(ALL_NUMERICALITY_CHECKS[option])[] + record.send(level).add(attr_name, configuration[:message] || ActiveRecord::Errors.default_error_messages[option]) unless raw_value.to_i.method(ALL_NUMERICALITY_CHECKS[option])[] else message = configuration[:message] || ActiveRecord::Errors.default_error_messages[option] message = message % configuration[option] if configuration[option] - record.errors.add(attr_name, message) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]] + record.send(level).add(attr_name, message) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]] end end end @@ -892,6 +902,10 @@ module ActiveRecord when :update then :validate_on_update end end + + def validation_level(configuration, default_level = :error) + (configuration[:level] || default_level).to_s.pluralize.to_sym + end end # The validation process on save can be skipped by passing false. The regular Base#save method is -- 1.5.5.1