reports_kit 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/.travis.yml +20 -0
- data/README.md +17 -19
- data/app/assets/javascripts/reports_kit/lib/_init.js +2 -1
- data/app/assets/javascripts/reports_kit/lib/chart.js +25 -16
- data/app/assets/javascripts/reports_kit/lib/report.js +42 -25
- data/app/assets/javascripts/reports_kit/lib/table.js +37 -2
- data/app/assets/stylesheets/reports_kit/reports.css.sass +3 -0
- data/docs/dimensions.md +26 -34
- data/docs/display_options.md +12 -15
- data/docs/filters.md +54 -63
- data/docs/measures.md +3 -4
- data/lib/reports_kit.rb +12 -10
- data/lib/reports_kit/base_controller.rb +1 -2
- data/lib/reports_kit/configuration.rb +19 -4
- data/lib/reports_kit/entity.rb +3 -0
- data/lib/reports_kit/helper.rb +17 -21
- data/lib/reports_kit/model_configuration.rb +1 -1
- data/lib/reports_kit/report_builder.rb +11 -11
- data/lib/reports_kit/reports/{abstract_measure.rb → abstract_series.rb} +1 -1
- data/lib/reports_kit/reports/{composite_measure.rb → composite_series.rb} +12 -8
- data/lib/reports_kit/reports/data/add_table_aggregations.rb +105 -0
- data/lib/reports_kit/reports/data/{composite_aggregation.rb → aggregate_composite.rb} +28 -27
- data/lib/reports_kit/reports/data/{one_dimension.rb → aggregate_one_dimension.rb} +9 -7
- data/lib/reports_kit/reports/data/{two_dimensions.rb → aggregate_two_dimensions.rb} +9 -8
- data/lib/reports_kit/reports/data/chart_options.rb +6 -11
- data/lib/reports_kit/reports/data/format_one_dimension.rb +56 -36
- data/lib/reports_kit/reports/data/format_table.rb +65 -0
- data/lib/reports_kit/reports/data/format_two_dimensions.rb +10 -8
- data/lib/reports_kit/reports/data/generate.rb +51 -28
- data/lib/reports_kit/reports/data/generate_for_properties.rb +52 -30
- data/lib/reports_kit/reports/data/populate_one_dimension.rb +30 -12
- data/lib/reports_kit/reports/data/populate_two_dimensions.rb +31 -31
- data/lib/reports_kit/reports/data/utils.rb +28 -24
- data/lib/reports_kit/reports/dimension.rb +4 -0
- data/lib/reports_kit/reports/{dimension_with_measure.rb → dimension_with_series.rb} +8 -9
- data/lib/reports_kit/reports/filter.rb +4 -0
- data/lib/reports_kit/reports/filter_types/base.rb +4 -3
- data/lib/reports_kit/reports/filter_types/boolean.rb +4 -4
- data/lib/reports_kit/reports/filter_types/datetime.rb +13 -3
- data/lib/reports_kit/reports/filter_types/number.rb +5 -5
- data/lib/reports_kit/reports/{filter_with_measure.rb → filter_with_series.rb} +7 -7
- data/lib/reports_kit/reports/generate_autocomplete_results.rb +2 -2
- data/lib/reports_kit/reports/inferrable_configuration.rb +6 -6
- data/lib/reports_kit/reports/{measure.rb → series.rb} +28 -15
- data/lib/reports_kit/reports_controller.rb +25 -5
- data/lib/reports_kit/value.rb +3 -0
- data/lib/reports_kit/version.rb +1 -1
- data/spec/fixtures/generate_inputs.yml +116 -63
- data/spec/fixtures/generate_outputs.yml +64 -0
- data/spec/reports_kit/report_builder_spec.rb +10 -12
- data/spec/reports_kit/reports/data/generate_spec.rb +559 -140
- data/spec/reports_kit/reports/{dimension_with_measure_spec.rb → dimension_with_series_spec.rb} +5 -7
- data/spec/reports_kit/reports/{filter_with_measure_spec.rb → filter_with_series_spec.rb} +3 -3
- data/spec/spec_helper.rb +5 -5
- data/spec/support/config.rb +31 -1
- data/spec/support/helpers.rb +6 -2
- metadata +17 -14
- data/lib/reports_kit/reports/data/entity.rb +0 -7
- data/lib/reports_kit/reports/data/value.rb +0 -7
@@ -2,33 +2,51 @@ module ReportsKit
|
|
2
2
|
module Reports
|
3
3
|
module Data
|
4
4
|
class PopulateOneDimension
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :sparse_serieses_dimension_keys_values, :context_record, :properties
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
7
|
+
def initialize(sparse_serieses_dimension_keys_values, context_record: nil, properties: nil)
|
8
|
+
self.sparse_serieses_dimension_keys_values = sparse_serieses_dimension_keys_values
|
9
|
+
self.context_record = context_record
|
10
|
+
self.properties = properties
|
9
11
|
end
|
10
12
|
|
11
13
|
def perform
|
12
|
-
return
|
13
|
-
|
14
|
+
return sparse_serieses_dimension_keys_values if sparse_serieses_dimension_keys_values.length == 1
|
15
|
+
serieses_dimension_keys_values
|
14
16
|
end
|
15
17
|
|
16
18
|
private
|
17
19
|
|
18
|
-
def
|
19
|
-
|
20
|
+
def serieses_dimension_keys_values
|
21
|
+
serieses_dimension_keys_values = sparse_serieses_dimension_keys_values.map do |series, dimension_keys_values|
|
20
22
|
dimension_keys.each do |key|
|
21
23
|
dimension_keys_values[key] ||= 0
|
22
24
|
end
|
23
|
-
[
|
25
|
+
[series, dimension_keys_values]
|
24
26
|
end
|
25
|
-
Hash[
|
27
|
+
Hash[serieses_dimension_keys_values]
|
26
28
|
end
|
27
29
|
|
28
30
|
def dimension_keys
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
dimension_keys_from_edit_dimension_keys_method || dimension_keys_from_results
|
32
|
+
end
|
33
|
+
|
34
|
+
def dimension_keys_from_edit_dimension_keys_method
|
35
|
+
return unless edit_dimension_keys_method
|
36
|
+
edit_dimension_keys_method.call(dimension_keys: dimension_keys_from_results, properties: properties, context_record: context_record)
|
37
|
+
end
|
38
|
+
|
39
|
+
def dimension_keys_from_results
|
40
|
+
@dimension_keys_from_results ||= begin
|
41
|
+
sparse_serieses_dimension_keys_values.map do |series, dimension_keys_values|
|
42
|
+
dimension_keys_values.keys
|
43
|
+
end.reduce(&:+).uniq
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def edit_dimension_keys_method
|
48
|
+
return unless properties
|
49
|
+
ReportsKit.configuration.custom_method(properties[:report_options].try(:[], :edit_dimension_keys_method))
|
32
50
|
end
|
33
51
|
end
|
34
52
|
end
|
@@ -2,25 +2,25 @@ module ReportsKit
|
|
2
2
|
module Reports
|
3
3
|
module Data
|
4
4
|
class PopulateTwoDimensions
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :serieses, :dimension, :second_dimension, :sparse_serieses_dimension_keys_values
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
9
|
-
self.dimension =
|
10
|
-
self.second_dimension =
|
11
|
-
self.
|
7
|
+
def initialize(sparse_serieses_dimension_keys_values)
|
8
|
+
self.serieses = sparse_serieses_dimension_keys_values.keys
|
9
|
+
self.dimension = serieses.first.dimensions[0]
|
10
|
+
self.second_dimension = serieses.first.dimensions[1]
|
11
|
+
self.sparse_serieses_dimension_keys_values = sparse_serieses_dimension_keys_values
|
12
12
|
end
|
13
13
|
|
14
14
|
def perform
|
15
|
-
|
15
|
+
serieses_populated_dimension_keys_values
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def
|
21
|
-
|
20
|
+
def serieses_populated_dimension_keys_values
|
21
|
+
serieses_dimension_keys_values = {}
|
22
22
|
secondary_keys_sums = Hash.new(0)
|
23
|
-
|
23
|
+
serieses_populated_primary_keys_secondary_keys_values.each do |series, primary_keys_secondary_keys_values|
|
24
24
|
primary_keys_secondary_keys_values.each do |primary_key, secondary_keys_values|
|
25
25
|
secondary_keys_values.each do |secondary_key, value|
|
26
26
|
secondary_keys_sums[secondary_key] += value
|
@@ -28,55 +28,55 @@ module ReportsKit
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
sorted_secondary_keys = secondary_keys_sums.sort_by(&:last).reverse.map(&:first)
|
31
|
-
|
32
|
-
|
31
|
+
serieses_populated_primary_keys_secondary_keys_values.each do |series, primary_key_secondary_keys_values|
|
32
|
+
serieses_dimension_keys_values[series] = {}
|
33
33
|
primary_key_secondary_keys_values.each do |primary_key, secondary_keys_values|
|
34
34
|
secondary_keys_values = secondary_keys_values.sort_by { |key, _| sorted_secondary_keys.index(key) }
|
35
35
|
secondary_keys_values.each do |secondary_key, value|
|
36
36
|
dimension_key = [primary_key, secondary_key]
|
37
|
-
|
37
|
+
serieses_dimension_keys_values[series][dimension_key] = value
|
38
38
|
secondary_keys_sums[secondary_key] += value
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
serieses_dimension_keys_values
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
45
|
+
def serieses_populated_primary_keys_secondary_keys_values
|
46
46
|
@populated_dimension_keys_values ||= begin
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
serieses_populated_primary_keys_secondary_keys_values = {}
|
48
|
+
serieses.each do |series|
|
49
|
+
serieses_populated_primary_keys_secondary_keys_values[series] = {}
|
50
50
|
primary_keys.each do |primary_key|
|
51
|
-
|
51
|
+
serieses_populated_primary_keys_secondary_keys_values[series][primary_key] = {}
|
52
52
|
secondary_keys.each do |secondary_key|
|
53
|
-
value =
|
54
|
-
|
53
|
+
value = serieses_primary_keys_secondary_keys_values[series][primary_key].try(:[], secondary_key) || 0
|
54
|
+
serieses_populated_primary_keys_secondary_keys_values[series][primary_key][secondary_key] = value
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
serieses_populated_primary_keys_secondary_keys_values
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
def serieses_primary_keys_secondary_keys_values
|
63
|
+
@serieses_primary_keys_secondary_keys_values ||= begin
|
64
|
+
serieses_primary_keys_secondary_keys_values = {}
|
65
|
+
sparse_serieses_dimension_keys_values.each do |series, dimension_keys_values|
|
66
|
+
serieses_primary_keys_secondary_keys_values[series] = {}
|
67
67
|
dimension_keys_values.each do |(primary_key, secondary_key), value|
|
68
68
|
primary_key = primary_key.to_date if primary_key.is_a?(Time)
|
69
69
|
secondary_key = secondary_key.to_date if secondary_key.is_a?(Time)
|
70
|
-
|
71
|
-
|
70
|
+
serieses_primary_keys_secondary_keys_values[series][primary_key] ||= {}
|
71
|
+
serieses_primary_keys_secondary_keys_values[series][primary_key][secondary_key] = value
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
serieses_primary_keys_secondary_keys_values
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
def dimension_keys
|
79
|
-
@dimension_keys ||=
|
79
|
+
@dimension_keys ||= sparse_serieses_dimension_keys_values.values.map(&:keys).reduce(&:+).uniq
|
80
80
|
end
|
81
81
|
|
82
82
|
def primary_keys
|
@@ -2,14 +2,18 @@ module ReportsKit
|
|
2
2
|
module Reports
|
3
3
|
module Data
|
4
4
|
class Utils
|
5
|
-
def self.format_display_time(time)
|
6
|
-
time.strftime('%b %-d, \'%y')
|
7
|
-
end
|
8
|
-
|
9
5
|
def self.format_configuration_time(time)
|
10
6
|
time.strftime('%b %-d, %Y')
|
11
7
|
end
|
12
8
|
|
9
|
+
def self.format_csv_time(time)
|
10
|
+
time.strftime('%Y-%m-%d')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.format_display_time(time)
|
14
|
+
time.strftime('%b %-d, \'%y')
|
15
|
+
end
|
16
|
+
|
13
17
|
def self.format_time_value(value)
|
14
18
|
time = RelativeTime.parse(value, prevent_exceptions: true)
|
15
19
|
return value unless time
|
@@ -22,17 +26,19 @@ module ReportsKit
|
|
22
26
|
number.round(Generate::ROUND_PRECISION)
|
23
27
|
end
|
24
28
|
|
29
|
+
def self.quote_column_name(string)
|
30
|
+
ActiveRecord::Base.connection.quote_column_name(string)
|
31
|
+
end
|
32
|
+
|
25
33
|
def self.parse_date_string(string)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
RelativeTime.parse(string)
|
30
|
-
end
|
34
|
+
Date.parse(string)
|
35
|
+
rescue ArgumentError
|
36
|
+
RelativeTime.parse(string)
|
31
37
|
end
|
32
38
|
|
33
39
|
def self.populate_sparse_hash(hash, dimension:)
|
34
40
|
keys = hash.keys
|
35
|
-
is_nested = dimension.
|
41
|
+
is_nested = dimension.series.has_two_dimensions?
|
36
42
|
if is_nested
|
37
43
|
keys_values = arrays_values_to_nested_hash(hash)
|
38
44
|
keys = keys_values.keys
|
@@ -67,11 +73,7 @@ module ReportsKit
|
|
67
73
|
keys = keys.sort
|
68
74
|
last_key = (dimension.last_key || keys.last).to_date
|
69
75
|
last_key = last_key.beginning_of_week(ReportsKit.configuration.first_day_of_week) if granularity == 'week'
|
70
|
-
|
71
|
-
if granularity == 'week'
|
72
|
-
beginning_of_current_week = Date.today.beginning_of_week(ReportsKit.configuration.first_day_of_week)
|
73
|
-
last_key = [beginning_of_current_week, last_key].compact.max
|
74
|
-
end
|
76
|
+
last_key ||= Date.today.beginning_of_week(ReportsKit.configuration.first_day_of_week) if granularity == 'week'
|
75
77
|
|
76
78
|
date = first_key
|
77
79
|
populated_keys = []
|
@@ -145,8 +147,8 @@ module ReportsKit
|
|
145
147
|
Value.new(raw_value, formatted_value)
|
146
148
|
end
|
147
149
|
|
148
|
-
def self.normalize_filters(
|
149
|
-
|
150
|
+
def self.normalize_filters(series_properties, ui_filters)
|
151
|
+
series_properties[:filters] = series_properties[:filters].map do |filter_properties|
|
150
152
|
filter_properties = { key: filter_properties } if filter_properties.is_a?(String)
|
151
153
|
key = filter_properties[:key]
|
152
154
|
ui_key = filter_properties[:ui_key]
|
@@ -158,18 +160,20 @@ module ReportsKit
|
|
158
160
|
end
|
159
161
|
filter_properties
|
160
162
|
end
|
161
|
-
|
163
|
+
series_properties
|
162
164
|
end
|
163
165
|
|
164
166
|
def self.normalize_properties(properties, ui_filters: nil)
|
167
|
+
can_have_nesting = properties[:composite_operator].present? || properties[:series].is_a?(Array)
|
165
168
|
ui_filters ||= properties[:ui_filters]
|
166
169
|
properties = properties.dup
|
167
|
-
properties[:
|
168
|
-
|
169
|
-
properties
|
170
|
-
|
171
|
-
|
172
|
-
|
170
|
+
properties[:series] ||= properties.slice(*Series::VALID_KEYS).presence
|
171
|
+
properties[:series] = [properties[:series]] if properties[:series].is_a?(Hash) && properties[:series].present?
|
172
|
+
return properties if ui_filters.blank? || properties[:series].blank?
|
173
|
+
properties[:series] = properties[:series].map do |series_properties|
|
174
|
+
series_properties = normalize_properties(series_properties, ui_filters: ui_filters) if can_have_nesting
|
175
|
+
next(series_properties) if series_properties[:filters].blank?
|
176
|
+
normalize_filters(series_properties, ui_filters)
|
173
177
|
end
|
174
178
|
properties
|
175
179
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ReportsKit
|
2
2
|
module Reports
|
3
|
-
class
|
4
|
-
DEFAULT_DIMENSION_INSTANCES_LIMIT = 30
|
3
|
+
class DimensionWithSeries
|
5
4
|
DEFAULT_GRANULARITY = 'week'
|
6
5
|
VALID_GRANULARITIES = %w(day week).freeze
|
7
6
|
ADAPTER_NAMES_CLASSES = {
|
@@ -9,16 +8,16 @@ module ReportsKit
|
|
9
8
|
'postgresql' => Adapters::Postgresql
|
10
9
|
}.freeze
|
11
10
|
|
12
|
-
attr_accessor :dimension, :
|
11
|
+
attr_accessor :dimension, :series, :configuration
|
13
12
|
|
14
|
-
delegate :key, :properties, :label, to: :dimension
|
13
|
+
delegate :key, :expression, :properties, :label, to: :dimension
|
15
14
|
delegate :configured_by_association?, :configured_by_column?, :configured_by_model?, :configured_by_time?,
|
16
15
|
:settings_from_model, :reflection, :instance_class, :model_class, :column_type,
|
17
16
|
to: :configuration
|
18
17
|
|
19
|
-
def initialize(dimension:,
|
18
|
+
def initialize(dimension:, series:)
|
20
19
|
self.dimension = dimension
|
21
|
-
self.
|
20
|
+
self.series = series
|
22
21
|
self.configuration = InferrableConfiguration.new(self, :dimensions)
|
23
22
|
missing_group_setting = settings && !settings.key?(:group)
|
24
23
|
raise ArgumentError.new("Dimension settings for dimension '#{key}' of #{model_class} must include :group") if missing_group_setting
|
@@ -84,7 +83,7 @@ module ReportsKit
|
|
84
83
|
if configured_by_time?
|
85
84
|
properties[:limit]
|
86
85
|
else
|
87
|
-
properties[:limit] ||
|
86
|
+
properties[:limit] || ReportsKit.configuration.default_dimension_limit
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
@@ -104,8 +103,8 @@ module ReportsKit
|
|
104
103
|
end
|
105
104
|
|
106
105
|
def datetime_filters
|
107
|
-
return [] unless
|
108
|
-
|
106
|
+
return [] unless series.filters.present?
|
107
|
+
series.filters.map(&:filter_type).select { |filter_type| filter_type.is_a?(FilterTypes::Datetime) }
|
109
108
|
end
|
110
109
|
|
111
110
|
def should_be_sorted_by_count?
|
@@ -2,11 +2,12 @@ module ReportsKit
|
|
2
2
|
module Reports
|
3
3
|
module FilterTypes
|
4
4
|
class Base
|
5
|
-
attr_accessor :settings, :properties
|
5
|
+
attr_accessor :settings, :properties, :primary_dimension
|
6
6
|
|
7
|
-
def initialize(settings, properties)
|
7
|
+
def initialize(settings, properties, primary_dimension:)
|
8
8
|
self.settings = settings || {}
|
9
9
|
self.properties = properties
|
10
|
+
self.primary_dimension = primary_dimension
|
10
11
|
end
|
11
12
|
|
12
13
|
def apply_filter(records)
|
@@ -39,7 +40,7 @@ module ReportsKit
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def column
|
42
|
-
settings[:column] || properties[:key]
|
43
|
+
settings[:column] || Data::Utils.quote_column_name(properties[:key])
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -20,13 +20,13 @@ module ReportsKit
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def boolean_value
|
23
|
-
case
|
23
|
+
case value
|
24
24
|
when true, 'true'
|
25
25
|
true
|
26
26
|
when false, 'false'
|
27
27
|
false
|
28
28
|
else
|
29
|
-
raise ArgumentError.new("Unsupported value: '#{
|
29
|
+
raise ArgumentError.new("Unsupported value: '#{value}'")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -35,11 +35,11 @@ module ReportsKit
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def valid?
|
38
|
-
|
38
|
+
value.present?
|
39
39
|
end
|
40
40
|
|
41
41
|
def conditions
|
42
|
-
settings[:conditions] || properties[:key]
|
42
|
+
settings[:conditions] || Data::Utils.quote_column_name(properties[:key])
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -10,7 +10,7 @@ module ReportsKit
|
|
10
10
|
def apply_conditions(records)
|
11
11
|
case criteria[:operator]
|
12
12
|
when 'between'
|
13
|
-
records.where(
|
13
|
+
records.where.not(column => nil).where(column => start_at..end_at)
|
14
14
|
else
|
15
15
|
raise ArgumentError.new("Unsupported operator: '#{criteria[:operator]}'")
|
16
16
|
end
|
@@ -21,8 +21,8 @@ module ReportsKit
|
|
21
21
|
return unless valid?
|
22
22
|
start_string, end_string = value.split(SEPARATOR)
|
23
23
|
start_at = ReportsKit::Reports::Data::Utils.parse_date_string(start_string)
|
24
|
-
end_at = ReportsKit::Reports::Data::Utils.parse_date_string(end_string)
|
25
|
-
|
24
|
+
end_at = ReportsKit::Reports::Data::Utils.parse_date_string(end_string)
|
25
|
+
adjust_range_to_dimension(start_at, end_at)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -34,6 +34,16 @@ module ReportsKit
|
|
34
34
|
start_at_end_at.try(:[], 1)
|
35
35
|
end
|
36
36
|
|
37
|
+
def adjust_range_to_dimension(start_at, end_at)
|
38
|
+
return [start_at.beginning_of_day, end_at.end_of_day] unless primary_dimension.configured_by_time?
|
39
|
+
return [start_at.beginning_of_day, end_at.end_of_day] if primary_dimension.granularity == 'day'
|
40
|
+
return [
|
41
|
+
start_at.beginning_of_week(ReportsKit.configuration.first_day_of_week),
|
42
|
+
end_at.end_of_week(ReportsKit.configuration.first_day_of_week)
|
43
|
+
] if primary_dimension.granularity == 'week'
|
44
|
+
[start_at, end_at]
|
45
|
+
end
|
46
|
+
|
37
47
|
def valid?
|
38
48
|
value.present?
|
39
49
|
end
|
@@ -7,15 +7,15 @@ module ReportsKit
|
|
7
7
|
def apply_conditions(records)
|
8
8
|
case criteria[:operator]
|
9
9
|
when '>'
|
10
|
-
records.where(
|
10
|
+
records.where(column => (value.to_i...Float::INFINITY))
|
11
11
|
when '>='
|
12
|
-
records.where(
|
12
|
+
records.where(column => (value.to_i..Float::INFINITY))
|
13
13
|
when '<'
|
14
|
-
records.where(
|
14
|
+
records.where(column => (-Float::INFINITY...value.to_i))
|
15
15
|
when '<='
|
16
|
-
records.where(
|
16
|
+
records.where(column => (-Float::INFINITY..value.to_i))
|
17
17
|
when '='
|
18
|
-
records.where(
|
18
|
+
records.where(column => value.to_i)
|
19
19
|
else
|
20
20
|
raise ArgumentError.new("Unsupported operator: '#{criteria[:operator]}'")
|
21
21
|
end
|