diff options
Diffstat (limited to 'activerecord/lib/active_record/type')
-rw-r--r-- | activerecord/lib/active_record/type/big_integer.rb | 13 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/boolean.rb | 13 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/decimal_without_scale.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/integer.rb | 25 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/string.rb | 8 |
5 files changed, 55 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/type/big_integer.rb b/activerecord/lib/active_record/type/big_integer.rb new file mode 100644 index 0000000000..0c72d8914f --- /dev/null +++ b/activerecord/lib/active_record/type/big_integer.rb @@ -0,0 +1,13 @@ +require 'active_record/type/integer' + +module ActiveRecord + module Type + class BigInteger < Integer # :nodoc: + private + + def max_value + ::Float::INFINITY + end + end + end +end diff --git a/activerecord/lib/active_record/type/boolean.rb b/activerecord/lib/active_record/type/boolean.rb index 06dd17ed28..978d16d524 100644 --- a/activerecord/lib/active_record/type/boolean.rb +++ b/activerecord/lib/active_record/type/boolean.rb @@ -10,8 +10,19 @@ module ActiveRecord def cast_value(value) if value == '' nil + elsif ConnectionAdapters::Column::TRUE_VALUES.include?(value) + true else - ConnectionAdapters::Column::TRUE_VALUES.include?(value) + if !ConnectionAdapters::Column::FALSE_VALUES.include?(value) + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You attempted to assign a value which is not explicitly `true` or `false` + to a boolean column. Currently this value casts to `false`. This will + change to match Ruby's semantics, and will cast to `true` in Rails 5. + If you would like to maintain the current behavior, you should + explicitly handle the values you would like cast to `false`. + MSG + end + false end end end diff --git a/activerecord/lib/active_record/type/decimal_without_scale.rb b/activerecord/lib/active_record/type/decimal_without_scale.rb index cabdcecdd7..ff5559e300 100644 --- a/activerecord/lib/active_record/type/decimal_without_scale.rb +++ b/activerecord/lib/active_record/type/decimal_without_scale.rb @@ -1,8 +1,8 @@ -require 'active_record/type/integer' +require 'active_record/type/big_integer' module ActiveRecord module Type - class DecimalWithoutScale < Integer # :nodoc: + class DecimalWithoutScale < BigInteger # :nodoc: def type :decimal end diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb index 08477d1303..d69e5b3f28 100644 --- a/activerecord/lib/active_record/type/integer.rb +++ b/activerecord/lib/active_record/type/integer.rb @@ -3,21 +3,44 @@ module ActiveRecord class Integer < Value # :nodoc: include Numeric + def initialize(*) + super + @range = -max_value...max_value + end + def type :integer end alias type_cast_for_database type_cast + protected + + attr_reader :range + private def cast_value(value) case value when true then 1 when false then 0 - else value.to_i rescue nil + else + result = value.to_i rescue nil + ensure_in_range(result) if result + result end end + + def ensure_in_range(value) + unless range.cover?(value) + raise RangeError, "#{value} is too large for #{self.class} with limit #{limit || 4}" + end + end + + def max_value + limit = self.limit || 4 + 1 << (limit * 8 - 1) # 8 bits per byte with one bit for sign + end end end end diff --git a/activerecord/lib/active_record/type/string.rb b/activerecord/lib/active_record/type/string.rb index 150defb106..fbc0af2c5a 100644 --- a/activerecord/lib/active_record/type/string.rb +++ b/activerecord/lib/active_record/type/string.rb @@ -15,8 +15,8 @@ module ActiveRecord case value when ::Numeric, ActiveSupport::Duration then value.to_s when ::String then ::String.new(value) - when true then "1" - when false then "0" + when true then "t" + when false then "f" else super end end @@ -25,8 +25,8 @@ module ActiveRecord def cast_value(value) case value - when true then "1" - when false then "0" + when true then "t" + when false then "f" # String.new is slightly faster than dup else ::String.new(value.to_s) end |