simple_drilldown 0.4.0 → 0.5.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/README.md +9 -6
- data/app/views/drilldown/_chart.html.erb +1 -1
- data/app/views/drilldown/_field.html.erb +0 -1
- data/app/views/drilldown/_filter.html.erb +4 -13
- data/app/views/drilldown/_record_list.html.erb +3 -3
- data/app/views/drilldown/_row.html.erb +9 -9
- data/app/views/drilldown/_summary_table.html.erb +2 -2
- data/app/views/drilldown/excel_export_transactions.builder +1 -1
- data/lib/generators/drilldown_controller/drilldown_controller_generator.rb +2 -1
- data/lib/generators/drilldown_controller/templates/drilldown_controller.rb.erb +14 -5
- data/lib/generators/drilldown_controller/templates/drilldown_controller_test.rb.erb +15 -0
- data/lib/simple_drilldown/drilldown_controller.rb +64 -67
- data/lib/simple_drilldown/engine.rb +3 -0
- data/lib/simple_drilldown/routing.rb +1 -0
- data/lib/simple_drilldown/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9994fb706e46554bec7e26a9191cdc10e2675a19770e4414019f5b4a067e7daf
|
4
|
+
data.tar.gz: 874f30d58de361193d6faed89b2af82e8899b0c628861865b917af9466faa64d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61559d0c5e2f91474c86bbb3424c55e41d4fb355921a06cd3b4627ea1ab72a789be74989e53135b7179ea3b59feec83d140ed4e681fb85f111f0f024017a169d
|
7
|
+
data.tar.gz: 8bed5fd23fb6254bf5280ddce378738294af1bf5de119da11000695a3c594e48797b9f820987ef4296ed94ac6a680075f20924a6d6473702f7b05c7fe120af34
|
data/README.md
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
<img align="right" src="https://travis-ci.org/DatekWireless/simple_drilldown.svg?branch=master" alt="Build Status">
|
5
5
|
</a>
|
6
6
|
|
7
|
-
simple_drilldown offers a simple way to define axis to filter and group records
|
7
|
+
`simple_drilldown` offers a simple way to define axis to filter and group records
|
8
8
|
for analysis. The result is a record count for the selected filter and
|
9
|
-
distribution and the option to list the actual records.
|
9
|
+
distribution and the option to list and export the actual records.
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
@@ -16,6 +16,10 @@ For a given schema:
|
|
16
16
|
|
17
17
|
```ruby
|
18
18
|
ActiveRecord::Schema.define(version: 20141204155251) do
|
19
|
+
create_table "users" do |t|
|
20
|
+
t.string "name", limit: 16, null: false
|
21
|
+
end
|
22
|
+
|
19
23
|
create_table "posts" do |t|
|
20
24
|
t.string "title", null: false
|
21
25
|
t.text "body", null: false
|
@@ -25,12 +29,9 @@ ActiveRecord::Schema.define(version: 20141204155251) do
|
|
25
29
|
t.datetime "updated_at", null: false
|
26
30
|
end
|
27
31
|
|
28
|
-
create_table "users" do |t|
|
29
|
-
t.string "name", limit: 16, null: false
|
30
|
-
end
|
31
|
-
|
32
32
|
create_table "comments" do |t|
|
33
33
|
t.integer "post_id", null: false
|
34
|
+
t.integer "user_id", null: false
|
34
35
|
t.string "title", null: false
|
35
36
|
t.text "body", null: false
|
36
37
|
t.integer "rating", null: false
|
@@ -65,6 +66,8 @@ end
|
|
65
66
|
Create a new controller to focus on posts. Each drilldown controller focuses on
|
66
67
|
one main entity.
|
67
68
|
|
69
|
+
bin/rails g drilldown_controller User
|
70
|
+
|
68
71
|
```ruby
|
69
72
|
class PostsDrilldownController < DrilldownController
|
70
73
|
|
@@ -37,7 +37,7 @@
|
|
37
37
|
<% (0..2).each do |i|
|
38
38
|
options = [['', '']]
|
39
39
|
options << [@dimensions[i][:pretty_name], @dimensions[i][:url_param_name]] if @dimensions[i]
|
40
|
-
options += @remaining_dimensions.keys.map { |name| [
|
40
|
+
options += @remaining_dimensions.keys.map { |name| [controller.c_dimension_defs[name][:pretty_name], name] } %>
|
41
41
|
<%= t(i == 0 ? :group_by : :then_by) %>:
|
42
42
|
<%= form.select 'dimensions', options, { :selected => @search.dimensions && @search.dimensions[i] },
|
43
43
|
{ :onChange => 'form.submit()', :name => 'search[dimensions][]', :id => "search_dimensions_#{i}" } %>
|
@@ -4,17 +4,8 @@
|
|
4
4
|
</div>
|
5
5
|
|
6
6
|
<% choices = Concurrent::Hash.new %>
|
7
|
-
<%
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<% choices[dimension_name] = [[t(:all), nil]] + (dimension[:legal_values] && dimension[:legal_values].call(@search).map { |o| o.is_a?(Array) ? [o[0].to_s, o[1].to_s] : o.to_s } || []) %>
|
12
|
-
<% end %>
|
13
|
-
<% end %>
|
14
|
-
<% next [t, dimension_name] %>
|
15
|
-
<% end %>
|
16
|
-
<% threads.each do |t, dimension_name| %>
|
17
|
-
<% t.join %>
|
18
|
-
<%= render partial: 'drilldown/field', locals: {choices: choices[dimension_name] || [],
|
19
|
-
form: form, dimension_name: dimension_name} %>
|
7
|
+
<% controller.c_dimension_defs.each do |dimension_name, dimension| %>
|
8
|
+
<% choices[dimension_name] = [[t(:all), nil]] + (dimension[:legal_values] && dimension[:legal_values].call(@search).map { |o| o.is_a?(Array) ? [o[0].to_s, o[1].to_s] : o.to_s } || []) %>
|
9
|
+
<%= render partial: 'drilldown/field', locals: { choices: choices[dimension_name] || [],
|
10
|
+
form: form, dimension_name: dimension_name } %>
|
20
11
|
<% end %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<% unless result[:transactions].empty? %>
|
2
2
|
<tr>
|
3
|
-
<td colspan="
|
3
|
+
<td colspan="<%= controller.c_summary_fields.size + 1 %>">
|
4
4
|
<table class="table table-condensed table-bordered" style="padding-bottom: 10px;">
|
5
|
-
<%=render :partial => '/drilldown/row_header' %>
|
5
|
+
<%= render :partial => '/drilldown/row_header' %>
|
6
6
|
<% result[:transactions].each do |t| %>
|
7
|
-
<%=render :partial => '/drilldown/row', :locals => {:transaction => t, :previous_transaction => nil, :errors => [], :error_row => false, :meter1_errors => false} %>
|
7
|
+
<%= render :partial => '/drilldown/row', :locals => { :transaction => t, :previous_transaction => nil, :errors => [], :error_row => false, :meter1_errors => false } %>
|
8
8
|
<% end %>
|
9
9
|
</table>
|
10
10
|
</td>
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<tr valign="top">
|
2
2
|
<% @search.fields.each do |field| %>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
<td>
|
4
|
+
<% if field == 'time' %>
|
5
|
+
<%= (transaction.respond_to?(:completed_at) ? transaction.completed_at : transaction.created_at).localtime.strftime('%Y-%m-%d %H:%M') %>
|
6
|
+
<% else %>
|
7
|
+
<% field_def = controller.c_fields[field.to_sym] %>
|
8
|
+
<%= field_def[:attr_method] ? field_def[:attr_method].call(transaction) : transaction.send(field) %>
|
9
|
+
<% end %>
|
10
|
+
</td>
|
11
11
|
<% end %>
|
12
|
-
<td><%=
|
12
|
+
<td><%= link_to t(:show), transaction %></td>
|
13
13
|
</tr>
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<% @dimensions.each do |d| %>
|
4
4
|
<th><%=h d[:pretty_name]%></th>
|
5
5
|
<% end %>
|
6
|
-
<th><%= t
|
7
|
-
<%=
|
6
|
+
<th><%= t controller.c_target_class.table_name.capitalize %></th>
|
7
|
+
<%= controller.c_summary_fields.map{|l| "<th>#{t(l)}</th>"}.join("\n").html_safe %>
|
8
8
|
</tr>
|
9
9
|
|
10
10
|
<%=summary_row(@result) %>
|
@@ -45,7 +45,7 @@ xml.Workbook(
|
|
45
45
|
@transactions.each do |transaction|
|
46
46
|
xml.Row do
|
47
47
|
@transaction_fields.each do |field|
|
48
|
-
field_map =
|
48
|
+
field_map = controller.c_fields[field.to_sym]
|
49
49
|
if field == 'time'
|
50
50
|
xml.Cell 'ss:StyleID' => 'DateOnlyFormat' do
|
51
51
|
xml.Data transaction.completed_at.gmtime.xmlschema, 'ss:Type' => 'DateTime'
|
@@ -5,6 +5,7 @@ class DrilldownControllerGenerator < Rails::Generators::NamedBase
|
|
5
5
|
|
6
6
|
def copy_drilldown_controller_file
|
7
7
|
template 'drilldown_controller.rb.erb', "app/controllers/#{file_name}_drilldown_controller.rb"
|
8
|
-
|
8
|
+
template 'drilldown_controller_test.rb.erb', "test/controllers/#{file_name}_drilldown_controller_test.rb"
|
9
|
+
route "draw_drilldown :#{singular_name}_drilldown"
|
9
10
|
end
|
10
11
|
end
|
@@ -1,14 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# What fields should be displayed as default when listing actual <%= class_name %> records.
|
5
|
-
default_fields %w[created_at updated_at] # TODO(uwe): Read fields from schema?
|
3
|
+
require 'simple_drilldown/drilldown_controller'
|
6
4
|
|
5
|
+
class <%= class_name %>DrilldownController < SimpleDrilldown::DrilldownController
|
7
6
|
# The main focus of the drilldown
|
8
|
-
target_class <%= class_name %>
|
7
|
+
# target_class <%= class_name %>
|
8
|
+
|
9
|
+
# `where` clause for the base line
|
10
|
+
# base_condition '1=1'
|
9
11
|
|
10
12
|
# How should we count the reords?
|
11
|
-
select 'count(*) as count'
|
13
|
+
# select 'count(*) as count'
|
14
|
+
|
15
|
+
# When selecting records, what relations should be included for optimization?
|
16
|
+
# Other relations can be included for specific dimensions and fields.
|
17
|
+
# base_includes :user, :comments # TODO(uwe): Read relations from schema?
|
18
|
+
|
19
|
+
# What fields should be displayed as default when listing actual <%= class_name %> records.
|
20
|
+
default_fields %w[created_at updated_at] # TODO(uwe): Read fields from schema?
|
12
21
|
|
13
22
|
# When listing records, what relations should be included for optimization?
|
14
23
|
# list_includes :user, :comments # TODO(uwe): Read relations from schema?
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class <%= class_name %>DrilldownControllerTest < ActionDispatch::IntegrationTest
|
6
|
+
test 'should get index' do
|
7
|
+
get <%= singular_name %>_drilldown_url
|
8
|
+
assert_response :success
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'should get index with list' do
|
12
|
+
get <%= singular_name %>_drilldown_url search: { list: 1 }
|
13
|
+
assert_response :success
|
14
|
+
end
|
15
|
+
end
|
@@ -9,46 +9,63 @@ module SimpleDrilldown
|
|
9
9
|
|
10
10
|
LIST_LIMIT = 10_000
|
11
11
|
|
12
|
+
class_attribute :c_base_condition, default: '1=1'
|
13
|
+
class_attribute :c_base_group, default: []
|
14
|
+
class_attribute :c_base_includes, default: []
|
15
|
+
class_attribute :c_default_fields, default: []
|
16
|
+
class_attribute :c_default_select_value, default: SimpleDrilldown::Search::SelectValue::COUNT
|
17
|
+
class_attribute :c_dimension_defs, default: Concurrent::Hash.new
|
18
|
+
class_attribute :c_fields, default: {}
|
19
|
+
class_attribute :c_list_includes, default: []
|
20
|
+
class_attribute :c_list_order
|
21
|
+
class_attribute :c_select, default: 'count(*) as count'
|
22
|
+
class_attribute :c_summary_fields, default: []
|
23
|
+
class_attribute :c_target_class
|
24
|
+
|
12
25
|
class << self
|
26
|
+
def inherited(base)
|
27
|
+
super
|
28
|
+
base.c_target_class = base.name.chomp('DrilldownController').constantize
|
29
|
+
end
|
30
|
+
|
13
31
|
def base_condition(base_condition)
|
14
|
-
|
32
|
+
self.c_base_condition = base_condition
|
15
33
|
end
|
16
34
|
|
17
35
|
def base_includes(base_includes)
|
18
|
-
|
36
|
+
self.c_base_includes = base_includes
|
19
37
|
end
|
20
38
|
|
21
39
|
def base_group(base_group)
|
22
|
-
|
40
|
+
self.c_base_group = base_group
|
23
41
|
end
|
24
42
|
|
25
|
-
def default_fields(
|
26
|
-
|
43
|
+
def default_fields(default_fields)
|
44
|
+
self.c_default_fields = default_fields
|
27
45
|
end
|
28
46
|
|
29
47
|
def target_class(target_class)
|
30
|
-
|
48
|
+
self.c_target_class = target_class
|
31
49
|
end
|
32
50
|
|
33
51
|
def select(select)
|
34
|
-
|
52
|
+
self.c_select = select
|
35
53
|
end
|
36
54
|
|
37
55
|
def list_includes(list_includes)
|
38
|
-
|
56
|
+
self.c_list_includes = list_includes
|
39
57
|
end
|
40
58
|
|
41
59
|
def list_order(list_order)
|
42
|
-
|
60
|
+
self.c_list_order = list_order
|
43
61
|
end
|
44
62
|
|
45
63
|
def field(name, **options)
|
46
|
-
|
47
|
-
@@fields[name] = options
|
64
|
+
c_fields[name] = options
|
48
65
|
end
|
49
66
|
|
50
67
|
def summary_fields(*summary_fields)
|
51
|
-
|
68
|
+
self.c_summary_fields = summary_fields
|
52
69
|
end
|
53
70
|
|
54
71
|
def dimension(name, select_expression = name, options = {})
|
@@ -74,9 +91,7 @@ module SimpleDrilldown
|
|
74
91
|
raise "Unknown options: #{query_opts.keys.inspect}" unless (query_opts.keys - %i[select includes where]).empty?
|
75
92
|
end
|
76
93
|
|
77
|
-
|
78
|
-
|
79
|
-
@@dimension_defs[name.to_s] = {
|
94
|
+
c_dimension_defs[name.to_s] = {
|
80
95
|
includes: queries.inject([]) do |a, e|
|
81
96
|
i = e[:includes]
|
82
97
|
next a unless i
|
@@ -101,7 +116,7 @@ module SimpleDrilldown
|
|
101
116
|
my_filter = search.filter.dup
|
102
117
|
my_filter.delete(field.to_s) unless preserve_filter
|
103
118
|
filter_conditions, _t, includes = make_conditions(my_filter)
|
104
|
-
dimension_def =
|
119
|
+
dimension_def = c_dimension_defs[field.to_s]
|
105
120
|
result_sets = dimension_def[:queries].map do |query|
|
106
121
|
if query[:includes]
|
107
122
|
if query[:includes].is_a?(Array)
|
@@ -111,11 +126,11 @@ module SimpleDrilldown
|
|
111
126
|
end
|
112
127
|
includes.uniq!
|
113
128
|
end
|
114
|
-
rows =
|
129
|
+
rows = c_target_class.unscoped.where(c_base_condition)
|
115
130
|
.select("#{query[:select]} AS value")
|
116
|
-
.where(filter_conditions)
|
117
|
-
.where(query[:where])
|
118
|
-
.joins(make_join([],
|
131
|
+
.where(filter_conditions || '1=1')
|
132
|
+
.where(query[:where] || '1=1')
|
133
|
+
.joins(make_join([], c_target_class.name.underscore.to_sym, includes))
|
119
134
|
.order('value')
|
120
135
|
.group(:value)
|
121
136
|
.to_a
|
@@ -137,14 +152,14 @@ module SimpleDrilldown
|
|
137
152
|
end
|
138
153
|
|
139
154
|
def make_conditions(search_filter)
|
140
|
-
includes =
|
155
|
+
includes = c_base_includes.dup
|
141
156
|
if search_filter
|
142
157
|
condition_strings = []
|
143
158
|
condition_values = []
|
144
159
|
|
145
160
|
filter_texts = []
|
146
161
|
search_filter.each do |field, values|
|
147
|
-
dimension_def =
|
162
|
+
dimension_def = c_dimension_defs[field]
|
148
163
|
raise "Unknown filter field: #{field.inspect}" if dimension_def.nil?
|
149
164
|
|
150
165
|
values = [*values]
|
@@ -254,24 +269,7 @@ module SimpleDrilldown
|
|
254
269
|
|
255
270
|
def initialize
|
256
271
|
super()
|
257
|
-
@
|
258
|
-
@default_fields = @@default_fields
|
259
|
-
@default_select_value = SimpleDrilldown::Search::SelectValue::COUNT
|
260
|
-
@target_class = @@target_class
|
261
|
-
@select = @@select
|
262
|
-
@@base_condition = '1 = 1' unless defined?(@@base_condition)
|
263
|
-
@base_condition = @@base_condition
|
264
|
-
@@base_includes = [] unless defined?(@@base_includes)
|
265
|
-
@base_includes = @@base_includes
|
266
|
-
@base_group = defined?(@@base_group) ? @@base_group : []
|
267
|
-
@@list_includes = [] unless defined?(@@list_includes)
|
268
|
-
@list_includes = @@list_includes
|
269
|
-
@list_order = @@list_order
|
270
|
-
@dimension_defs = @@dimension_defs
|
271
|
-
@@summary_fields = [] unless defined?(@@summary_fields)
|
272
|
-
@summary_fields = @@summary_fields
|
273
|
-
|
274
|
-
@history_fields = @fields.select { |_k, v| v[:list_change_times] }.map { |k, _v| k.to_s }
|
272
|
+
@history_fields = c_fields.select { |_k, v| v[:list_change_times] }.map { |k, _v| k.to_s }
|
275
273
|
end
|
276
274
|
|
277
275
|
# ?dimension[0]=supplier&dimension[1]=transaction_type&
|
@@ -279,18 +277,17 @@ module SimpleDrilldown
|
|
279
277
|
def index(do_render = true)
|
280
278
|
@search = new_search_object
|
281
279
|
|
282
|
-
@transaction_fields = (@search.fields + (
|
283
|
-
@transaction_fields_map = @fields
|
280
|
+
@transaction_fields = (@search.fields + (c_fields.keys.map(&:to_s) - @search.fields))
|
284
281
|
|
285
|
-
select =
|
286
|
-
includes =
|
282
|
+
select = c_select.dup
|
283
|
+
includes = c_base_includes.dup
|
287
284
|
|
288
285
|
@dimensions = []
|
289
|
-
select << ", 'All'::text as value0"
|
286
|
+
select << ", 'All'#{'::text' if c_target_class.connection.adapter_name == 'PostgreSQL'} as value0"
|
290
287
|
@dimensions += @search.dimensions.map do |dn|
|
291
|
-
raise "Unknown distribution field: #{dn.inspect}" if
|
288
|
+
raise "Unknown distribution field: #{dn.inspect}" if c_dimension_defs[dn].nil?
|
292
289
|
|
293
|
-
|
290
|
+
c_dimension_defs[dn]
|
294
291
|
end
|
295
292
|
@dimensions.each_with_index do |d, i|
|
296
293
|
select << ", #{d[:select_expression]} as value#{i + 1}"
|
@@ -315,18 +312,18 @@ module SimpleDrilldown
|
|
315
312
|
order = (1..@dimensions.size).map { |i| "value#{i}" }.join(',')
|
316
313
|
order = nil if order.empty?
|
317
314
|
end
|
318
|
-
group = (
|
315
|
+
group = (c_base_group + (1..@dimensions.size).map { |i| "value#{i}" }).join(',')
|
319
316
|
group = nil if group.empty?
|
320
317
|
|
321
|
-
joins = self.class.make_join([],
|
322
|
-
rows =
|
323
|
-
|
324
|
-
|
325
|
-
|
318
|
+
joins = self.class.make_join([], c_target_class.name.underscore.to_sym, includes)
|
319
|
+
rows = c_target_class.unscoped.where(c_base_condition).select(select).where(conditions)
|
320
|
+
.joins(joins)
|
321
|
+
.group(group)
|
322
|
+
.order(order).to_a
|
326
323
|
|
327
324
|
if rows.empty?
|
328
325
|
@result = { value: 'All', count: 0, row_count: 0, nodes: 0, rows: [] }
|
329
|
-
|
326
|
+
c_summary_fields.each { |f| @result[f] = 0 }
|
330
327
|
else
|
331
328
|
if do_render && @search.list && rows.inject(0) { |sum, r| sum + r[:count].to_i } > LIST_LIMIT
|
332
329
|
@search.list = false
|
@@ -335,9 +332,9 @@ module SimpleDrilldown
|
|
335
332
|
@result = result_from_rows(rows, 0, 0, ['All'])
|
336
333
|
end
|
337
334
|
|
338
|
-
remove_duplicates(@result) unless
|
335
|
+
remove_duplicates(@result) unless c_base_group.empty?
|
339
336
|
|
340
|
-
@remaining_dimensions =
|
337
|
+
@remaining_dimensions = c_dimension_defs.dup
|
341
338
|
@remaining_dimensions.each_key do |dim_name|
|
342
339
|
if (@search.filter[dim_name] && @search.filter[dim_name].size == 1) ||
|
343
340
|
(@dimensions.any? { |d| d[:url_param_name] == dim_name })
|
@@ -352,9 +349,9 @@ module SimpleDrilldown
|
|
352
349
|
def choices
|
353
350
|
@search = new_search_object
|
354
351
|
dimension_name = params[:dimension_name]
|
355
|
-
dimension =
|
352
|
+
dimension = c_dimension_defs[dimension_name]
|
356
353
|
selected = @search.filter[dimension_name] || []
|
357
|
-
raise "Unknown dimension #{dimension_name.inspect}: #{
|
354
|
+
raise "Unknown dimension #{dimension_name.inspect}: #{c_dimension_defs.keys.inspect}" unless dimension
|
358
355
|
|
359
356
|
choices = [[t(:all), nil]] +
|
360
357
|
(dimension[:legal_values]&.call(@search)&.map { |o| o.is_a?(Array) ? o[0..1].map(&:to_s) : o.to_s } || [])
|
@@ -398,7 +395,7 @@ module SimpleDrilldown
|
|
398
395
|
private
|
399
396
|
|
400
397
|
def new_search_object
|
401
|
-
SimpleDrilldown::Search.new(params[:search]&.to_unsafe_h,
|
398
|
+
SimpleDrilldown::Search.new(params[:search]&.to_unsafe_h, c_default_fields, c_default_select_value)
|
402
399
|
end
|
403
400
|
|
404
401
|
def remove_duplicates(result)
|
@@ -411,7 +408,7 @@ module SimpleDrilldown
|
|
411
408
|
if prev_row
|
412
409
|
if prev_row[:value] == r[:value]
|
413
410
|
prev_row[:count] += r[:count]
|
414
|
-
|
411
|
+
c_summary_fields.each do |f|
|
415
412
|
prev_row[f] += r[f]
|
416
413
|
end
|
417
414
|
prev_row[:row_count] = [prev_row[:row_count], r[:row_count]].max
|
@@ -449,7 +446,7 @@ module SimpleDrilldown
|
|
449
446
|
row_count: 0,
|
450
447
|
nodes: 0
|
451
448
|
}
|
452
|
-
|
449
|
+
c_summary_fields.each { |f| sub_result[f] = 0 }
|
453
450
|
sub_result[:rows] = add_zero_results([], dimension + 1) if dimension < @dimensions.size - 1
|
454
451
|
result_rows << sub_result
|
455
452
|
end
|
@@ -472,7 +469,7 @@ module SimpleDrilldown
|
|
472
469
|
row_count: 1,
|
473
470
|
nodes: @search.list ? 2 : 1
|
474
471
|
}
|
475
|
-
|
472
|
+
c_summary_fields.each { |f| result[f] = row[f].to_i }
|
476
473
|
return result
|
477
474
|
end
|
478
475
|
|
@@ -495,7 +492,7 @@ module SimpleDrilldown
|
|
495
492
|
nodes: result_rows.inject(0) { |t, r| t + r[:nodes] } + 1,
|
496
493
|
rows: result_rows
|
497
494
|
}
|
498
|
-
|
495
|
+
c_summary_fields.each { |f| result[f] = result_rows.inject(0) { |t, r| t + r[f] } }
|
499
496
|
result
|
500
497
|
end
|
501
498
|
|
@@ -505,9 +502,9 @@ module SimpleDrilldown
|
|
505
502
|
populate_list(conditions, includes, r, values + [r[:value]])
|
506
503
|
end
|
507
504
|
else
|
508
|
-
list_includes = includes +
|
505
|
+
list_includes = includes + c_list_includes
|
509
506
|
@search.fields.each do |field|
|
510
|
-
field_def =
|
507
|
+
field_def = c_fields[field.to_sym]
|
511
508
|
raise "Field definition missing for: #{field.inspect}" unless field_def
|
512
509
|
|
513
510
|
field_includes = field_def[:include]
|
@@ -521,9 +518,9 @@ module SimpleDrilldown
|
|
521
518
|
list_includes << { assignment: { order: :"#{f}_changes" } } if @search.fields.include? f
|
522
519
|
end
|
523
520
|
end
|
524
|
-
joins = self.class.make_join([],
|
521
|
+
joins = self.class.make_join([], c_target_class.name.underscore.to_sym, list_includes)
|
525
522
|
list_conditions = list_conditions(conditions, values)
|
526
|
-
base_query =
|
523
|
+
base_query = c_target_class.unscoped.where(c_base_condition).joins(joins).order(@list_order)
|
527
524
|
base_query = base_query.where(list_conditions) if list_conditions
|
528
525
|
result[:transactions] = base_query.to_a
|
529
526
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'chartkick'
|
4
|
+
|
3
5
|
module SimpleDrilldown
|
4
6
|
class Engine < ::Rails::Engine
|
5
7
|
isolate_namespace SimpleDrilldown
|
8
|
+
config.autoload_paths << File.dirname(__dir__)
|
6
9
|
|
7
10
|
initializer 'simple_drilldown.assets.precompile' do |app|
|
8
11
|
app.config.assets.precompile += %w[chartkick.js]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_drilldown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uwe Kubosch
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chartkick
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/generators/drilldown_controller/USAGE
|
124
124
|
- lib/generators/drilldown_controller/drilldown_controller_generator.rb
|
125
125
|
- lib/generators/drilldown_controller/templates/drilldown_controller.rb.erb
|
126
|
+
- lib/generators/drilldown_controller/templates/drilldown_controller_test.rb.erb
|
126
127
|
- lib/simple_drilldown.rb
|
127
128
|
- lib/simple_drilldown/drilldown_controller.rb
|
128
129
|
- lib/simple_drilldown/drilldown_helper.rb
|
@@ -136,7 +137,7 @@ licenses:
|
|
136
137
|
- MIT
|
137
138
|
metadata:
|
138
139
|
allowed_push_host: https://rubygems.org/
|
139
|
-
post_install_message:
|
140
|
+
post_install_message:
|
140
141
|
rdoc_options: []
|
141
142
|
require_paths:
|
142
143
|
- lib
|
@@ -152,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
153
|
version: '0'
|
153
154
|
requirements: []
|
154
155
|
rubygems_version: 3.1.2
|
155
|
-
signing_key:
|
156
|
+
signing_key:
|
156
157
|
specification_version: 4
|
157
158
|
summary: Simple data warehouse and drilldown.
|
158
159
|
test_files: []
|