diff options
Diffstat (limited to 'activemodel/lib/active_model')
-rw-r--r-- | activemodel/lib/active_model/locale/en.yml | 1 | ||||
-rw-r--r-- | activemodel/lib/active_model/serializers/xml.rb | 35 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/numericality.rb | 29 |
3 files changed, 36 insertions, 29 deletions
diff --git a/activemodel/lib/active_model/locale/en.yml b/activemodel/lib/active_model/locale/en.yml index ea58021767..d05c04967c 100644 --- a/activemodel/lib/active_model/locale/en.yml +++ b/activemodel/lib/active_model/locale/en.yml @@ -17,6 +17,7 @@ en: too_short: "is too short (minimum is {{count}} characters)" wrong_length: "is the wrong length (should be {{count}} characters)" not_a_number: "is not a number" + not_an_integer: "must be an integer" greater_than: "must be greater than {{count}}" greater_than_or_equal_to: "must be greater than or equal to {{count}}" equal_to: "must be equal to {{count}}" diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index c226359ea7..ee3e0eab06 100644 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -1,6 +1,7 @@ require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/hash/conversions' +require 'active_support/core_ext/hash/slice' module ActiveModel module Serializers @@ -12,8 +13,10 @@ module ActiveModel class Attribute #:nodoc: attr_reader :name, :value, :type - def initialize(name, serializable) + def initialize(name, serializable, raw_value=nil) @name, @serializable = name, serializable + @raw_value = raw_value || @serializable.send(name) + @type = compute_type @value = compute_value end @@ -51,20 +54,17 @@ module ActiveModel protected def compute_type - value = @serializable.send(name) - type = Hash::XML_TYPE_NAMES[value.class.name] - type ||= :string if value.respond_to?(:to_str) + type = Hash::XML_TYPE_NAMES[@raw_value.class.name] + type ||= :string if @raw_value.respond_to?(:to_str) type ||= :yaml type end def compute_value - value = @serializable.send(name) - if formatter = Hash::XML_FORMATTING[type.to_s] - value ? formatter.call(value) : nil + @raw_value ? formatter.call(@raw_value) : nil else - value + @raw_value end end end @@ -72,7 +72,7 @@ module ActiveModel class MethodAttribute < Attribute #:nodoc: protected def compute_type - Hash::XML_TYPE_NAMES[@serializable.send(name).class.name] || :string + Hash::XML_TYPE_NAMES[@raw_value.class.name] || :string end end @@ -92,25 +92,24 @@ module ActiveModel # then because <tt>:except</tt> is set to a default value, the second # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if # <tt>:only</tt> is set, always delete <tt>:except</tt>. - def serializable_attribute_names - attribute_names = @serializable.attributes.keys.sort - + def serializable_attributes_hash + attributes = @serializable.attributes if options[:only].any? - attribute_names &= options[:only] + attributes.slice(*options[:only]) elsif options[:except].any? - attribute_names -= options[:except] + attributes.except(*options[:except]) + else + attributes end - - attribute_names end def serializable_attributes - serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) } + serializable_attributes_hash.map { |name, value| self.class::Attribute.new(name, @serializable, value) } end def serializable_method_attributes Array.wrap(options[:methods]).inject([]) do |methods, name| - methods << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s) + methods << self.class::MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s) methods end end diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index c6d84c5312..f974999bef 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -25,11 +25,18 @@ module ActiveModel return if options[:allow_nil] && raw_value.nil? - unless value = parse_raw_value(raw_value, options) + unless value = parse_raw_value_as_a_number(raw_value) record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => options[:message]) 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]) + return + end + end + options.slice(*CHECKS.keys).each do |option, option_value| case option when :odd, :even @@ -44,23 +51,23 @@ module ActiveModel record.errors.add(attr_name, option, :default => options[:message], :value => value, :count => option_value) end end - end + end end protected - def parse_raw_value(raw_value, options) - if options[:only_integer] - raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/ - else - begin - Kernel.Float(raw_value) - rescue ArgumentError, TypeError - nil - end + def parse_raw_value_as_a_number(raw_value) + begin + Kernel.Float(raw_value) + rescue ArgumentError, TypeError + nil end end + def parse_raw_value_as_an_integer(raw_value) + raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/ + end + end module ClassMethods |