Sha256: 19128c7c4b8c7bccf1fe64f23e2d11773d5ae7c6fd3b843d1bbc7818eb2c98ad

Contents?: true

Size: 1.98 KB

Versions: 18

Compression:

Stored size: 1.98 KB

Contents

# frozen_string_literal: true

module ActiveElement
  module Components
    module Util
      # Provides options for a `<input type="number" />` element based on database column properties.
      class NumericField
        def initialize(field:, column:)
          @field = field
          @column = column
        end

        def options
          {
            step: step,
            min: min,
            max: max
          }.compact
        end

        private

        attr_reader :field, :column

        def step
          return 'any' if column.blank?
          return '1' if column.type == :integer
          return 'any' if column.try(:scale).blank?

          "0.#{'1'.rjust(column.scale, '0')}"
        end

        def min
          return min_decimal if column.try(:precision).present?
          return min_integer if column.try(:limit).present?

          nil
        end

        def max
          return max_decimal if column.try(:precision).present?
          return max_integer if column.try(:limit).present?

          nil
        end

        # XXX: This is the theoretical maximum value for a column with a given precision but,
        # since the maximum database value is constrained by total significant figures (i.e.
        # before and after the decimal point), an input can still be provided that would cause an
        # error, so the default controller rescues `ActiveRecord::RangeError` to deal with this.
        def max_decimal
          '9' * column.precision
        end

        def min_decimal
          "-#{'9' * column.precision}"
        end

        # `limit` represents available bytes for storing a signed integer e.g.
        # 2**(8 * 8) / 2 - 1 == 9223372036854775807
        # which matches PostgreSQL's `bigint` max value:
        # https://www.postgresql.org/docs/current/datatype-numeric.html
        def max_integer
          ((2**(column.limit * 8)) / 2) - 1
        end

        def min_integer
          -2**(column.limit * 8) / 2
        end
      end
    end
  end
end

Version data entries

18 entries across 18 versions & 1 rubygems

Version Path
active_element-0.0.31 lib/active_element/components/util/numeric_field.rb
active_element-0.0.30 lib/active_element/components/util/numeric_field.rb
active_element-0.0.29 lib/active_element/components/util/numeric_field.rb
active_element-0.0.28 lib/active_element/components/util/numeric_field.rb
active_element-0.0.27 lib/active_element/components/util/numeric_field.rb
active_element-0.0.26 lib/active_element/components/util/numeric_field.rb
active_element-0.0.24 lib/active_element/components/util/numeric_field.rb
active_element-0.0.23 lib/active_element/components/util/numeric_field.rb
active_element-0.0.22 lib/active_element/components/util/numeric_field.rb
active_element-0.0.21 lib/active_element/components/util/numeric_field.rb
active_element-0.0.19 lib/active_element/components/util/numeric_field.rb
active_element-0.0.18 lib/active_element/components/util/numeric_field.rb
active_element-0.0.17 lib/active_element/components/util/numeric_field.rb
active_element-0.0.16 lib/active_element/components/util/numeric_field.rb
active_element-0.0.15 lib/active_element/components/util/numeric_field.rb
active_element-0.0.14 lib/active_element/components/util/numeric_field.rb
active_element-0.0.13 lib/active_element/components/util/numeric_field.rb
active_element-0.0.12 lib/active_element/components/util/numeric_field.rb