Class: CckForms::ParameterTypeClass::NumberRange

Inherits:
Object
  • Object
show all
Includes:
Base
Defined in:
lib/cck_forms/parameter_type_class/number_range.rb

Overview

Represents a decimal range — two integer values.

Has an extra_options (see base.rb): :ranges If passed, on each object save the intersection of the target range and :ranges will be calculated and saved into DB (denormalized) for easy finding later via where(‘some_field.ranged.300-600’ => true).

Direct Known Subclasses

FloatRange, IntegerRange

Instance Method Summary collapse

Instance Method Details

#build_form(form_builder, options) ⇒ Object

If options == :search and options == :select, builds a SELECT with options from extra_options. Otherwise, two inputs are built.

options are available if the former case.



87
88
89
90
91
92
93
94
# File 'lib/cck_forms/parameter_type_class/number_range.rb', line 87

def build_form(form_builder, options)
  set_value_in_hash options
  if options.delete(:for) == :search
    build_search_form(form_builder, options)
  else
    build_for_admin_interface_form(form_builder, options)
  end
end

#mongoizeObject

500, to: 1000, ranges: {“300-600” => true, “601-900” => true, “901-1500” => false}



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/cck_forms/parameter_type_class/number_range.rb', line 11

def mongoize
  value_from_form = value
  return nil if value_from_form.blank?

  from = normalize_number value_from_form.try(:[], 'from')
  till = normalize_number value_from_form.try(:[], 'till')

  db_representation = {
    from: from,
    till: till,
    ranges: {}
  }

  if @extra_options[:ranges].respond_to? :each
    @extra_options[:ranges].each do |range_string|
      low, high = range_string.split(range_string_delimiter)
      if normalize_number(high).to_s != high.to_s
        high = Integer::MAX_32BIT
      end
      low, high = normalize_number(low), normalize_number(high)

      #   -----
      # [ RANGE ]
      completely_in_range = (from >= low && till <= high)

      #       -------
      # [ RANGE ]
      #
      # ------
      #    [ RANGE ]
      intersects_range_partially = (from <= low && till >= low) || (from <= high && till >= high)

      # -----------
      #  [ RANGE ]
      contains_range = from < low && till > high

      db_representation[:ranges][range_string] = completely_in_range || intersects_range_partially || contains_range
    end
  end

  db_representation
end

#search(criteria, field, query) ⇒ Object

Search with the help of extra_options



97
98
99
# File 'lib/cck_forms/parameter_type_class/number_range.rb', line 97

def search(criteria, field, query)
  criteria.where("#{field}.ranges.#{query}" => true)
end

#to_s(options = {}) ⇒ Object

“from 10” “till 20” “10-20”

options:

delimeter - instead of "-"


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/cck_forms/parameter_type_class/number_range.rb', line 61

def to_s(options = {})
  options ||= {}
  return '' if value.blank?

  delimiter = options[:delimeter].presence || default_number_range_delimiter

  from = normalize_number value.try(:[], 'from')
  till = normalize_number value.try(:[], 'till')

  return '' if from.zero? && till.zero?

  if from.zero?
    [I18n.t("cck_forms.#{self.class.code}.till"), till].join(' ')
  elsif till.zero?
    [I18n.t("cck_forms.#{self.class.code}.from"), from].join(' ')
  elsif from == till
    from.to_s
  else
    [from, till].join(delimiter)
  end
end