actionset 0.9.1 → 0.9.2
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 +34 -0
- data/Gemfile.lock +1 -1
- data/actionset.gemspec +1 -1
- data/lib/action_set.rb +4 -48
- data/lib/action_set/filter_instructions.rb +72 -0
- data/lib/action_set/sort_instructions.rb +44 -0
- data/lib/active_set/filtering/active_record/query_column.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cb8d92535baa9047efc45d77b0b7093348eb0ab
|
|
4
|
+
data.tar.gz: efc763790124d2130deb03b5a54656d4a8bc35cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b34b291f7d8ec64de74565e81c451c27b91819263fea54385cabbe08d0367a253e26e6ea52350f0429def47d5e1803cee7f8795e1b6d1368af2db4ed499997b0
|
|
7
|
+
data.tar.gz: a15050e490ac28036860fe2d8c93ea4e856ee0814424fafec168f1042c078cde849fb4fb50eb8d0df4c7d4fc368519246646fa020012a3e7f8d054fb5800ade6
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
v 0.9.2
|
|
2
|
+
- allow for form-friendly filter parameters
|
|
3
|
+
```
|
|
4
|
+
{
|
|
5
|
+
'0': {
|
|
6
|
+
attribute: :foo,
|
|
7
|
+
operator: :EQ,
|
|
8
|
+
query: 'query'
|
|
9
|
+
},
|
|
10
|
+
'1': {
|
|
11
|
+
attribute: :bar,
|
|
12
|
+
operator: :GT,
|
|
13
|
+
query: 'value'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
{ foo: 'query', bar(GT): 'value' }
|
|
18
|
+
```
|
|
19
|
+
- allow for form-friendly sort parameters
|
|
20
|
+
```
|
|
21
|
+
{
|
|
22
|
+
'0': {
|
|
23
|
+
attribute: :foo,
|
|
24
|
+
direction: :desc
|
|
25
|
+
},
|
|
26
|
+
'1': {
|
|
27
|
+
attribute: :bar,
|
|
28
|
+
direction: :asc
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
{ foo: 'desc', bar: 'asc' }
|
|
33
|
+
```
|
|
34
|
+
|
|
1
35
|
v 0.9.1
|
|
2
36
|
- ensure that our RubyGems build is stable, since we had a TravisCI build problem in the last version
|
|
3
37
|
v 0.9.0
|
data/Gemfile.lock
CHANGED
data/actionset.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.platform = Gem::Platform::RUBY
|
|
8
8
|
spec.name = 'actionset'
|
|
9
|
-
spec.version = '0.9.
|
|
9
|
+
spec.version = '0.9.2'
|
|
10
10
|
spec.authors = ['Stephen Margheim']
|
|
11
11
|
spec.email = ['stephen.margheim@gmail.com']
|
|
12
12
|
|
data/lib/action_set.rb
CHANGED
|
@@ -5,7 +5,8 @@ require 'active_support/core_ext/object/blank'
|
|
|
5
5
|
require 'active_support/lazy_load_hooks'
|
|
6
6
|
require 'active_set'
|
|
7
7
|
|
|
8
|
-
require_relative './action_set/
|
|
8
|
+
require_relative './action_set/filter_instructions'
|
|
9
|
+
require_relative './action_set/sort_instructions'
|
|
9
10
|
require_relative './action_set/helpers/helper_methods'
|
|
10
11
|
|
|
11
12
|
module ActionSet
|
|
@@ -24,13 +25,13 @@ module ActionSet
|
|
|
24
25
|
|
|
25
26
|
def filter_set(set)
|
|
26
27
|
active_set = ensure_active_set(set)
|
|
27
|
-
active_set = active_set.filter(
|
|
28
|
+
active_set = active_set.filter(FilterInstructions.new(filter_params, set, self).get) if filter_params.any?
|
|
28
29
|
active_set
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def sort_set(set)
|
|
32
33
|
active_set = ensure_active_set(set)
|
|
33
|
-
active_set = active_set.sort(
|
|
34
|
+
active_set = active_set.sort(SortInstructions.new(sort_params, set, self).get) if sort_params.any?
|
|
34
35
|
active_set
|
|
35
36
|
end
|
|
36
37
|
|
|
@@ -52,26 +53,6 @@ module ActionSet
|
|
|
52
53
|
|
|
53
54
|
private
|
|
54
55
|
|
|
55
|
-
def filter_instructions_for(set)
|
|
56
|
-
flatten_keys_of(filter_params).reject { |_, v| v.try(:empty?) }.each_with_object({}) do |(keypath, value), memo|
|
|
57
|
-
typecast_value = if value.respond_to?(:each)
|
|
58
|
-
value.map { |v| filter_typecasted_value_for(keypath, v, set) }
|
|
59
|
-
else
|
|
60
|
-
filter_typecasted_value_for(keypath, value, set)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
memo[keypath] = typecast_value
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def sort_instructions
|
|
68
|
-
if sort_params.key?(:attribute) && sort_params.key?(:direction)
|
|
69
|
-
{ sort_params[:attribute] => sort_params[:direction] }
|
|
70
|
-
else
|
|
71
|
-
sort_params.transform_values { |v| v.remove('ending') }
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
56
|
def paginate_instructions
|
|
76
57
|
paginate_params.transform_values(&:to_i)
|
|
77
58
|
end
|
|
@@ -102,31 +83,6 @@ module ActionSet
|
|
|
102
83
|
end
|
|
103
84
|
# rubocop:enable Metrics/AbcSize
|
|
104
85
|
|
|
105
|
-
def filter_typecasted_value_for(keypath, value, set)
|
|
106
|
-
klass = klass_for_keypath(keypath, value, set)
|
|
107
|
-
ActionSet::AttributeValue.new(value)
|
|
108
|
-
.cast(to: klass)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def klass_for_keypath(keypath, value, set)
|
|
112
|
-
if respond_to?(:filter_set_types, true)
|
|
113
|
-
type_declarations = public_send(:filter_set_types)
|
|
114
|
-
types = type_declarations['types'] || type_declarations[:types]
|
|
115
|
-
klass = types[keypath.join('.')]
|
|
116
|
-
return klass if klass
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
if set.is_a?(ActiveRecord::Relation) || set.view.is_a?(ActiveRecord::Relation)
|
|
120
|
-
klass_type = set.model.columns_hash.fetch(keypath, nil)&.type
|
|
121
|
-
return klass_type.class if klass_type
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
instruction = ActiveSet::AttributeInstruction.new(keypath, value)
|
|
125
|
-
item_with_value = set.find { |i| !instruction.value_for(item: i).nil? }
|
|
126
|
-
item_value = instruction.value_for(item: item_with_value)
|
|
127
|
-
item_value.class
|
|
128
|
-
end
|
|
129
|
-
|
|
130
86
|
def filter_params
|
|
131
87
|
params.fetch(:filter, {}).to_unsafe_hash
|
|
132
88
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './attribute_value'
|
|
4
|
+
|
|
5
|
+
module ActionSet
|
|
6
|
+
class FilterInstructions
|
|
7
|
+
def initialize(params, set, controller)
|
|
8
|
+
@params = params
|
|
9
|
+
@set = set
|
|
10
|
+
@controller = controller
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get
|
|
14
|
+
instructions_hash = if form_friendly_complex_params?
|
|
15
|
+
form_friendly_complex_params_to_hash
|
|
16
|
+
elsif form_friendly_simple_params?
|
|
17
|
+
form_friendly_simple_params_to_hash
|
|
18
|
+
else
|
|
19
|
+
@params
|
|
20
|
+
end
|
|
21
|
+
flattened_instructions = flatten_keys_of(instructions_hash).reject { |_, v| v.try(:empty?) }
|
|
22
|
+
flattened_instructions.each_with_object({}) do |(keypath, value), memo|
|
|
23
|
+
memo[keypath] = if value.respond_to?(:map)
|
|
24
|
+
value.map { |v| AttributeValue.new(v).cast(to: klass_for_keypath(keypath, v, @set)) }
|
|
25
|
+
else
|
|
26
|
+
AttributeValue.new(value).cast(to: klass_for_keypath(keypath, value, @set))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def form_friendly_complex_params?
|
|
34
|
+
@params.key?(:'0')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def form_friendly_simple_params?
|
|
38
|
+
@params.key?(:attribute) &&
|
|
39
|
+
@params.key?(:operator) &&
|
|
40
|
+
@params.key?(:query)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def form_friendly_complex_params_to_hash
|
|
44
|
+
ordered_instructions = @params.sort_by(&:first)
|
|
45
|
+
array_of_instructions = ordered_instructions.map { |_, h| ["#{h[:attribute]}(#{h[:operator]})", h[:query]] }
|
|
46
|
+
Hash[array_of_instructions]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def form_friendly_simple_params_to_hash
|
|
50
|
+
{ "#{@params[:attribute]}(#{@params[:operator]})" => @params[:query] }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def klass_for_keypath(keypath, value, set)
|
|
54
|
+
if @controller.respond_to?(:filter_set_types, true)
|
|
55
|
+
type_declarations = @controller.public_send(:filter_set_types)
|
|
56
|
+
types = type_declarations['types'] || type_declarations[:types]
|
|
57
|
+
klass = types[keypath.join('.')]
|
|
58
|
+
return klass if klass
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if set.is_a?(ActiveRecord::Relation) || set.view.is_a?(ActiveRecord::Relation)
|
|
62
|
+
klass_type = set.model.columns_hash.fetch(keypath, nil)&.type
|
|
63
|
+
return klass_type.class if klass_type
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
instruction = ActiveSet::AttributeInstruction.new(keypath, value)
|
|
67
|
+
item_with_value = set.find { |i| !instruction.value_for(item: i).nil? }
|
|
68
|
+
item_value = instruction.value_for(item: item_with_value)
|
|
69
|
+
item_value.class
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionSet
|
|
4
|
+
class SortInstructions
|
|
5
|
+
def initialize(params, set, controller)
|
|
6
|
+
@params = params
|
|
7
|
+
@set = set
|
|
8
|
+
@controller = controller
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get
|
|
12
|
+
instructions_hash = if form_friendly_complex_params?
|
|
13
|
+
form_friendly_complex_params_to_hash
|
|
14
|
+
elsif form_friendly_simple_params?
|
|
15
|
+
form_friendly_simple_params_to_hash
|
|
16
|
+
else
|
|
17
|
+
@params
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
instructions_hash.transform_values { |v| v.remove('ending') }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def form_friendly_complex_params?
|
|
26
|
+
@params.key?(:'0')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def form_friendly_simple_params?
|
|
30
|
+
@params.key?(:attribute) &&
|
|
31
|
+
@params.key?(:direction)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def form_friendly_complex_params_to_hash
|
|
35
|
+
ordered_instructions = @params.sort_by(&:first)
|
|
36
|
+
array_of_instructions = ordered_instructions.map { |_, h| [h[:attribute], h[:direction]] }
|
|
37
|
+
Hash[array_of_instructions]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def form_friendly_simple_params_to_hash
|
|
41
|
+
{ @params[:attribute] => @params[:direction] }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -24,7 +24,7 @@ class ActiveSet
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def must_cast_numerical_column?
|
|
27
|
-
# The LIKE operator can
|
|
27
|
+
# The LIKE operator can't be used if the column hosts numeric types.
|
|
28
28
|
return false unless arel_type.presence_in(%i[integer float])
|
|
29
29
|
|
|
30
30
|
arel_operator.to_s.downcase.include?('match')
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: actionset
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen Margheim
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-08-
|
|
11
|
+
date: 2019-08-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -259,6 +259,7 @@ files:
|
|
|
259
259
|
- config.ru
|
|
260
260
|
- lib/action_set.rb
|
|
261
261
|
- lib/action_set/attribute_value.rb
|
|
262
|
+
- lib/action_set/filter_instructions.rb
|
|
262
263
|
- lib/action_set/helpers/export/path_for_helper.rb
|
|
263
264
|
- lib/action_set/helpers/helper_methods.rb
|
|
264
265
|
- lib/action_set/helpers/pagination/current_page_description_for_helper.rb
|
|
@@ -284,6 +285,7 @@ files:
|
|
|
284
285
|
- lib/action_set/helpers/sort/link_for_helper.rb
|
|
285
286
|
- lib/action_set/helpers/sort/next_direction_for_helper.rb
|
|
286
287
|
- lib/action_set/helpers/sort/path_for_helper.rb
|
|
288
|
+
- lib/action_set/sort_instructions.rb
|
|
287
289
|
- lib/active_set.rb
|
|
288
290
|
- lib/active_set/active_record_set_instruction.rb
|
|
289
291
|
- lib/active_set/attribute_instruction.rb
|