From 9cc8c6f3730df3d94c81a55be9ee1b7b4ffd29f6 Mon Sep 17 00:00:00 2001 From: Kir Shatrov Date: Mon, 7 Sep 2015 21:20:15 +0300 Subject: Move ActiveRecord::Type to ActiveModel The first step of bringing typecasting to ActiveModel --- activemodel/lib/active_model/type/integer.rb | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 activemodel/lib/active_model/type/integer.rb (limited to 'activemodel/lib/active_model/type/integer.rb') diff --git a/activemodel/lib/active_model/type/integer.rb b/activemodel/lib/active_model/type/integer.rb new file mode 100644 index 0000000000..2f73ede009 --- /dev/null +++ b/activemodel/lib/active_model/type/integer.rb @@ -0,0 +1,66 @@ +module ActiveModel + module Type + class Integer < Value # :nodoc: + include Helpers::Numeric + + # Column storage size in bytes. + # 4 bytes means a MySQL int or Postgres integer as opposed to smallint etc. + DEFAULT_LIMIT = 4 + + def initialize(*) + super + @range = min_value...max_value + end + + def type + :integer + end + + def deserialize(value) + return if value.nil? + value.to_i + end + + def serialize(value) + result = cast(value) + if result + ensure_in_range(result) + end + result + end + + 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 + end + end + + def ensure_in_range(value) + unless range.cover?(value) + raise RangeError, "#{value} is out of range for #{self.class} with limit #{_limit}" + end + end + + def max_value + 1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign + end + + def min_value + -max_value + end + + def _limit + self.limit || DEFAULT_LIMIT + end + end + end +end -- cgit v1.2.3