Class: ReportsKit::Reports::Series

Inherits:
AbstractSeries show all
Defined in:
lib/reports_kit/reports/series.rb

Constant Summary collapse

VALID_KEYS =
[:measure, :dimensions, :contextual_filters, :context_params, :filters, :limit, :context_params, :report_options]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractSeries

#value_format_method

Constructor Details

#initialize(properties, context_record: nil) ⇒ Series

Returns a new instance of Series.

Raises:

  • (ArgumentError)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/reports_kit/reports/series.rb', line 8

def initialize(properties, context_record: nil)
  properties = { measure: properties } if properties.is_a?(String)
  properties = properties.deep_symbolize_keys.dup
  measure_properties = properties[:measure]
  properties[:measure] = measure_properties
  properties[:measure] = { key: properties[:measure] } if properties[:measure].is_a?(String)
  raise ArgumentError.new("Measure properties must be a String or Hash, not a #{properties.class.name}: #{properties.inspect}") unless properties.is_a?(Hash)

  contextual_filter_keys = properties[:contextual_filters] || []
  dimension_hashes = properties[:dimensions] || []
  dimension_hashes = dimension_hashes.values if dimension_hashes.is_a?(Hash) && dimension_hashes.key?(:'0')
  filter_hashes = properties[:filters] || []
  filter_hashes = filter_hashes.values if filter_hashes.is_a?(Hash) && filter_hashes.key?(:'0')

  self.properties = properties
  self.context_record = context_record
  self.dimensions = dimension_hashes.map { |dimension_hash| DimensionWithSeries.new(dimension: Dimension.new(dimension_hash), series: self) }
  self.filters = filter_hashes.map { |filter_hash| FilterWithSeries.new(filter: Filter.new(filter_hash), series: self) }
  self.contextual_filters = contextual_filter_keys.map { |key| ContextualFilter.new(key, series: self) }
end

Instance Attribute Details

#context_recordObject

Returns the value of attribute context_record.



6
7
8
# File 'lib/reports_kit/reports/series.rb', line 6

def context_record
  @context_record
end

#contextual_filtersObject

Returns the value of attribute contextual_filters.



6
7
8
# File 'lib/reports_kit/reports/series.rb', line 6

def contextual_filters
  @contextual_filters
end

#dimensionsObject

Returns the value of attribute dimensions.



6
7
8
# File 'lib/reports_kit/reports/series.rb', line 6

def dimensions
  @dimensions
end

#filtersObject

Returns the value of attribute filters.



6
7
8
# File 'lib/reports_kit/reports/series.rb', line 6

def filters
  @filters
end

#propertiesObject

Returns the value of attribute properties.



6
7
8
# File 'lib/reports_kit/reports/series.rb', line 6

def properties
  @properties
end

Class Method Details

.new_from_properties!(properties, context_record:) ⇒ Object

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/reports_kit/reports/series.rb', line 106

def self.new_from_properties!(properties, context_record:)
  series_hashes = properties[:series].presence || properties.slice(*Series::VALID_KEYS)
  series_hashes = [series_hashes] if series_hashes.is_a?(Hash)
  raise ArgumentError.new('At least one series must be configured') if series_hashes.blank?

  series_hashes.map do |series_hash|
    if series_hash[:composite_operator].present?
      CompositeSeries.new(series_hash, context_record: context_record)
    else
      new(series_hash, context_record: context_record)
    end
  end
end

Instance Method Details

#aggregate_functionObject



49
50
51
# File 'lib/reports_kit/reports/series.rb', line 49

def aggregate_function
  aggregation_expression || [:count, model_class.primary_key]
end

#aggregation_configObject



67
68
69
70
71
72
73
74
75
# File 'lib/reports_kit/reports/series.rb', line 67

def aggregation_config
  @aggregation_config ||= begin
    return unless aggregation_key
    raise ArgumentError.new("A '#{aggregation_key}' aggregation on the #{model_class} model hasn't been configured") unless model_class.respond_to?(:reports_kit_configuration)
    config = model_class.reports_kit_configuration.aggregations.find { |aggregation| aggregation[:key] == aggregation_key }
    raise ArgumentError.new("A '#{aggregation_key}' aggregation on the #{model_class} model hasn't been configured") unless config
    config
  end
end

#aggregation_expressionObject



53
54
55
56
57
58
59
60
61
# File 'lib/reports_kit/reports/series.rb', line 53

def aggregation_expression
  return unless aggregation_config
  expression = aggregation_config[:expression]
  if expression.is_a?(Array)
    expression
  else
    raise ArgumentError.new("The '#{aggregation_key}' aggregation on the #{model_class} model isn't valid")
  end
end

#aggregation_keyObject



63
64
65
# File 'lib/reports_kit/reports/series.rb', line 63

def aggregation_key
  properties[:measure][:aggregation]
end

#base_relationObject



77
78
79
80
# File 'lib/reports_kit/reports/series.rb', line 77

def base_relation
  return context_record.public_send(relation_name) if context_record
  model_class
end

#edit_relation_methodObject



41
42
43
# File 'lib/reports_kit/reports/series.rb', line 41

def edit_relation_method
  ReportsKit.configuration.custom_method(properties[:report_options].try(:[], :edit_relation_method))
end

#filtered_relationObject



91
92
93
94
95
96
97
98
99
100
# File 'lib/reports_kit/reports/series.rb', line 91

def filtered_relation
  relation = base_relation
  filters.each do |filter|
    relation = filter.apply(relation)
  end
  contextual_filters.each do |filter|
    relation = filter.apply(relation, properties[:context_params])
  end
  relation
end

#has_two_dimensions?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/reports_kit/reports/series.rb', line 102

def has_two_dimensions?
  dimensions.length == 2
end

#keyObject



29
30
31
# File 'lib/reports_kit/reports/series.rb', line 29

def key
  properties[:measure][:key].underscore
end

#labelObject



33
34
35
# File 'lib/reports_kit/reports/series.rb', line 33

def label
  properties[:measure][:name].presence || key.pluralize.titleize
end

#limitObject



37
38
39
# File 'lib/reports_kit/reports/series.rb', line 37

def limit
  properties[:limit]
end

#model_classObject



82
83
84
85
86
87
88
89
# File 'lib/reports_kit/reports/series.rb', line 82

def model_class
  if context_record
    reflection = context_record.class.reflect_on_association(key.to_sym) ||
      context_record.class.reflect_on_association(key.pluralize.to_sym)
    return reflection.klass if reflection
  end
  key.camelize.constantize
end

#relation_nameObject



45
46
47
# File 'lib/reports_kit/reports/series.rb', line 45

def relation_name
  key.tableize
end