aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib/active_model')
-rw-r--r--activemodel/lib/active_model/naming.rb2
-rw-r--r--activemodel/lib/active_model/type.rb2
-rw-r--r--activemodel/lib/active_model/type/immutable_string.rb29
-rw-r--r--activemodel/lib/active_model/type/string.rb25
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb23
5 files changed, 47 insertions, 34 deletions
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb
index de5fb27467..d86ef6224e 100644
--- a/activemodel/lib/active_model/naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -226,7 +226,7 @@ module ActiveModel
# (See ActiveModel::Name for more information).
#
# class Person
- # include ActiveModel::Model
+ # extend ActiveModel::Naming
# end
#
# Person.model_name.name # => "Person"
diff --git a/activemodel/lib/active_model/type.rb b/activemodel/lib/active_model/type.rb
index f8ca7d0512..bec851594f 100644
--- a/activemodel/lib/active_model/type.rb
+++ b/activemodel/lib/active_model/type.rb
@@ -9,6 +9,7 @@ require 'active_model/type/date_time'
require 'active_model/type/decimal'
require 'active_model/type/decimal_without_scale'
require 'active_model/type/float'
+require 'active_model/type/immutable_string'
require 'active_model/type/integer'
require 'active_model/type/string'
require 'active_model/type/text'
@@ -49,6 +50,7 @@ module ActiveModel
register(:date_time, Type::DateTime)
register(:decimal, Type::Decimal)
register(:float, Type::Float)
+ register(:immutable_string, Type::ImmutableString)
register(:integer, Type::Integer)
register(:string, Type::String)
register(:text, Type::Text)
diff --git a/activemodel/lib/active_model/type/immutable_string.rb b/activemodel/lib/active_model/type/immutable_string.rb
new file mode 100644
index 0000000000..20b8ca0cc4
--- /dev/null
+++ b/activemodel/lib/active_model/type/immutable_string.rb
@@ -0,0 +1,29 @@
+module ActiveModel
+ module Type
+ class ImmutableString < Value # :nodoc:
+ def type
+ :string
+ end
+
+ def serialize(value)
+ case value
+ when ::Numeric, ActiveSupport::Duration then value.to_s
+ when true then "t"
+ when false then "f"
+ else super
+ end
+ end
+
+ private
+
+ def cast_value(value)
+ result = case value
+ when true then "t"
+ when false then "f"
+ else value.to_s
+ end
+ result.freeze
+ end
+ end
+ end
+end
diff --git a/activemodel/lib/active_model/type/string.rb b/activemodel/lib/active_model/type/string.rb
index fd1630c751..8a91410998 100644
--- a/activemodel/lib/active_model/type/string.rb
+++ b/activemodel/lib/active_model/type/string.rb
@@ -1,35 +1,18 @@
+require "active_model/type/immutable_string"
+
module ActiveModel
module Type
- class String < Value # :nodoc:
- def type
- :string
- end
-
+ class String < ImmutableString # :nodoc:
def changed_in_place?(raw_old_value, new_value)
if new_value.is_a?(::String)
raw_old_value != new_value
end
end
- def serialize(value)
- case value
- when ::Numeric, ActiveSupport::Duration then value.to_s
- when ::String then ::String.new(value)
- when true then "t"
- when false then "f"
- else super
- end
- end
-
private
def cast_value(value)
- case value
- when true then "t"
- when false then "f"
- # String.new is slightly faster than dup
- else ::String.new(value.to_s)
- end
+ ::String.new(super)
end
end
end
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index 4ba4e3e8f7..9c1e8b4ba7 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -20,7 +20,7 @@ module ActiveModel
def validate_each(record, attr_name, value)
before_type_cast = :"#{attr_name}_before_type_cast"
- raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast)
+ raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast) && record.send(before_type_cast) != value
raw_value ||= value
if record_attribute_changed_in_place?(record, attr_name)
@@ -29,16 +29,14 @@ module ActiveModel
return if options[:allow_nil] && raw_value.nil?
- unless value = parse_raw_value_as_a_number(raw_value)
+ unless is_number?(raw_value)
record.errors.add(attr_name, :not_a_number, filtered_options(raw_value))
return
end
- if allow_only_integer?(record)
- unless value = parse_raw_value_as_an_integer(raw_value)
- record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
- return
- end
+ if allow_only_integer?(record) && !is_integer?(raw_value)
+ record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
+ return
end
options.slice(*CHECKS.keys).each do |option, option_value|
@@ -64,14 +62,15 @@ module ActiveModel
protected
- def parse_raw_value_as_a_number(raw_value)
- Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
+ def is_number?(raw_value)
+ parsed_value = Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
+ !parsed_value.nil?
rescue ArgumentError, TypeError
- nil
+ false
end
- def parse_raw_value_as_an_integer(raw_value)
- raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\z/
+ def is_integer?(raw_value)
+ /\A[+-]?\d+\z/ === raw_value.to_s
end
def filtered_options(value)