simple_drilldown 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9994fb706e46554bec7e26a9191cdc10e2675a19770e4414019f5b4a067e7daf
4
- data.tar.gz: 874f30d58de361193d6faed89b2af82e8899b0c628861865b917af9466faa64d
3
+ metadata.gz: 3a69810eb60aa499744a6989bad20efed263b05fc51dfcb094f151494deacbad
4
+ data.tar.gz: e3402d01f9a8a19683c6c4095fa47725eede9dda5434ff2dd9a43cb5d5e75643
5
5
  SHA512:
6
- metadata.gz: 61559d0c5e2f91474c86bbb3424c55e41d4fb355921a06cd3b4627ea1ab72a789be74989e53135b7179ea3b59feec83d140ed4e681fb85f111f0f024017a169d
7
- data.tar.gz: 8bed5fd23fb6254bf5280ddce378738294af1bf5de119da11000695a3c594e48797b9f820987ef4296ed94ac6a680075f20924a6d6473702f7b05c7fe120af34
6
+ metadata.gz: 7701b13e4ee048dd707b9e5a787e2081932ad301cb62eb028e770033664a6d7696267fd2a409a79a540db73a06026305b2bd2eee597fdd8196c7568db161d2f6
7
+ data.tar.gz: 5a9a820ecee0516f76bebb0a3ce64325a80e0e3f71f4855b2529ab07b451cf87db2148544114343f40d5f35e624bf5bac8c614ca600642ca8127b62f6ffc072c
@@ -3,9 +3,8 @@
3
3
  <%= form.text_field :title, class: 'form-control' %>
4
4
  </div>
5
5
 
6
- <% choices = Concurrent::Hash.new %>
7
6
  <% 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] || [],
7
+ <% choices = [[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 } || []) %>
8
+ <%= render partial: 'drilldown/field', locals: { choices: choices || [],
10
9
  form: form, dimension_name: dimension_name } %>
11
10
  <% end %>
@@ -6,3 +6,4 @@ Example:
6
6
 
7
7
  This will create:
8
8
  app/controllers/thing_drilldown_controller.rb
9
+ test/controllers/thing_drilldown_controller_test.rb
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'simple_drilldown/drilldown_controller'
3
+ require 'simple_drilldown/controller'
4
4
 
5
- class <%= class_name %>DrilldownController < SimpleDrilldown::DrilldownController
5
+ class <%= class_name %>DrilldownController < SimpleDrilldown::Controller
6
6
  # The main focus of the drilldown
7
7
  # target_class <%= class_name %>
8
8
 
@@ -4,7 +4,7 @@ require 'simple_drilldown/drilldown_helper'
4
4
  require 'simple_drilldown/search'
5
5
 
6
6
  module SimpleDrilldown
7
- class DrilldownController < ::ApplicationController
7
+ class Controller < ::ApplicationController
8
8
  helper DrilldownHelper
9
9
 
10
10
  LIST_LIMIT = 10_000
@@ -14,8 +14,8 @@ module SimpleDrilldown
14
14
  class_attribute :c_base_includes, default: []
15
15
  class_attribute :c_default_fields, default: []
16
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: {}
17
+ class_attribute :c_dimension_defs
18
+ class_attribute :c_fields
19
19
  class_attribute :c_list_includes, default: []
20
20
  class_attribute :c_list_order
21
21
  class_attribute :c_select, default: 'count(*) as count'
@@ -25,7 +25,16 @@ module SimpleDrilldown
25
25
  class << self
26
26
  def inherited(base)
27
27
  super
28
- base.c_target_class = base.name.chomp('DrilldownController').constantize
28
+ base.c_dimension_defs = Concurrent::Hash.new
29
+ base.c_fields = {}
30
+ begin
31
+ base.c_target_class = base.name.chomp('DrilldownController').constantize
32
+ rescue NameError
33
+ begin
34
+ base.c_target_class = base.name.chomp('Controller').constantize
35
+ rescue NameError
36
+ end
37
+ end
29
38
  end
30
39
 
31
40
  def base_condition(base_condition)
@@ -41,7 +50,11 @@ module SimpleDrilldown
41
50
  end
42
51
 
43
52
  def default_fields(default_fields)
44
- self.c_default_fields = default_fields
53
+ self.c_default_fields = default_fields.flatten
54
+ end
55
+
56
+ def default_select_value(default_select_value)
57
+ self.c_default_select_value = default_select_value
45
58
  end
46
59
 
47
60
  def target_class(target_class)
@@ -53,7 +66,7 @@ module SimpleDrilldown
53
66
  end
54
67
 
55
68
  def list_includes(list_includes)
56
- self.c_list_includes = list_includes
69
+ self.c_list_includes = list_includes.flatten
57
70
  end
58
71
 
59
72
  def list_order(list_order)
@@ -65,7 +78,7 @@ module SimpleDrilldown
65
78
  end
66
79
 
67
80
  def summary_fields(*summary_fields)
68
- self.c_summary_fields = summary_fields
81
+ self.c_summary_fields = summary_fields.flatten
69
82
  end
70
83
 
71
84
  def dimension(name, select_expression = name, options = {})
@@ -92,12 +105,19 @@ module SimpleDrilldown
92
105
  end
93
106
 
94
107
  c_dimension_defs[name.to_s] = {
95
- includes: queries.inject([]) do |a, e|
108
+ includes: queries.inject(nil) do |a, e|
96
109
  i = e[:includes]
97
110
  next a unless i
98
- next a if a.include?(i)
111
+ next a if a&.include?(i)
99
112
 
100
- a + [i]
113
+ case a
114
+ when nil
115
+ i
116
+ when Symbol
117
+ [a, *i]
118
+ else
119
+ a.concat(*i)
120
+ end
101
121
  end,
102
122
  interval: interval,
103
123
  label_method: label_method,
@@ -217,9 +237,9 @@ module SimpleDrilldown
217
237
  when Hash
218
238
  sql = +''
219
239
  include.each do |parent, child|
220
- sql << make_join(joins, model, parent) + ' '
240
+ sql << ' ' + make_join(joins, model, parent)
221
241
  ass = model.to_s.camelize.constantize.reflect_on_association parent
222
- sql << make_join(joins, parent, child, ass.class_name.constantize)
242
+ sql << ' ' + make_join(joins, parent, child, ass.class_name.constantize)
223
243
  end
224
244
  sql
225
245
  when Symbol
@@ -498,31 +518,69 @@ module SimpleDrilldown
498
518
 
499
519
  def populate_list(conditions, includes, result, values)
500
520
  if result[:rows]
501
- result[:rows].each do |r|
502
- populate_list(conditions, includes, r, values + [r[:value]])
521
+ return result[:rows].each { |r| populate_list(conditions, includes, r, values + [r[:value]]) }
522
+ end
523
+ list_includes = merge_includes(includes, c_list_includes)
524
+ @search.fields.each do |field|
525
+ field_def = c_fields[field.to_sym]
526
+ raise "Field definition missing for: #{field.inspect}" unless field_def
527
+
528
+ field_includes = field_def[:include]
529
+ if field_includes
530
+ list_includes = merge_includes(list_includes , field_includes)
503
531
  end
504
- else
505
- list_includes = includes + c_list_includes
506
- @search.fields.each do |field|
507
- field_def = c_fields[field.to_sym]
508
- raise "Field definition missing for: #{field.inspect}" unless field_def
509
-
510
- field_includes = field_def[:include]
511
- if field_includes
512
- list_includes += field_includes.is_a?(Array) ? field_includes : [field_includes]
532
+ end
533
+ if @search.list_change_times
534
+ @history_fields.each do |f|
535
+ if @search.fields.include? f
536
+ list_includes = merge_includes(list_includes, assignment: { order: :"#{f}_changes" } )
513
537
  end
514
538
  end
515
- list_includes.uniq!
516
- if @search.list_change_times
517
- @history_fields.each do |f|
518
- list_includes << { assignment: { order: :"#{f}_changes" } } if @search.fields.include? f
519
- end
539
+ end
540
+ joins = self.class.make_join([], c_target_class.name.underscore.to_sym, list_includes)
541
+ list_conditions = list_conditions(conditions, values)
542
+ base_query = c_target_class.unscoped.where(c_base_condition).joins(joins).order(@list_order)
543
+ base_query = base_query.where(list_conditions) if list_conditions
544
+ result[:transactions] = base_query.to_a
545
+ end
546
+
547
+ def merge_includes(*args)
548
+ hash = hash_includes(*args)
549
+ result = hash.dup.map { |k, v|
550
+ if v.blank?
551
+ hash.delete(k)
552
+ k
553
+ end
554
+ }.compact
555
+ result << hash unless hash.blank?
556
+ case result.size
557
+ when 0
558
+ nil
559
+ when 1
560
+ result[0]
561
+ else
562
+ result
563
+ end
564
+ end
565
+
566
+ def hash_includes(*args)
567
+ args.inject({}) do |h, inc|
568
+ case inc
569
+ when Array
570
+ inc.each { |v|
571
+ h = hash_includes(h, v)
572
+ }
573
+ when Hash
574
+ inc.each { |k, v|
575
+ h[k] = merge_includes(h[k], v)
576
+ }
577
+ when NilClass, FalseClass
578
+ when String, Symbol
579
+ h[inc] ||= []
580
+ else
581
+ raise "Unknown include type: #{inc.inspect}"
520
582
  end
521
- joins = self.class.make_join([], c_target_class.name.underscore.to_sym, list_includes)
522
- list_conditions = list_conditions(conditions, values)
523
- base_query = c_target_class.unscoped.where(c_base_condition).joins(joins).order(@list_order)
524
- base_query = base_query.where(list_conditions) if list_conditions
525
- result[:transactions] = base_query.to_a
583
+ h
526
584
  end
527
585
  end
528
586
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  module SimpleDrilldown
4
4
  # View helper for SimpleDrilldown
5
+ # FIXME(uwe): Rename to Helper
5
6
  module DrilldownHelper
6
7
  def value_label(dimension_index, value)
7
8
  dimension = @dimensions[dimension_index]
@@ -11,7 +12,7 @@ module SimpleDrilldown
11
12
  end
12
13
 
13
14
  def caption
14
- result = @search.title || "#{@target_class} #{t(@search.select_value.downcase)}" +
15
+ result = @search.title || "#{controller.c_target_class} #{t(@search.select_value.downcase)}" +
15
16
  (@dimensions && @dimensions.any? ? ' by ' + @dimensions.map { |d| d[:pretty_name] }.join(' and ') : '')
16
17
  result.gsub('$date', [*@search.filter[:calendar_date]].uniq.join(' - '))
17
18
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'chartkick'
4
+ require 'simple_drilldown/routing'
4
5
 
5
6
  module SimpleDrilldown
6
7
  class Engine < ::Rails::Engine
@@ -10,5 +11,7 @@ module SimpleDrilldown
10
11
  initializer 'simple_drilldown.assets.precompile' do |app|
11
12
  app.config.assets.precompile += %w[chartkick.js]
12
13
  end
14
+
15
+ ActionDispatch::Routing::Mapper.include SimpleDrilldown::Routing
13
16
  end
14
17
  end
@@ -6,7 +6,7 @@ module SimpleDrilldown
6
6
  def draw_drilldown(path, controller = path)
7
7
  get "#{path}(.:format)" => "#{controller}#index", as: path
8
8
  scope path do
9
- %i[excel_export html_export index].each do |action|
9
+ %i[choices excel_export html_export index].each do |action|
10
10
  get "#{action}(/:id)(.:format)", controller: controller, action: action
11
11
  end
12
12
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleDrilldown
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
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.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uwe Kubosch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-12 00:00:00.000000000 Z
11
+ date: 2020-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -125,7 +125,7 @@ files:
125
125
  - lib/generators/drilldown_controller/templates/drilldown_controller.rb.erb
126
126
  - lib/generators/drilldown_controller/templates/drilldown_controller_test.rb.erb
127
127
  - lib/simple_drilldown.rb
128
- - lib/simple_drilldown/drilldown_controller.rb
128
+ - lib/simple_drilldown/controller.rb
129
129
  - lib/simple_drilldown/drilldown_helper.rb
130
130
  - lib/simple_drilldown/engine.rb
131
131
  - lib/simple_drilldown/routing.rb