activeset 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +6 -0
- data/lib/active_set.rb +6 -6
- data/lib/active_set/instructions/base.rb +14 -6
- data/lib/active_set/instructions/entry.rb +2 -1
- data/lib/active_set/processors/base_adapter.rb +9 -1
- data/lib/active_set/processors/filter/active_record_adapter.rb +28 -9
- data/lib/active_set/processors/filter/enumerable_adapter.rb +10 -16
- data/lib/active_set/processors/paginate/enumerable_adapter.rb +7 -2
- data/lib/active_set/processors/paginate_processor.rb +1 -2
- data/lib/active_set/processors/sort/active_record_adapter.rb +10 -7
- data/lib/active_set/processors/sort/enumerable_adapter.rb +16 -5
- data/lib/active_set/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eaba5e4aae16ae6f0dc4c2fad28b8c7177231448
|
4
|
+
data.tar.gz: 5d9b7ec416a8462f9a98db7f7aa04472357ccd9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79079f1f927cb72e863a15a1f0ccee14a3cb3b2b3f7e32cc5b40e2dc71ee52c0b76ba4af21c46e8b98b896183c739f78662f58e16596fef10f5dccd829486df1
|
7
|
+
data.tar.gz: be55e192739fe5b3bdcb6a1a6775ec932310467440826c7362c102e2aaba0595facd02acba55f30d30f243ba26101a971f7758b37130dcfe47001196d0ef909b
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
v 0.4.0
|
2
|
+
- fix bug with filtering against falsey values
|
3
|
+
- remove hack of casting DateTime and Time objects to Integer for filtering
|
4
|
+
- add support for ActiveRecord :time columns
|
5
|
+
- ensure that an adapter is only run if necessary for a particular instruction; that is, try to process the instruction with the first adapter, if it succeeds, don't run any other adapters, if it doesn't, try the next adapter, etc.
|
6
|
+
- allow ActiveRecord sets to be filtered by a scope method
|
1
7
|
v 0.3.1
|
2
8
|
- Implement an Instructions object layer for handling the hashes passed into Processors
|
3
9
|
v 0.3.0
|
data/lib/active_set.rb
CHANGED
@@ -32,18 +32,18 @@ class ActiveSet
|
|
32
32
|
@set.respond_to?(method_name) || super
|
33
33
|
end
|
34
34
|
|
35
|
-
def filter(
|
36
|
-
filterer = FilterProcessor.new(@set,
|
35
|
+
def filter(instructions)
|
36
|
+
filterer = FilterProcessor.new(@set, instructions)
|
37
37
|
self.class.new(filterer.process)
|
38
38
|
end
|
39
39
|
|
40
|
-
def sort(
|
41
|
-
sorter = SortProcessor.new(@set,
|
40
|
+
def sort(instructions)
|
41
|
+
sorter = SortProcessor.new(@set, instructions)
|
42
42
|
self.class.new(sorter.process)
|
43
43
|
end
|
44
44
|
|
45
|
-
def paginate(
|
46
|
-
paginater = PaginateProcessor.new(@set,
|
45
|
+
def paginate(instructions)
|
46
|
+
paginater = PaginateProcessor.new(@set, instructions)
|
47
47
|
self.class.new(paginater.process)
|
48
48
|
end
|
49
49
|
end
|
@@ -8,19 +8,27 @@ class ActiveSet
|
|
8
8
|
|
9
9
|
def initialize(hash)
|
10
10
|
@hash = hash
|
11
|
-
@flattened_hash = hash.flatten_keys
|
11
|
+
@flattened_hash = hash.flatten_keys.transform_keys { |k| k.map(&:to_s) }
|
12
12
|
end
|
13
13
|
|
14
14
|
def process_adapter(set:, adapter:)
|
15
|
-
@flattened_hash.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
@flattened_hash.reduce(set) do |inner_set, (keypath, value)|
|
16
|
+
instruction = Entry.new(keypath, value)
|
17
|
+
output = adapter.new(inner_set, instruction).process
|
18
|
+
remove_from_instruction_set(key: instruction.path) if output[:processed]
|
19
|
+
|
20
|
+
output[:set]
|
21
|
+
end
|
20
22
|
end
|
21
23
|
|
22
24
|
def get(keypath)
|
23
25
|
@hash.dig(*keypath)
|
24
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def remove_from_instruction_set(key:)
|
31
|
+
@flattened_hash.delete(key)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
@@ -10,7 +10,8 @@ class ActiveSet
|
|
10
10
|
class Entry
|
11
11
|
attr_reader :keypath
|
12
12
|
|
13
|
-
delegate :attribute, :operator, :associations_array,
|
13
|
+
delegate :path, :attribute, :operator, :associations_array,
|
14
|
+
:associations_hash, :value_for, :resource_for,
|
14
15
|
to: :keypath
|
15
16
|
|
16
17
|
def initialize(keypath, value)
|
@@ -2,8 +2,16 @@
|
|
2
2
|
|
3
3
|
class ActiveSet
|
4
4
|
class BaseAdapter
|
5
|
-
def initialize(instruction)
|
5
|
+
def initialize(set, instruction)
|
6
|
+
@set = set
|
6
7
|
@instruction = instruction
|
7
8
|
end
|
9
|
+
|
10
|
+
def return_set(set = nil)
|
11
|
+
{}.tap do |h|
|
12
|
+
h[:set] = set || @set
|
13
|
+
h[:processed] = set ? true : false
|
14
|
+
end
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
@@ -6,26 +6,40 @@ require_relative '../base_processor'
|
|
6
6
|
class ActiveSet
|
7
7
|
class FilterProcessor < BaseProcessor
|
8
8
|
class ActiveRecordAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
@set
|
11
|
-
return
|
12
|
-
return
|
9
|
+
def process
|
10
|
+
return return_set unless @set.respond_to? :to_sql
|
11
|
+
return return_set(processed_query_set) if attribute_is_field?
|
12
|
+
return return_set(processed_scope_set) if attribute_is_class_method? && attribute_is_method_with_params?
|
13
13
|
|
14
|
-
|
14
|
+
return_set
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
+
def processed_query_set
|
20
|
+
arel_eager_load_associations.where(arel_operation)
|
21
|
+
end
|
22
|
+
|
23
|
+
def processed_scope_set
|
24
|
+
tmp_results = attribute_model.public_send(@instruction.attribute, @instruction.value)
|
25
|
+
return @set unless tmp_results.is_a?(ActiveRecord::Relation)
|
26
|
+
arel_eager_load_associations.merge(tmp_results)
|
27
|
+
end
|
28
|
+
|
19
29
|
def attribute_is_field?
|
20
30
|
return false unless attribute_model
|
21
31
|
attribute_model.attribute_names
|
22
32
|
.include?(@instruction.attribute)
|
23
33
|
end
|
24
34
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
35
|
+
def attribute_is_class_method?
|
36
|
+
return false unless attribute_model
|
37
|
+
attribute_model.respond_to?(@instruction.attribute)
|
38
|
+
end
|
39
|
+
|
40
|
+
def attribute_is_method_with_params?
|
41
|
+
return false unless attribute_model
|
42
|
+
attribute_model.method(@instruction.attribute).arity != 0
|
29
43
|
end
|
30
44
|
|
31
45
|
def arel_operation
|
@@ -41,6 +55,11 @@ class ActiveSet
|
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
58
|
+
def arel_eager_load_associations
|
59
|
+
@set.includes(@instruction.associations_hash)
|
60
|
+
.references(@instruction.associations_hash)
|
61
|
+
end
|
62
|
+
|
44
63
|
def arel_column
|
45
64
|
arel_table[@instruction.attribute]
|
46
65
|
end
|
@@ -5,28 +5,22 @@ require_relative '../base_adapter'
|
|
5
5
|
class ActiveSet
|
6
6
|
class FilterProcessor < BaseProcessor
|
7
7
|
class EnumerableAdapter < BaseAdapter
|
8
|
-
def process
|
9
|
-
|
10
|
-
value_for(item).send(@instruction.operator,
|
11
|
-
passed_value)
|
12
|
-
end
|
8
|
+
def process
|
9
|
+
return_set(filtered_set)
|
13
10
|
end
|
14
11
|
|
15
12
|
private
|
16
13
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def passed_value
|
22
|
-
convert_datetime_values_to_integer(@instruction.value)
|
14
|
+
def filtered_set
|
15
|
+
@set.select do |item|
|
16
|
+
select_comparison_for(item: item)
|
17
|
+
end
|
23
18
|
end
|
24
19
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
value.to_i
|
20
|
+
def select_comparison_for(item:)
|
21
|
+
@instruction.value_for(item: item)
|
22
|
+
.send(@instruction.operator,
|
23
|
+
@instruction.value)
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,12 +6,17 @@ require_relative '../base_processor'
|
|
6
6
|
class ActiveSet
|
7
7
|
class PaginateProcessor < BaseProcessor
|
8
8
|
class EnumerableAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
set.
|
9
|
+
def process
|
10
|
+
return return_set if @set.count < pagesize
|
11
|
+
return_set(paginated_set)
|
11
12
|
end
|
12
13
|
|
13
14
|
private
|
14
15
|
|
16
|
+
def paginated_set
|
17
|
+
@set.each_slice(pagesize).take(page_number).last
|
18
|
+
end
|
19
|
+
|
15
20
|
def pagesize
|
16
21
|
@instruction.value
|
17
22
|
end
|
@@ -6,8 +6,7 @@ require_relative './paginate/enumerable_adapter'
|
|
6
6
|
class ActiveSet
|
7
7
|
class PaginateProcessor < BaseProcessor
|
8
8
|
def process
|
9
|
-
|
10
|
-
adapter.new(instruction).process(@set)
|
9
|
+
adapter.new(@set, instruction).process
|
11
10
|
end
|
12
11
|
|
13
12
|
private
|
@@ -6,14 +6,11 @@ require_relative '../base_processor'
|
|
6
6
|
class ActiveSet
|
7
7
|
class SortProcessor < BaseProcessor
|
8
8
|
class ActiveRecordAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
@set
|
11
|
-
return
|
12
|
-
return @set unless attribute_is_field?
|
9
|
+
def process
|
10
|
+
return return_set unless @set.respond_to? :to_sql
|
11
|
+
return return_set unless attribute_is_field?
|
13
12
|
|
14
|
-
|
15
|
-
.references(@instruction.associations_hash)
|
16
|
-
.merge(arel_operation)
|
13
|
+
return_set(processed_set)
|
17
14
|
end
|
18
15
|
|
19
16
|
private
|
@@ -24,6 +21,12 @@ class ActiveSet
|
|
24
21
|
.include?(@instruction.attribute)
|
25
22
|
end
|
26
23
|
|
24
|
+
def processed_set
|
25
|
+
@set.includes(@instruction.associations_hash)
|
26
|
+
.references(@instruction.associations_hash)
|
27
|
+
.merge(arel_operation)
|
28
|
+
end
|
29
|
+
|
27
30
|
def arel_operation
|
28
31
|
column = case_insensitive? ? arel_column.lower : arel_column
|
29
32
|
attribute_model.order(column.send(@instruction.value))
|
@@ -6,15 +6,22 @@ require_relative '../base_processor'
|
|
6
6
|
class ActiveSet
|
7
7
|
class SortProcessor < BaseProcessor
|
8
8
|
class EnumerableAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
|
11
|
-
attribute_value = @instruction.value_for(item: item)
|
12
|
-
case_insensitive?(attribute_value) ? insensify(attribute_value) : attribute_value
|
13
|
-
end.tap { |c| c.reverse! if @instruction.value.to_s == 'desc' }
|
9
|
+
def process
|
10
|
+
return_set(sorted_set)
|
14
11
|
end
|
15
12
|
|
16
13
|
private
|
17
14
|
|
15
|
+
def sorted_set
|
16
|
+
@set.sort_by { |item| sortable_attribute_for(item: item) }
|
17
|
+
.tap { |c| c.reverse! if descending? }
|
18
|
+
end
|
19
|
+
|
20
|
+
def sortable_attribute_for(item:)
|
21
|
+
attribute_value = @instruction.value_for(item: item)
|
22
|
+
case_insensitive?(attribute_value) ? insensify(attribute_value) : attribute_value
|
23
|
+
end
|
24
|
+
|
18
25
|
def case_insensitive?(value)
|
19
26
|
# Cannot sort pure Booleans or Nils, so we _must_ cast to Strings
|
20
27
|
return true if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
@@ -25,6 +32,10 @@ class ActiveSet
|
|
25
32
|
def insensify(value)
|
26
33
|
value.to_s.downcase
|
27
34
|
end
|
35
|
+
|
36
|
+
def descending?
|
37
|
+
@instruction.value.to_s == 'desc'
|
38
|
+
end
|
28
39
|
end
|
29
40
|
end
|
30
41
|
end
|
data/lib/active_set/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeset
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Margheim
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|