diff options
author | Xavier Noria <fxn@hashref.com> | 2010-06-28 00:12:15 +0200 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2010-06-28 00:12:15 +0200 |
commit | 4329f8133fee8e4f3e558787f67de59f0c4a4dd1 (patch) | |
tree | 346ef7340d8348e50d119ca749a16c1654c20a08 /activemodel/lib | |
parent | c37f7d66e49ffe5ac2115cc30e5529fd1c2924a8 (diff) | |
parent | ebee77a28a7267d5f23a28ba23c1eb88a2d7d527 (diff) | |
download | rails-4329f8133fee8e4f3e558787f67de59f0c4a4dd1.tar.gz rails-4329f8133fee8e4f3e558787f67de59f0c4a4dd1.tar.bz2 rails-4329f8133fee8e4f3e558787f67de59f0c4a4dd1.zip |
Merge remote branch 'rails/master'
Diffstat (limited to 'activemodel/lib')
12 files changed, 81 insertions, 48 deletions
diff --git a/activemodel/lib/active_model/deprecated_error_methods.rb b/activemodel/lib/active_model/deprecated_error_methods.rb index dd8050c549..adc50773d9 100644 --- a/activemodel/lib/active_model/deprecated_error_methods.rb +++ b/activemodel/lib/active_model/deprecated_error_methods.rb @@ -16,7 +16,7 @@ module ActiveModel end def add_to_base(msg) - ActiveSupport::Deprecation.warn "Errors#add_to_base(msg) has been deprecated, use Errors#[:base] << msg instead" + ActiveSupport::Deprecation.warn "Errors#add_to_base(msg) has been deprecated, use Errors#add(:base, msg) instead" self[:base] << msg end diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 9efb683547..d42fc5291d 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -3,6 +3,7 @@ require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/hash/reverse_merge' require 'active_support/ordered_hash' module ActiveModel @@ -61,6 +62,8 @@ module ActiveModel class Errors < ActiveSupport::OrderedHash include DeprecatedErrorMethods + CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank] + # Pass in the instance of the object that is using the errors object. # # class Person @@ -162,15 +165,12 @@ module ActiveModel # # <error>name must be specified</error> # # </errors> def to_xml(options={}) - require 'builder' unless defined? ::Builder - options[:root] ||= "errors" - options[:indent] ||= 2 - options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent]) - - options[:builder].instruct! unless options.delete(:skip_instruct) - options[:builder].errors do |e| - to_a.each { |error| e.error(error) } - end + to_a.to_xml options.reverse_merge(:root => "errors", :skip_types => true) + end + + # Returns an array as JSON representation for this object. + def as_json(options=nil) + to_a end # Adds +message+ to the error messages on +attribute+, which will be returned on a call to @@ -182,25 +182,44 @@ module ActiveModel # If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. def add(attribute, message = nil, options = {}) message ||= :invalid - message = generate_message(attribute, message, options) if message.is_a?(Symbol) - message = message.call if message.is_a?(Proc) + + if message.is_a?(Symbol) + message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) + elsif message.is_a?(Proc) + message = message.call + end + self[attribute] << message end # Will add an error message to each of the attributes in +attributes+ that is empty. - def add_on_empty(attributes, custom_message = nil) + def add_on_empty(attributes, options = {}) + if options && !options.is_a?(Hash) + options = { :message => options } + ActiveSupport::Deprecation.warn \ + "ActiveModel::Errors#add_on_empty(attributes, custom_message) has been deprecated.\n" + + "Instead of passing a custom_message pass an options Hash { :message => custom_message }." + end + [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) is_empty = value.respond_to?(:empty?) ? value.empty? : false - add(attribute, :empty, :default => custom_message) unless !value.nil? && !is_empty + add(attribute, :empty, options) if value.nil? || is_empty end end # Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?). - def add_on_blank(attributes, custom_message = nil) + def add_on_blank(attributes, options = {}) + if options && !options.is_a?(Hash) + options = { :message => options } + ActiveSupport::Deprecation.warn \ + "ActiveModel::Errors#add_on_blank(attributes, custom_message) has been deprecated.\n" + + "Instead of passing a custom_message pass an options Hash { :message => custom_message }." + end + [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) - add(attribute, :blank, :default => custom_message) if value.blank? + add(attribute, :blank, options) if value.blank? end end @@ -262,24 +281,31 @@ module ActiveModel # <li><tt>errors.attributes.title.blank</tt></li> # <li><tt>errors.messages.blank</tt></li> # </ol> - def generate_message(attribute, message = :invalid, options = {}) - message, options[:default] = options[:default], message if options[:default].is_a?(Symbol) + def generate_message(attribute, type = :invalid, options = {}) + type = options.delete(:message) if options[:message].is_a?(Symbol) + + if options[:default] + ActiveSupport::Deprecation.warn \ + "ActiveModel::Errors#generate_message(attributes, custom_message) has been deprecated.\n" + + "Use ActiveModel::Errors#generate_message(attributes, :message => 'your message') instead." + options[:message] = options.delete(:default) + end defaults = @base.class.lookup_ancestors.map do |klass| - [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{message}", - :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{message}" ] + [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{type}", + :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{type}" ] end - defaults << options.delete(:default) - defaults << :"#{@base.class.i18n_scope}.errors.messages.#{message}" - defaults << :"errors.attributes.#{attribute}.#{message}" - defaults << :"errors.messages.#{message}" + defaults << options.delete(:message) + defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" + defaults << :"errors.attributes.#{attribute}.#{type}" + defaults << :"errors.messages.#{type}" defaults.compact! defaults.flatten! key = defaults.shift - value = @base.send(:read_attribute_for_validation, attribute) + value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) options = { :default => defaults, diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index 14f8bf72dc..d0f36ce3b1 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -2,7 +2,6 @@ require 'singleton' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/module/aliasing' require 'active_support/core_ext/string/inflections' -require 'active_support/core_ext/string/conversions' module ActiveModel module Observing diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb index 77c401e0cc..99b8966def 100644 --- a/activemodel/lib/active_model/validations/acceptance.rb +++ b/activemodel/lib/active_model/validations/acceptance.rb @@ -9,10 +9,10 @@ module ActiveModel def validate_each(record, attribute, value) unless value == options[:accept] - record.errors.add(attribute, :accepted, :default => options[:message]) + record.errors.add(attribute, :accepted, options.except(:accept, :allow_nil)) end end - + def setup(klass) # Note: instance_methods.map(&:to_s) is important for 1.9 compatibility # as instance_methods returns symbols unlike 1.8 which returns strings. diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb index 5e13db7491..3a80893866 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -6,11 +6,11 @@ module ActiveModel def validate_each(record, attribute, value) confirmed = record.send(:"#{attribute}_confirmation") return if confirmed.nil? || value == confirmed - record.errors.add(attribute, :confirmation, :default => options[:message]) + record.errors.add(attribute, :confirmation, options) end - + def setup(klass) - klass.send(:attr_accessor, *attributes.map { |attribute| :"#{attribute}_confirmation" }) + klass.send(:attr_accessor, *attributes.map { |attribute| :"#{attribute}_confirmation" }) end end diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb index 599623368f..4138892786 100644 --- a/activemodel/lib/active_model/validations/exclusion.rb +++ b/activemodel/lib/active_model/validations/exclusion.rb @@ -9,8 +9,9 @@ module ActiveModel end def validate_each(record, attribute, value) - return unless options[:in].include?(value) - record.errors.add(attribute, :exclusion, :default => options[:message], :value => value) + if options[:in].include?(value) + record.errors.add(attribute, :exclusion, options.except(:in).merge!(:value => value)) + end end end diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb index 3b57d4fd77..104f403492 100644 --- a/activemodel/lib/active_model/validations/format.rb +++ b/activemodel/lib/active_model/validations/format.rb @@ -5,12 +5,12 @@ module ActiveModel class FormatValidator < EachValidator def validate_each(record, attribute, value) if options[:with] && value.to_s !~ options[:with] - record.errors.add(attribute, :invalid, :default => options[:message], :value => value) + record.errors.add(attribute, :invalid, options.except(:with).merge!(:value => value)) elsif options[:without] && value.to_s =~ options[:without] - record.errors.add(attribute, :invalid, :default => options[:message], :value => value) + record.errors.add(attribute, :invalid, options.except(:without).merge!(:value => value)) end end - + def check_validity! unless options.include?(:with) ^ options.include?(:without) # ^ == xor, or "exclusive or" raise ArgumentError, "Either :with or :without must be supplied (but not both)" diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb index e9940dbbf0..049b093618 100644 --- a/activemodel/lib/active_model/validations/inclusion.rb +++ b/activemodel/lib/active_model/validations/inclusion.rb @@ -9,8 +9,9 @@ module ActiveModel end def validate_each(record, attribute, value) - return if options[:in].include?(value) - record.errors.add(attribute, :inclusion, :default => options[:message], :value => value) + unless options[:in].include?(value) + record.errors.add(attribute, :inclusion, options.except(:in).merge!(:value => value)) + end end end diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index dc191d3150..c8a77ad666 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -7,6 +7,7 @@ module ActiveModel CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze DEFAULT_TOKENIZER = lambda { |value| value.split(//) } + RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long] def initialize(options) if range = (options.delete(:in) || options.delete(:within)) @@ -39,7 +40,8 @@ module ActiveModel CHECKS.each do |key, validity_check| next unless check_value = options[key] - custom_message = options[:message] || options[MESSAGES[key]] + default_message = options[MESSAGES[key]] + options[:message] ||= default_message if default_message valid_value = if key == :maximum value.nil? || value.size.send(validity_check, check_value) @@ -48,7 +50,9 @@ module ActiveModel end next if valid_value - record.errors.add(attribute, MESSAGES[key], :default => custom_message, :count => check_value) + + record.errors.add(attribute, MESSAGES[key], + options.except(*RESERVED_OPTIONS).merge!(:count => check_value)) end end end diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index c2e7223939..b6aff7aa6b 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -7,6 +7,8 @@ module ActiveModel :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=, :odd => :odd?, :even => :even? }.freeze + RESERVED_OPTIONS = CHECKS.keys + [:only_integer] + def initialize(options) super(options.reverse_merge(:only_integer => false, :allow_nil => false)) end @@ -28,13 +30,13 @@ module ActiveModel return if options[:allow_nil] && raw_value.nil? unless value = parse_raw_value_as_a_number(raw_value) - record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => options[:message]) + record.errors.add(attr_name, :not_a_number, filtered_options(raw_value)) return end if options[:only_integer] unless value = parse_raw_value_as_an_integer(raw_value) - record.errors.add(attr_name, :not_an_integer, :value => raw_value, :default => options[:message]) + record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value)) return end end @@ -43,14 +45,14 @@ module ActiveModel case option when :odd, :even unless value.to_i.send(CHECKS[option]) - record.errors.add(attr_name, option, :value => value, :default => options[:message]) + record.errors.add(attr_name, option, filtered_options(value)) end else option_value = option_value.call(record) if option_value.is_a?(Proc) option_value = record.send(option_value) if option_value.is_a?(Symbol) unless value.send(CHECKS[option], option_value) - record.errors.add(attr_name, option, :default => options[:message], :value => value, :count => option_value) + record.errors.add(attr_name, option, filtered_options(value).merge(:count => option_value)) end end end @@ -75,6 +77,9 @@ module ActiveModel raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/ end + def filtered_options(value) + options.except(*RESERVED_OPTIONS).merge!(:value => value) + end end module HelperMethods diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb index e36bee8115..28c4640b17 100644 --- a/activemodel/lib/active_model/validations/presence.rb +++ b/activemodel/lib/active_model/validations/presence.rb @@ -6,7 +6,7 @@ module ActiveModel module Validations class PresenceValidator < EachValidator def validate(record) - record.errors.add_on_blank(attributes, options[:message]) + record.errors.add_on_blank(attributes, options) end end diff --git a/activemodel/lib/active_model/validations/with.rb b/activemodel/lib/active_model/validations/with.rb index a2e870d714..200efd4eb5 100644 --- a/activemodel/lib/active_model/validations/with.rb +++ b/activemodel/lib/active_model/validations/with.rb @@ -1,6 +1,4 @@ module ActiveModel - - # == Active Model validates_with method module Validations module HelperMethods private @@ -11,7 +9,6 @@ module ActiveModel end module ClassMethods - # Passes the record off to the class or classes specified and allows them # to add errors based on more complex conditions. # |