rokaki 0.3.0 → 0.4.0
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/README.md +48 -1
- data/lib/rokaki/filter_model/like.rb +34 -0
- data/lib/rokaki/filter_model.rb +75 -26
- data/lib/rokaki/filterable.rb +1 -3
- data/lib/rokaki/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fd44ddd6bbfce39a8417111397fda97131f893d9e502b9a43c1068a18fae5ba
|
4
|
+
data.tar.gz: b17ce9c86ae2a7ed95a358662c48fde64e29c6d647a4d3e38f7d13ac6275f201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8574514a686795b089997a792cbf188ac82ed8751a94d5a0469d6ed92cf7860dd31d13762887972c6546e7e24f5427dfdd52f1c907c95e82de8f4509bec3d616
|
7
|
+
data.tar.gz: a38042fff170ed676be0fd9585b2fc9f1ce7ed9691fead44c9744724d6dfe94c65ed8ab005feaaaf7555268f653ab1906aa2765012036698cc8b4a43bb49c0e8
|
data/README.md
CHANGED
@@ -30,6 +30,7 @@ A simple example might be:-
|
|
30
30
|
@filters = filters
|
31
31
|
@articles = Article
|
32
32
|
end
|
33
|
+
|
33
34
|
attr_accessor :filters
|
34
35
|
|
35
36
|
define_filter_keys :date, author: [:first_name, :last_name]
|
@@ -84,7 +85,35 @@ filtered_results = filter.results
|
|
84
85
|
```
|
85
86
|
|
86
87
|
### Partial matching
|
87
|
-
You can use `like` to perform a partial match on a specific key, there are 3 options:- `:prefix`, `:circumfix` and `:suffix`.
|
88
|
+
You can use `like` to perform a partial match on a specific key, there are 3 options:- `:prefix`, `:circumfix` and `:suffix`. There are two syntaxes you can use for this:-
|
89
|
+
|
90
|
+
#### 1. The `filter` command syntax
|
91
|
+
|
92
|
+
|
93
|
+
```
|
94
|
+
class ArticleFilter
|
95
|
+
include FilterModel
|
96
|
+
|
97
|
+
filter :article,
|
98
|
+
like: {
|
99
|
+
author: {
|
100
|
+
first_name: :circumfix,
|
101
|
+
last_name: :circumfix
|
102
|
+
}
|
103
|
+
},
|
104
|
+
|
105
|
+
attr_accessor :filters
|
106
|
+
|
107
|
+
def initialize(filters:)
|
108
|
+
@filters = filters
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
Or
|
113
|
+
|
114
|
+
#### 2. The porcelain command syntax
|
115
|
+
|
116
|
+
In this syntax you will need to provide three keywords:- `filters`, `like` and `filter_model` if you are not passing in the model type and assigning it to `@model`
|
88
117
|
|
89
118
|
|
90
119
|
```
|
@@ -103,6 +132,24 @@ class ArticleFilter
|
|
103
132
|
end
|
104
133
|
```
|
105
134
|
|
135
|
+
Or without the model in the initializer
|
136
|
+
|
137
|
+
```
|
138
|
+
class ArticleFilter
|
139
|
+
include FilterModel
|
140
|
+
|
141
|
+
filters :date, :title, author: [:first_name, :last_name]
|
142
|
+
like title: :circumfix
|
143
|
+
filter_model :article
|
144
|
+
|
145
|
+
attr_accessor :filters
|
146
|
+
|
147
|
+
def initialize(filters:)
|
148
|
+
@filters = filters
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
106
153
|
Would produce a query with a LIKE which circumfixes '%' around the filter term, like:-
|
107
154
|
|
108
155
|
```
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rokaki
|
4
|
+
module FilterModel
|
5
|
+
module Like
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def like(args)
|
12
|
+
raise ArgumentError, 'argument mush be a hash' unless args.is_a? Hash
|
13
|
+
@_like_semantics = (@_like_semantics || {}).merge(args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def _chain_filter_like_type(key)
|
17
|
+
filter = "#{filter_key_prefix}#{key}"
|
18
|
+
|
19
|
+
query = "@model.where(\"#{key} LIKE :query\", "
|
20
|
+
if mode == :circumfix
|
21
|
+
query += "query: \"%\#{#{filter}}%\")"
|
22
|
+
end
|
23
|
+
if mode == :infix
|
24
|
+
query += "query: \"%\#{#{filter}}\")"
|
25
|
+
end
|
26
|
+
if mode == :suffix
|
27
|
+
query += "query: \"\#{#{filter}}%\")"
|
28
|
+
end
|
29
|
+
"#{query};"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/rokaki/filter_model.rb
CHANGED
@@ -12,46 +12,57 @@ module Rokaki
|
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
+
def filter(model, options)
|
16
|
+
filter_model(model)
|
17
|
+
|
18
|
+
like(options[:like]) if options[:like]
|
19
|
+
filters(*options[:match]) if options[:match]
|
20
|
+
end
|
21
|
+
|
15
22
|
def filters(*filter_keys)
|
16
23
|
define_filter_keys *filter_keys
|
17
24
|
|
18
|
-
@_chain_filters
|
25
|
+
@_chain_filters ||= []
|
19
26
|
filter_keys.each do |filter_key|
|
20
|
-
_chain_filter(filter_key) unless filter_key.is_a? Hash
|
21
|
-
_chain_nested
|
27
|
+
_chain_filter([filter_key]) unless filter_key.is_a? Hash
|
28
|
+
_chain_nested(filter_key) if filter_key.is_a? Hash
|
22
29
|
end
|
23
30
|
|
24
31
|
define_results
|
25
32
|
end
|
26
33
|
|
27
|
-
def _chain_filter(
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
34
|
+
def _chain_filter(keys)
|
35
|
+
first_key = keys.shift
|
36
|
+
filter = "#{filter_key_prefix}#{first_key}"
|
37
|
+
name = first_key
|
38
|
+
|
39
|
+
keys.each do |key|
|
40
|
+
filter += "#{filter_key_infix}#{key}"
|
41
|
+
name += "#{filter_key_infix}#{key}"
|
42
|
+
end
|
32
43
|
|
33
|
-
|
44
|
+
filter_method = "def #{filter_key_prefix}filter_#{name};" \
|
45
|
+
"#{_chain_filter_type(name)} end;"
|
46
|
+
|
47
|
+
class_eval filter_method, __FILE__, __LINE__ - 2
|
48
|
+
|
49
|
+
@_chain_filters << "@model = #{filter_key_prefix}filter_#{name} if #{filter};"
|
34
50
|
end
|
35
51
|
|
36
52
|
def _chain_filter_type(key)
|
37
53
|
filter = "#{filter_key_prefix}#{key}"
|
38
54
|
|
39
|
-
query =
|
55
|
+
query = ''
|
40
56
|
if @_like_semantics && mode = @_like_semantics[key]
|
41
57
|
query = "@model.where(\"#{key} LIKE :query\", "
|
42
|
-
if mode == :circumfix
|
43
|
-
|
44
|
-
|
45
|
-
if mode == :prefix
|
46
|
-
query += "query: \"%\#{#{filter}}\")"
|
47
|
-
end
|
48
|
-
if mode == :suffix
|
49
|
-
query += "query: \"\#{#{filter}}%\")"
|
50
|
-
end
|
58
|
+
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
59
|
+
query += "query: \"%\#{#{filter}}\")" if mode == :prefix
|
60
|
+
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
51
61
|
else
|
52
62
|
query = "@model.where(#{filter}: #{key})"
|
53
63
|
end
|
54
|
-
|
64
|
+
|
65
|
+
query
|
55
66
|
end
|
56
67
|
|
57
68
|
def _build_deep_chain(keys)
|
@@ -72,13 +83,15 @@ module Rokaki
|
|
72
83
|
where = "{ #{key.to_s.pluralize}: { #{leaf}: #{name} } }"
|
73
84
|
end
|
74
85
|
|
75
|
-
|
76
86
|
joins = joins += out
|
77
87
|
where = where += out
|
78
88
|
|
79
|
-
|
80
|
-
|
81
|
-
|
89
|
+
# chain filter here?
|
90
|
+
#
|
91
|
+
filter_method = "def #{filter_key_prefix}filter_#{name};"\
|
92
|
+
"@model.joins(#{joins}).where(#{where}); end;"
|
93
|
+
|
94
|
+
class_eval filter_method, __FILE__, __LINE__ - 2
|
82
95
|
|
83
96
|
@_chain_filters << "@model = #{filter_key_prefix}filter_#{name} if #{name};"
|
84
97
|
end
|
@@ -94,12 +107,45 @@ module Rokaki
|
|
94
107
|
end
|
95
108
|
|
96
109
|
def filter_model(model)
|
97
|
-
@model = model
|
110
|
+
@model = (model.is_a?(Class) ? model : Object.const_get(model.capitalize))
|
111
|
+
class_eval "def model; @model ||= #{@model}; end;"
|
98
112
|
end
|
99
113
|
|
100
114
|
def like(args)
|
101
115
|
raise ArgumentError, 'argument mush be a hash' unless args.is_a? Hash
|
116
|
+
|
117
|
+
like_keys = {base: []}
|
118
|
+
args.keys.each do |key|
|
119
|
+
map_like_keys(like_keys, args, key)
|
120
|
+
end
|
121
|
+
|
102
122
|
@_like_semantics = (@_like_semantics || {}).merge(args)
|
123
|
+
|
124
|
+
base_keys = like_keys.delete(:base)
|
125
|
+
key_results = base_keys << like_keys
|
126
|
+
|
127
|
+
filters(*key_results)
|
128
|
+
end
|
129
|
+
|
130
|
+
def map_like_keys(key_result, base_object, key)
|
131
|
+
sub_object = base_object[key]
|
132
|
+
if sub_object.is_a? Hash
|
133
|
+
sub_object.keys.each do |sub_key|
|
134
|
+
sub_object_value = sub_object[sub_key]
|
135
|
+
if sub_object_value.is_a? Symbol
|
136
|
+
if key_result[key].is_a? Array
|
137
|
+
key_result[key] << sub_key
|
138
|
+
else
|
139
|
+
key_result[key] = [sub_key]
|
140
|
+
end
|
141
|
+
elsif sub_object_value.is_a? Hash
|
142
|
+
map_like_keys(key_result, sub_object, sub_key)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
elsif sub_object.is_a? Symbol
|
146
|
+
key_result[:base] << key
|
147
|
+
end
|
148
|
+
key_result
|
103
149
|
end
|
104
150
|
|
105
151
|
def deep_chain(keys, value)
|
@@ -123,8 +169,11 @@ module Rokaki
|
|
123
169
|
end
|
124
170
|
end
|
125
171
|
|
172
|
+
# the model method is called to instatiate @model from the
|
173
|
+
# filter_model method
|
174
|
+
#
|
126
175
|
def define_results
|
127
|
-
results_def = 'def results;'
|
176
|
+
results_def = 'def results;model;'
|
128
177
|
@_chain_filters.each do |item|
|
129
178
|
results_def += item
|
130
179
|
end
|
data/lib/rokaki/filterable.rb
CHANGED
@@ -26,14 +26,11 @@ module Rokaki
|
|
26
26
|
|
27
27
|
def _build_filter(keys)
|
28
28
|
name = @filter_key_prefix.to_s
|
29
|
-
filters = "filters"
|
30
29
|
count = keys.size - 1
|
31
30
|
|
32
31
|
keys.each_with_index do |key, i|
|
33
32
|
name += key.to_s
|
34
33
|
name += filter_key_infix.to_s unless count == i
|
35
|
-
|
36
|
-
filters += "[:#{key}]"
|
37
34
|
end
|
38
35
|
|
39
36
|
class_eval "def #{name}; filters.dig(*#{keys}); end;", __FILE__, __LINE__
|
@@ -53,6 +50,7 @@ module Rokaki
|
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
53
|
+
|
56
54
|
if value.is_a? Array
|
57
55
|
value.each do |av|
|
58
56
|
_keys = keys.dup << av
|
data/lib/rokaki/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rokaki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- bin/setup
|
144
144
|
- lib/rokaki.rb
|
145
145
|
- lib/rokaki/filter_model.rb
|
146
|
+
- lib/rokaki/filter_model/like.rb
|
146
147
|
- lib/rokaki/filterable.rb
|
147
148
|
- lib/rokaki/version.rb
|
148
149
|
- rokaki.gemspec
|