diff --git a/activemodel/lib/active_model/type/big_integer.rb b/activemodel/lib/active_model/type/big_integer.rb index ce173c8b1f69d..224cd62bc910e 100644 --- a/activemodel/lib/active_model/type/big_integer.rb +++ b/activemodel/lib/active_model/type/big_integer.rb @@ -23,32 +23,15 @@ module Type # All casting and serialization are performed in the same way as the # standard ActiveModel::Type::Integer type. class BigInteger < Integer - def serialize(value) # :nodoc: - case value - when ::Integer - # noop - when ::String - int = value.to_i - if int.zero? && value != "0" - return if non_numeric_string?(value) - end - value = int - else - value = super - end - - value - end - - def serialize_cast_value(value) # :nodoc: - value - end - def serializable?(value, &_) true end private + def ensure_within_range!(value) + # noop + end + def max_value ::Float::INFINITY end diff --git a/activemodel/lib/active_model/type/integer.rb b/activemodel/lib/active_model/type/integer.rb index b3c3f3eb3767c..613e643f60f99 100644 --- a/activemodel/lib/active_model/type/integer.rb +++ b/activemodel/lib/active_model/type/integer.rb @@ -77,18 +77,13 @@ def serialize(value) value = super end - if out_of_range?(value) - raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes" - end + ensure_within_range!(value) value end def serialize_cast_value(value) # :nodoc: - if out_of_range?(value) - raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes" - end - + ensure_within_range!(value) value end @@ -100,6 +95,13 @@ def serializable?(value) end private + + def ensure_within_range!(value) + return unless out_of_range?(value) + + raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes" + end + def out_of_range?(value) value && (@max <= value || @min > value) end diff --git a/bench_big_int.rb b/bench_big_int.rb new file mode 100644 index 0000000000000..cad164555c3fa --- /dev/null +++ b/bench_big_int.rb @@ -0,0 +1,17 @@ +require 'benchmark/ips' +require 'active_model' + +class TestModel + include ActiveModel::Model + include ActiveModel::Attributes + + attribute :number, :big_integer +end + +Benchmark.ips do |x| + model = TestModel.new + x.load! 'tmp/bigint_conversion_benchmark' + + x.report("big_integer") { model.number = BigDecimal("9223372036854775807") } + x.save! 'tmp/bigint_conversion_benchmark' +end