effective_datatables 2.0.4 → 2.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 104ed4736f57500cb86aaa07631d96aa36b4df8d
4
- data.tar.gz: 800891f688c2e363b19336e19896ba0fa5900ecb
3
+ metadata.gz: e5dd14893bb1a01f311ccb678ab2ab199177d7c6
4
+ data.tar.gz: 0dca76ae65b7c576ccdb3bdb2eba5e30ab00b44d
5
5
  SHA512:
6
- metadata.gz: 1b70a5c78893a581b4db8bc277196c37e19b5fe1d4ea2eb5025868aee2512e071b8cfb9ce1ef0f3ec4f8e2ffb1ba363eae7c6d24db6fd7291838c653b2076fb9
7
- data.tar.gz: 066e62e1d2a348dfe780f59b2405284c7707a00985ed3db03166b542e8ddce4fe82110ea3feddc911241489f47411026c490271627c6cff7985b696e1a0484c7
6
+ metadata.gz: 34f5a501b53fa8be7ce46dd44522b045534e4c8e6c51c68c2b77f03e3326b09bf8d7fdea6e7fb27949607b4b5e9dd3a21d7f49bee22fea48b62bbb2ec635f5fc
7
+ data.tar.gz: f2bf133e9d2b309d4eb199a61fbb402138c7f945879796832237541b36759592728486497269d2b4448b9437e8f12edbc9f4980d0297f849583c44f252523ea1
data/README.md CHANGED
@@ -346,6 +346,7 @@ Some additional, lesser used options include:
346
346
 
347
347
  ```ruby
348
348
  :filter => {:fuzzy => true} # Will use an ILIKE/includes rather than = when filtering. Use this for selects.
349
+ :filter => {sql_operation => :having} # Will use .having() instead of .where() to handle aggregate columns (autodetected)
349
350
  ```
350
351
 
351
352
  ### Rendering Options
@@ -38,13 +38,14 @@ module Effective
38
38
 
39
39
  def search_column_with_defaults(collection, table_column, term)
40
40
  column = table_column[:column]
41
+ sql_op = table_column[:filter][:sql_operation] || :where # only other option is :having
41
42
 
42
43
  case table_column[:type]
43
44
  when :string, :text
44
- if table_column[:filter][:type] == :select && table_column[:filter][:fuzzy] != true
45
- collection.where("#{column} = :term", term: term)
45
+ if (table_column[:filter][:type] == :select && table_column[:filter][:fuzzy] != true) || sql_op != :where
46
+ collection.public_send(sql_op, "#{column} = :term", term: term)
46
47
  else
47
- collection.where("#{column} ILIKE :term", term: "%#{term}%")
48
+ collection.public_send(sql_op, "#{column} ILIKE :term", term: "%#{term}%")
48
49
  end
49
50
  when :has_many
50
51
  inverse_ids = term.split(',').map { |term| (term = term.to_i) == 0 ? nil : term }.compact
@@ -61,7 +62,15 @@ module Effective
61
62
 
62
63
  ids = klass.where(id: inverse_ids).joins(inverse.name).pluck(inverse.foreign_key)
63
64
 
64
- collection.where(id: ids)
65
+ collection.public_send(sql_op, id: ids)
66
+ when :obfuscated_id
67
+ if (deobfuscated_id = collection.deobfuscate(term)) == term # We weren't able to deobfuscate it, so this is an Invalid ID
68
+ collection.public_send(sql_op, "#{column} = :term", term: 0)
69
+ else
70
+ collection.public_send(sql_op, "#{column} = :term", term: deobfuscated_id)
71
+ end
72
+ when :effective_roles
73
+ collection.with_role(term)
65
74
  when :datetime, :date
66
75
  begin
67
76
  digits = term.scan(/(\d+)/).flatten.map(&:to_i)
@@ -84,29 +93,21 @@ module Effective
84
93
  end_at = start_at
85
94
  end
86
95
 
87
- collection.where("#{column} >= :start_at AND #{column} <= :end_at", start_at: start_at, end_at: end_at)
96
+ collection.public_send(sql_op, "#{column} >= :start_at AND #{column} <= :end_at", start_at: start_at, end_at: end_at)
88
97
  rescue => e
89
98
  collection
90
99
  end
91
- when :obfuscated_id
92
- if (deobfuscated_id = collection.deobfuscate(term)) == term # We weren't able to deobfuscate it, so this is an Invalid ID
93
- collection.where("#{column} = :term", term: 0)
94
- else
95
- collection.where("#{column} = :term", term: deobfuscated_id)
96
- end
97
- when :effective_roles
98
- collection.with_role(term)
99
100
  when :integer
100
- collection.where("#{column} = :term", term: term.to_i)
101
+ collection.public_send(sql_op, "#{column} = :term", term: term.to_i)
101
102
  when :year
102
- collection.where("EXTRACT(YEAR FROM #{column}) = :term", term: term.to_i)
103
+ collection.public_send(sql_op, "EXTRACT(YEAR FROM #{column}) = :term", term: term.to_i)
103
104
  when :price
104
105
  price_in_cents = (term.gsub(/[^0-9|\.]/, '').to_f * 100.0).to_i
105
- collection.where("#{column} = :term", term: price_in_cents)
106
+ collection.public_send(sql_op, "#{column} = :term", term: price_in_cents)
106
107
  when :currency
107
- collection.where("#{column} = :term", term: term.gsub(/[^0-9|\.]/, '').to_f)
108
+ collection.public_send(sql_op, "#{column} = :term", term: term.gsub(/[^0-9|\.]/, '').to_f)
108
109
  else
109
- collection.where("#{column} = :term", term: term)
110
+ collection.public_send(sql_op, "#{column} = :term", term: term)
110
111
  end
111
112
  end
112
113
 
@@ -87,7 +87,7 @@ module Effective
87
87
  cols[name][:sql_as_column] = true
88
88
  end
89
89
 
90
- cols[name][:filter] = initialize_table_column_filter(cols[name][:filter], cols[name][:type], belong_tos[name], has_manys[name])
90
+ cols[name][:filter] = initialize_table_column_filter(cols[name], belong_tos[name], has_manys[name])
91
91
 
92
92
  if cols[name][:partial]
93
93
  cols[name][:partial_local] ||= (sql_table.try(:name) || cols[name][:partial].split('/').last(2).first.presence || 'obj').singularize.to_sym
@@ -102,7 +102,11 @@ module Effective
102
102
 
103
103
  end
104
104
 
105
- def initialize_table_column_filter(filter, col_type, belongs_to, has_many)
105
+ def initialize_table_column_filter(column, belongs_to, has_many)
106
+ filter = column[:filter]
107
+ col_type = column[:type]
108
+ sql_column = column[:column].to_s.upcase
109
+
106
110
  return {type: :null} if filter == false
107
111
 
108
112
  filter = {type: filter.to_sym} if filter.kind_of?(String)
@@ -111,17 +115,22 @@ module Effective
111
115
  # This is a fix for passing filter[:selected] == false, it needs to be 'false'
112
116
  filter[:selected] = filter[:selected].to_s unless filter[:selected].nil?
113
117
 
118
+ # Check if this is an aggregate column
119
+ if ['SUM(', 'COUNT(', 'MAX(', 'MIN(', 'AVG('].any? { |str| sql_column.include?(str) }
120
+ filter[:sql_operation] = :having
121
+ end
122
+
114
123
  case col_type
115
124
  when :belongs_to
116
125
  {
117
126
  type: :select,
118
- values: Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
127
+ values: Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[0] <=> y[0] } }
119
128
  }
120
129
  when :has_many
121
130
  {
122
131
  type: :select,
123
132
  multiple: true,
124
- values: Proc.new { has_many[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
133
+ values: Proc.new { has_many[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[0] <=> y[0] } }
125
134
  }
126
135
  when :effective_roles
127
136
  {type: :select, values: EffectiveRoles.roles}
@@ -95,27 +95,32 @@ module Effective
95
95
  elsif opts[:type] == :belongs_to
96
96
  (obj.send(name) rescue nil).to_s
97
97
  elsif opts[:type] == :has_many
98
- objs = (obj.send(name).map(&:to_s).sort rescue [])
98
+ objs = (obj.send(name).map { |x| x.to_s }.sort rescue [])
99
99
  objs.length == 1 ? objs.first : (opts[:sentence] ? objs.to_sentence : objs.join('<br>'))
100
100
  elsif opts[:type] == :obfuscated_id
101
101
  (obj.send(:to_param) rescue nil).to_s
102
102
  elsif opts[:type] == :effective_roles
103
103
  (obj.send(:roles) rescue []).join(', ')
104
- elsif opts[:type] == :datetime
105
- (obj.send(name).strftime(EffectiveDatatables.datetime_format) rescue nil)
106
- elsif opts[:type] == :date
107
- (obj.send(name).strftime(EffectiveDatatables.date_format) rescue nil)
108
- elsif opts[:type] == :price
109
- # This is price_to_currency from effective_form_inputs retyped...
110
- price = ((obj.send(name) || 0) rescue 0)
111
- raise 'column type: price expects an Integer representing the number of cents' unless price.kind_of?(Integer)
112
- number_to_currency(price / 100.0)
113
- elsif opts[:type] == :currency
114
- number_to_currency(((obj.send(name) || 0) rescue 0))
115
104
  else
116
- obj.send(name) rescue (obj[opts[:array_index]] rescue nil)
105
+ # Normal value, but we still may want to format it
106
+ value = (obj.send(name) rescue nil) || (obj[name] rescue nil) || (obj[opts[:array_index]] rescue nil)
107
+
108
+ case opts[:type]
109
+ when :datetime
110
+ value.strftime(EffectiveDatatables.datetime_format) rescue nil
111
+ when :date
112
+ value.strftime(EffectiveDatatables.date_format) rescue nil
113
+ when :price
114
+ # This is an integer value, "number of cents"
115
+ value ||= 0
116
+ raise 'column type: price expects an Integer representing the number of cents' unless value.kind_of?(Integer)
117
+ number_to_currency(value / 100.0)
118
+ when :currency
119
+ number_to_currency(value || 0)
120
+ else
121
+ value
122
+ end
117
123
  end
118
-
119
124
  end
120
125
  end
121
126
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '2.0.4'.freeze
2
+ VERSION = '2.0.5'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_datatables
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-20 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails