Class: Repor::Report
- Inherits:
-
Object
- Object
- Repor::Report
- Defined in:
- lib/repor/report.rb
Instance Attribute Summary collapse
-
#params ⇒ Object
readonly
Returns the value of attribute params.
Class Method Summary collapse
- .aggregator(name, aggregator_class, opts = {}) ⇒ Object
- .aggregators ⇒ Object
-
.autoreport_association_name_columns(reflection) ⇒ Object
override this to change which columns of the association are used to auto-label it.
-
.autoreport_column(column) ⇒ Object
can override this method to skip or change certain column declarations.
-
.autoreport_on(class_or_name) ⇒ Object
autoreporting will automatically define dimensions based on columns.
- .default_class ⇒ Object
- .dimension(name, dimension_class, opts = {}) ⇒ Object
- .dimensions ⇒ Object
-
.inherited(subclass) ⇒ Object
ensure subclasses gain any aggregators or dimensions defined on their parents.
- .klass ⇒ Object
- .report_on(class_or_name) ⇒ Object
Instance Method Summary collapse
- #aggregator ⇒ Object
- #aggregator_name ⇒ Object
- #aggregators ⇒ Object
- #base_relation ⇒ Object
- #data ⇒ Object
- #dimensions ⇒ Object
- #filters ⇒ Object
-
#flat_data ⇒ Object
flat hash of { [x1, x2, x3] => y }.
- #group_values ⇒ Object
- #grouper_names ⇒ Object
- #groupers ⇒ Object
- #groups ⇒ Object
-
#initialize(params = {}) ⇒ Report
constructor
A new instance of Report.
-
#nested_data ⇒ Object
nested array of [{ key: x3, values: [{ key: x2, values: [{ key: x1, value: y }] }] }].
- #raw_data ⇒ Object
- #records ⇒ Object
- #relation ⇒ Object
- #relators ⇒ Object
- #table_name ⇒ Object
Constructor Details
#initialize(params = {}) ⇒ Report
Returns a new instance of Report.
7 8 9 10 11 |
# File 'lib/repor/report.rb', line 7 def initialize(params = {}) @params = params.deep_symbolize_keys.deep_dup deep_strip_blanks(@params) unless @params[:strip_blanks] == false validate_params! end |
Instance Attribute Details
#params ⇒ Object (readonly)
Returns the value of attribute params.
5 6 7 |
# File 'lib/repor/report.rb', line 5 def params @params end |
Class Method Details
.aggregator(name, aggregator_class, opts = {}) ⇒ Object
110 111 112 |
# File 'lib/repor/report.rb', line 110 def aggregator(name, aggregator_class, opts = {}) aggregators[name.to_sym] = { axis_class: aggregator_class, opts: opts } end |
.aggregators ⇒ Object
106 107 108 |
# File 'lib/repor/report.rb', line 106 def aggregators @aggregators ||= {} end |
.autoreport_association_name_columns(reflection) ⇒ Object
override this to change which columns of the association are used to auto-label it
182 183 184 |
# File 'lib/repor/report.rb', line 182 def autoreport_association_name_columns(reflection) %w(name email title) end |
.autoreport_column(column) ⇒ Object
can override this method to skip or change certain column declarations
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/repor/report.rb', line 159 def autoreport_column(column) return if column.name == 'id' belongs_to_ref = klass.reflections.find { |_, a| a.foreign_key == column.name } if belongs_to_ref name, ref = belongs_to_ref name_col = (ref.klass.column_names & autoreport_association_name_columns(ref)).first if name_col name_expr = "#{ref.klass.table_name}.#{name_col}" category_dimension name, expression: name_expr, relation: ->(r) { r.joins(name) } else category_dimension column.name end elsif column.cast_type.type == :datetime time_dimension column.name elsif column.cast_type.number? number_dimension column.name else category_dimension column.name end end |
.autoreport_on(class_or_name) ⇒ Object
autoreporting will automatically define dimensions based on columns
152 153 154 155 156 |
# File 'lib/repor/report.rb', line 152 def autoreport_on(class_or_name) report_on class_or_name klass.columns.each(&method(:autoreport_column)) count_aggregator :count if aggregators.blank? end |
.default_class ⇒ Object
130 131 132 |
# File 'lib/repor/report.rb', line 130 def default_class self.name.demodulize.sub(/Report$/, '').constantize end |
.dimension(name, dimension_class, opts = {}) ⇒ Object
102 103 104 |
# File 'lib/repor/report.rb', line 102 def dimension(name, dimension_class, opts = {}) dimensions[name.to_sym] = { axis_class: dimension_class, opts: opts } end |
.dimensions ⇒ Object
98 99 100 |
# File 'lib/repor/report.rb', line 98 def dimensions @dimensions ||= {} end |
.inherited(subclass) ⇒ Object
ensure subclasses gain any aggregators or dimensions defined on their parents
145 146 147 148 149 |
# File 'lib/repor/report.rb', line 145 def inherited(subclass) instance_values.each do |ivar, ival| subclass.instance_variable_set(:"@#{ivar}", ival.dup) end end |
.klass ⇒ Object
134 135 136 137 138 |
# File 'lib/repor/report.rb', line 134 def klass @klass ||= default_class rescue NameError raise NameError, "must specify a class to report on, e.g. `report_on Post`" end |
.report_on(class_or_name) ⇒ Object
140 141 142 |
# File 'lib/repor/report.rb', line 140 def report_on(class_or_name) @klass = class_or_name.to_s.constantize end |
Instance Method Details
#aggregator ⇒ Object
25 26 27 |
# File 'lib/repor/report.rb', line 25 def aggregator @aggregator ||= aggregators[aggregator_name] end |
#aggregator_name ⇒ Object
21 22 23 |
# File 'lib/repor/report.rb', line 21 def aggregator_name params.fetch(:aggregator, default_aggregator_name).to_sym end |
#aggregators ⇒ Object
17 18 19 |
# File 'lib/repor/report.rb', line 17 def aggregators @aggregators ||= build_axes(self.class.aggregators) end |
#base_relation ⇒ Object
47 48 49 |
# File 'lib/repor/report.rb', line 47 def base_relation params.fetch(:relation, klass.all) end |
#data ⇒ Object
93 94 95 |
# File 'lib/repor/report.rb', line 93 def data nested_data end |
#dimensions ⇒ Object
13 14 15 |
# File 'lib/repor/report.rb', line 13 def dimensions @dimensions ||= build_axes(self.class.dimensions) end |
#filters ⇒ Object
39 40 41 |
# File 'lib/repor/report.rb', line 39 def filters @filters ||= dimensions.values.select(&:filtering?) end |
#flat_data ⇒ Object
flat hash of { [x1, x2, x3] => y }
83 84 85 |
# File 'lib/repor/report.rb', line 83 def flat_data @flat_data ||= Hash[group_values.map { |x| [x, raw_data[x]] }] end |
#group_values ⇒ Object
77 78 79 |
# File 'lib/repor/report.rb', line 77 def group_values @group_values ||= all_combinations_of(groupers.map(&:group_values)) end |
#grouper_names ⇒ Object
29 30 31 32 33 |
# File 'lib/repor/report.rb', line 29 def grouper_names names = params.fetch(:groupers, default_grouper_names) names = names.is_a?(Hash) ? names.values : Array.wrap(names) names.map(&:to_sym) end |
#groupers ⇒ Object
35 36 37 |
# File 'lib/repor/report.rb', line 35 def groupers @groupers ||= dimensions.values_at(*grouper_names) end |
#groups ⇒ Object
67 68 69 70 71 |
# File 'lib/repor/report.rb', line 67 def groups @groups ||= groupers.reduce(records) do |relation, dimension| dimension.group(relation) end end |
#nested_data ⇒ Object
nested array of
- { key: x3, values: [{ key: x2, values: [{ key: x1, value: y }
-
}] }]
89 90 91 |
# File 'lib/repor/report.rb', line 89 def nested_data @nested_data ||= nest_data end |
#raw_data ⇒ Object
73 74 75 |
# File 'lib/repor/report.rb', line 73 def raw_data @raw_data ||= aggregator.aggregate(groups) end |
#records ⇒ Object
61 62 63 64 65 |
# File 'lib/repor/report.rb', line 61 def records @records ||= filters.reduce(relation) do |relation, dimension| dimension.filter(relation) end end |
#relation ⇒ Object
55 56 57 58 59 |
# File 'lib/repor/report.rb', line 55 def relation @relation ||= relators.reduce(base_relation) do |relation, dimension| dimension.relate(relation) end end |
#relators ⇒ Object
43 44 45 |
# File 'lib/repor/report.rb', line 43 def relators filters | groupers end |
#table_name ⇒ Object
51 52 53 |
# File 'lib/repor/report.rb', line 51 def table_name klass.table_name end |