datagrid 2.0.5 → 2.0.8
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/CHANGELOG.md +45 -0
- data/lib/datagrid/columns.rb +3 -0
- data/lib/datagrid/core.rb +17 -6
- data/lib/datagrid/drivers/active_record.rb +30 -18
- data/lib/datagrid/filters/base_filter.rb +5 -2
- data/lib/datagrid/filters/date_filter.rb +3 -1
- data/lib/datagrid/filters/dynamic_filter.rb +5 -1
- data/lib/datagrid/filters.rb +3 -0
- data/lib/datagrid/helper.rb +1 -1
- data/lib/datagrid/utils.rb +4 -2
- data/lib/datagrid/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f5ac6077bea5b3ee95001a94f7c862a2430dec10d5d35602ac763ad748b2bd6f
|
|
4
|
+
data.tar.gz: 86a7e62eebc8044e215708ce2aa29f63955e5c7c0635a4e48e1e41f35bffc291
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3f695cc908307c31ae745621b6afe99ef86422b685549d3084e9b5610c7420eea8c0de9318a25849f0e0042bdc0c95d11b6163ebf0d01ea1b4d62d6de8bd2b81
|
|
7
|
+
data.tar.gz: 3fe0c0cde94487679ec67ba563b8668f26fa4f977700a25ae58c35a1908bdc73d1558b83a4593eaaf51810844baa26e99e834f7a280edae01ad55f6bc83c3051
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.8]
|
|
4
|
+
|
|
5
|
+
* Rescue StatementInvalid when guessing column type from a query
|
|
6
|
+
* Prevent typecasting of date into timestamp when `:date` filter has a block
|
|
7
|
+
|
|
8
|
+
``` ruby
|
|
9
|
+
class MyGrid < Datagrid::Base
|
|
10
|
+
scope { User }
|
|
11
|
+
|
|
12
|
+
filter(:created_at, :date) do |scope, value|
|
|
13
|
+
value.is_a?(Date) # => true
|
|
14
|
+
scope.joins(:registration).where(registrations: { registration_date: value })
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## [2.0.7]
|
|
20
|
+
|
|
21
|
+
* Raise `Datagrid::ConfigurationError` when column or filter name
|
|
22
|
+
specified in `before` or `after` option not found.
|
|
23
|
+
* Fixed `as_query` method when dynamic filter is used. Fixes [#344](https://github.com/bogdan/datagrid/issues/344)
|
|
24
|
+
|
|
25
|
+
``` ruby
|
|
26
|
+
grid = ProductsGrid.new(category: 'dresses', available: true, condition: ["price", ">=", 25])
|
|
27
|
+
# Before
|
|
28
|
+
grid.as_query
|
|
29
|
+
# => {
|
|
30
|
+
# category: 'dresses',
|
|
31
|
+
# available: true,
|
|
32
|
+
# condition: #<Object>
|
|
33
|
+
# }
|
|
34
|
+
# After
|
|
35
|
+
grid.as_query
|
|
36
|
+
# => {
|
|
37
|
+
# "category" => 'dresses',
|
|
38
|
+
# "available" => true,
|
|
39
|
+
# "condition" => { "field" => "price", "operation" => ">=", "value" => "25" }
|
|
40
|
+
# }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## [2.0.6]
|
|
45
|
+
|
|
46
|
+
* Validate dummy filter can not accept block
|
|
47
|
+
|
|
3
48
|
## [2.0.5]
|
|
4
49
|
|
|
5
50
|
* Add support for timestamptz ActiveRecord column type
|
data/lib/datagrid/columns.rb
CHANGED
|
@@ -378,6 +378,9 @@ module Datagrid
|
|
|
378
378
|
end
|
|
379
379
|
|
|
380
380
|
position = Datagrid::Utils.extract_position_from_options(columns, options)
|
|
381
|
+
unless position
|
|
382
|
+
raise Datagrid::ConfigurationError, "#{self}##{options[:before] || options[:after]} column not found"
|
|
383
|
+
end
|
|
381
384
|
column = Datagrid::Columns::Column.new(
|
|
382
385
|
self, name, query, options, &block
|
|
383
386
|
)
|
data/lib/datagrid/core.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "datagrid/drivers"
|
|
4
4
|
require "active_support/core_ext/class/attribute"
|
|
5
|
+
require "active_support/core_ext/object/json"
|
|
5
6
|
require "active_model/attribute_assignment"
|
|
6
7
|
|
|
7
8
|
module Datagrid
|
|
@@ -210,16 +211,15 @@ module Datagrid
|
|
|
210
211
|
scope
|
|
211
212
|
end
|
|
212
213
|
|
|
213
|
-
# @return [Hash{
|
|
214
|
+
# @return [Hash{String => Object}] serializable query arguments skipping all nil values
|
|
214
215
|
# @example
|
|
215
216
|
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
|
216
217
|
# grid.as_query # => {category: 'dresses', available: true}
|
|
217
218
|
def as_query
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
self.attributes.reduce({}) do |result, (k,v)|
|
|
220
|
+
result[k.to_s] = v.as_json unless v.nil?
|
|
221
|
+
result
|
|
221
222
|
end
|
|
222
|
-
attributes
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
# @return [Hash{Symbol => Hash{Symbol => Object}}] query parameters to link this grid from a page
|
|
@@ -228,7 +228,18 @@ module Datagrid
|
|
|
228
228
|
# Rails.application.routes.url_helpers.products_path(grid.query_params)
|
|
229
229
|
# # => "/products?products_grid[category]=dresses&products_grid[available]=true"
|
|
230
230
|
def query_params(attributes = {})
|
|
231
|
-
{ param_name.
|
|
231
|
+
{ param_name.to_s => as_query.merge(attributes.stringify_keys) }
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# @return [Hash{String => Object}] JSON representation of datagrid attributes
|
|
235
|
+
# @example
|
|
236
|
+
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
|
237
|
+
# grid.as_json # => {"category" => 'dresses', "available" => true}
|
|
238
|
+
def as_json(options = nil)
|
|
239
|
+
attributes.reduce({}) do |result, (k,v)|
|
|
240
|
+
result[k.to_s] = v.as_json(options)
|
|
241
|
+
result
|
|
242
|
+
end
|
|
232
243
|
end
|
|
233
244
|
|
|
234
245
|
# @return [void] redefines scope at instance level
|
|
@@ -31,12 +31,10 @@ module Datagrid
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def append_column_queries(assets, columns)
|
|
34
|
-
if columns.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
assets
|
|
34
|
+
return assets if columns.empty?
|
|
35
|
+
assets = assets.select(assets.klass.arel_table[Arel.star]) if assets.select_values.empty?
|
|
36
|
+
columns = columns.map { |c| "#{c.query} AS #{c.name}" }
|
|
37
|
+
assets.select(*columns)
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def where(scope, attribute, value)
|
|
@@ -88,20 +86,34 @@ module Datagrid
|
|
|
88
86
|
scope.where("#{field} #{contains_predicate} ?", "%#{value}%")
|
|
89
87
|
end
|
|
90
88
|
|
|
89
|
+
def builtin_type(scope, field)
|
|
90
|
+
if scope_has_column?(scope, field)
|
|
91
|
+
scope.columns_hash[field.to_s].type
|
|
92
|
+
else
|
|
93
|
+
begin
|
|
94
|
+
scope.connection.select_all(
|
|
95
|
+
scope.unscope(:select, :order).select(field => "custom_field").limit(0).arel
|
|
96
|
+
).column_types['custom_field']&.type
|
|
97
|
+
rescue ActiveRecord::StatementInvalid
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
91
103
|
def normalized_column_type(scope, field)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return value if keys.include?(builtin_type)
|
|
104
|
+
if builtin_type = builtin_type(scope, field)
|
|
105
|
+
{
|
|
106
|
+
%i[string text time binary] => :string,
|
|
107
|
+
%i[integer primary_key] => :integer,
|
|
108
|
+
%i[float decimal] => :float,
|
|
109
|
+
[:date] => :date,
|
|
110
|
+
%i[datetime timestamp timestamptz] => :timestamp,
|
|
111
|
+
[:boolean] => :boolean,
|
|
112
|
+
}.each do |keys, value|
|
|
113
|
+
return value if keys.include?(builtin_type)
|
|
114
|
+
end
|
|
104
115
|
end
|
|
116
|
+
nil
|
|
105
117
|
end
|
|
106
118
|
|
|
107
119
|
def batch_each(scope, batch_size, &block)
|
|
@@ -17,10 +17,13 @@ module Datagrid
|
|
|
17
17
|
self.name = name.to_sym
|
|
18
18
|
self.options = Datagrid::Utils.callable(grid_class.default_filter_options, self).merge(options)
|
|
19
19
|
self.block = block
|
|
20
|
+
if dummy? && block
|
|
21
|
+
raise Datagrid::ConfigurationError, "#{grid_class}##{name} filter is dummy and can not accept block"
|
|
22
|
+
end
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
def parse(value)
|
|
23
|
-
raise NotImplementedError, "#parse(value) suppose to be overwritten"
|
|
26
|
+
raise NotImplementedError, "#{self.class}#parse(value) suppose to be overwritten"
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
def default_input_options
|
|
@@ -32,7 +35,7 @@ module Datagrid
|
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def apply(grid_object, scope, value)
|
|
35
|
-
return scope if unapplicable_value?(value)
|
|
38
|
+
return scope if dummy? || unapplicable_value?(value)
|
|
36
39
|
|
|
37
40
|
result = execute(value, scope, grid_object)
|
|
38
41
|
|
|
@@ -12,7 +12,9 @@ module Datagrid
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def apply(grid_object, scope, value)
|
|
15
|
-
|
|
15
|
+
if !dummy? && !block && grid_object.driver.timestamp_column?(scope, name)
|
|
16
|
+
value = Datagrid::Utils.format_date_as_timestamp(value)
|
|
17
|
+
end
|
|
16
18
|
super
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -128,7 +128,7 @@ module Datagrid
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
def inspect
|
|
131
|
-
{
|
|
131
|
+
"#<#{self.class} #{to_h.inspect}>"
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
def to_ary
|
|
@@ -143,6 +143,10 @@ module Datagrid
|
|
|
143
143
|
{ field: field, operation: operation, value: value }
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
+
def as_json
|
|
147
|
+
{ "field" => field, "operation" => operation, "value" => value }
|
|
148
|
+
end
|
|
149
|
+
|
|
146
150
|
protected
|
|
147
151
|
|
|
148
152
|
def type_cast(type, value)
|
data/lib/datagrid/filters.rb
CHANGED
|
@@ -244,6 +244,9 @@ module Datagrid
|
|
|
244
244
|
raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
|
|
245
245
|
|
|
246
246
|
position = Datagrid::Utils.extract_position_from_options(filters_array, options)
|
|
247
|
+
unless position
|
|
248
|
+
raise Datagrid::ConfigurationError, "#{self}##{options[:before] || options[:after]} filter not found"
|
|
249
|
+
end
|
|
247
250
|
filter = klass.new(self, name, **options, &block)
|
|
248
251
|
filters_array.insert(position, filter)
|
|
249
252
|
|
data/lib/datagrid/helper.rb
CHANGED
|
@@ -436,7 +436,7 @@ module Datagrid
|
|
|
436
436
|
query = request&.query_parameters || {}
|
|
437
437
|
ActionDispatch::Http::URL.path_for(
|
|
438
438
|
path: request&.path || "/",
|
|
439
|
-
params: query.merge(grid.query_params(order
|
|
439
|
+
params: query.merge(grid.query_params("order" => column.name, "descending" => descending)),
|
|
440
440
|
)
|
|
441
441
|
end
|
|
442
442
|
|
data/lib/datagrid/utils.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Datagrid
|
|
|
4
4
|
# @!visibility private
|
|
5
5
|
module Utils
|
|
6
6
|
class << self
|
|
7
|
-
TRUTH = [true, 1, "1", "true", "yes", "on"].freeze
|
|
7
|
+
TRUTH = [true, 1, "1", "true", "yes", "on", "y"].freeze
|
|
8
8
|
|
|
9
9
|
def booleanize(value)
|
|
10
10
|
value = value.downcase if value.respond_to?(:downcase)
|
|
@@ -68,7 +68,9 @@ module Datagrid
|
|
|
68
68
|
array.index { |c| c.name.to_sym == before }
|
|
69
69
|
elsif after
|
|
70
70
|
after = after.to_sym
|
|
71
|
-
array.index { |c| c.name.to_sym == after }
|
|
71
|
+
if index = array.index { |c| c.name.to_sym == after }
|
|
72
|
+
index + 1
|
|
73
|
+
end
|
|
72
74
|
else
|
|
73
75
|
-1
|
|
74
76
|
end
|
data/lib/datagrid/version.rb
CHANGED