integer.rb 1.4 KB
Newer Older
1
module ActiveModel
2 3
  module Type
    class Integer < Value # :nodoc:
4
      include Helpers::Numeric
5

6 7 8 9
      # Column storage size in bytes.
      # 4 bytes means a MySQL int or Postgres integer as opposed to smallint etc.
      DEFAULT_LIMIT = 4

10 11
      def initialize(*)
        super
12
        @range = min_value...max_value
13 14
      end

15 16 17 18
      def type
        :integer
      end

19
      def deserialize(value)
S
Sean Griffin 已提交
20 21 22 23
        return if value.nil?
        value.to_i
      end

24
      def serialize(value)
S
Sean Griffin 已提交
25
        result = cast(value)
26 27 28 29 30 31
        if result
          ensure_in_range(result)
        end
        result
      end

A
Akira Matsuda 已提交
32 33
      # TODO Change this to private once we've dropped Ruby 2.2 support.
      # Workaround for Ruby 2.2 "private attribute?" warning.
34 35
      protected

36
        attr_reader :range
37

38 39
      private

40 41 42 43 44 45 46
        def cast_value(value)
          case value
          when true then 1
          when false then 0
          else
            value.to_i rescue nil
          end
47
        end
48

49 50 51 52
        def ensure_in_range(value)
          unless range.cover?(value)
            raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit}"
          end
53 54
        end

55 56 57
        def max_value
          1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign
        end
58

59 60 61
        def min_value
          -max_value
        end
62

63
        def _limit
64
          limit || DEFAULT_LIMIT
65
        end
66 67 68
    end
  end
end