rokaki 0.6.0 → 0.7.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/Gemfile.lock +3 -1
- data/README.md +56 -0
- data/lib/rokaki/filter_model/basic_filter.rb +13 -6
- data/lib/rokaki/filter_model/nested_filter.rb +13 -6
- data/lib/rokaki/filter_model.rb +22 -14
- data/lib/rokaki/version.rb +1 -1
- data/rokaki.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a46db4e821b0a8fb7f661ed539c18c6509b0a644b3bc0f790c0619ab72ff4108
|
4
|
+
data.tar.gz: f6ae9809a6a82c9a1de24ecf7d79b9f0cc6cab530579751df919832c0fa3593e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55b11eee1380defcbd8b56e584b4d4ea145571718da3fa82e5445b2233d779bf169c173d19f5afbf5e7eb6dc69a070a8a08ff64fa3dc41fc4d29690ab2de0556
|
7
|
+
data.tar.gz: 88869cad8ba114234d2581661277963d3eb2effd4aecded8be6d2b7140dcb8331b68d529b4e388518c8ca503deff5f5b8ede87d33bb98152c8e29f676eb268ba
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rokaki (0.
|
4
|
+
rokaki (0.6.0)
|
5
5
|
activesupport
|
6
6
|
|
7
7
|
GEM
|
@@ -51,6 +51,7 @@ GEM
|
|
51
51
|
notiffany (0.1.3)
|
52
52
|
nenv (~> 0.1)
|
53
53
|
shellany (~> 0.0)
|
54
|
+
pg (1.1.4)
|
54
55
|
pry (0.12.2)
|
55
56
|
coderay (~> 1.1.0)
|
56
57
|
method_source (~> 0.9.0)
|
@@ -91,6 +92,7 @@ DEPENDENCIES
|
|
91
92
|
bundler (~> 2.0)
|
92
93
|
guard
|
93
94
|
guard-rspec
|
95
|
+
pg
|
94
96
|
pry
|
95
97
|
pry-byebug
|
96
98
|
rake (~> 10.0)
|
data/README.md
CHANGED
@@ -161,6 +161,62 @@ Would produce a query with a LIKE which circumfixes '%' around the filter term,
|
|
161
161
|
@model = @model.where('title LIKE :query', query: "%#{title}%")
|
162
162
|
```
|
163
163
|
|
164
|
+
### Deep nesting
|
165
|
+
You can filter joins both with basic matching and partial matching
|
166
|
+
```ruby
|
167
|
+
class ArticleFilter
|
168
|
+
include FilterModel
|
169
|
+
|
170
|
+
filter :author,
|
171
|
+
like: {
|
172
|
+
articles: {
|
173
|
+
reviews: {
|
174
|
+
title: :circumfix
|
175
|
+
}
|
176
|
+
},
|
177
|
+
}
|
178
|
+
|
179
|
+
attr_accessor :filters
|
180
|
+
|
181
|
+
def initialize(filters:)
|
182
|
+
@filters = filters
|
183
|
+
end
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
### Array params
|
188
|
+
You can pass array params (and partially match them), to filters (search multiple matches) in databases that support it (postgres) by passing the `db` param to the filter keyword, and passing an array of search terms at runtine
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
class ArticleFilter
|
192
|
+
filter :article,
|
193
|
+
like: {
|
194
|
+
author: {
|
195
|
+
first_name: :circumfix,
|
196
|
+
last_name: :circumfix
|
197
|
+
}
|
198
|
+
},
|
199
|
+
match: %i[title created_at],
|
200
|
+
db: :postgres
|
201
|
+
|
202
|
+
attr_accessor :filters
|
203
|
+
|
204
|
+
def initialize(filters:)
|
205
|
+
@filters = filters
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
filterable = ArticleFilter.new(filters:
|
210
|
+
{
|
211
|
+
author: {
|
212
|
+
first_name: ['Match One', 'Match Two']
|
213
|
+
}
|
214
|
+
}
|
215
|
+
)
|
216
|
+
|
217
|
+
filterable.results
|
218
|
+
```
|
219
|
+
|
164
220
|
|
165
221
|
## Development
|
166
222
|
|
@@ -3,14 +3,15 @@
|
|
3
3
|
module Rokaki
|
4
4
|
module FilterModel
|
5
5
|
class BasicFilter
|
6
|
-
def initialize(keys:, prefix:, infix:, like_semantics:, i_like_semantics:)
|
6
|
+
def initialize(keys:, prefix:, infix:, like_semantics:, i_like_semantics:, db:)
|
7
7
|
@keys = keys
|
8
8
|
@prefix = prefix
|
9
9
|
@infix = infix
|
10
10
|
@like_semantics = like_semantics
|
11
11
|
@i_like_semantics = i_like_semantics
|
12
|
+
@db = db
|
12
13
|
end
|
13
|
-
attr_reader :keys, :prefix, :infix, :like_semantics, :i_like_semantics
|
14
|
+
attr_reader :keys, :prefix, :infix, :like_semantics, :i_like_semantics, :db
|
14
15
|
attr_accessor :filter_method, :filter_template
|
15
16
|
|
16
17
|
def call
|
@@ -59,10 +60,16 @@ module Rokaki
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def build_like_query(type:, query:, filter:, mode:, key:)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
if db == :postgres
|
64
|
+
query = "@model.where(\"#{key} #{type} ANY (ARRAY[?])\", "
|
65
|
+
query += "prepare_terms(#{filter}, :#{mode}))"
|
66
|
+
else
|
67
|
+
query = "@model.where(\"#{key} #{type} :query\", "
|
68
|
+
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
69
|
+
query += "query: \"%\#{#{filter}}\")" if mode == :prefix
|
70
|
+
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
71
|
+
end
|
72
|
+
|
66
73
|
query
|
67
74
|
end
|
68
75
|
end
|
@@ -4,7 +4,7 @@ require 'active_support/inflector'
|
|
4
4
|
module Rokaki
|
5
5
|
module FilterModel
|
6
6
|
class NestedFilter
|
7
|
-
def initialize(filter_key_object:, prefix:, infix:, like_semantics:, i_like_semantics:)
|
7
|
+
def initialize(filter_key_object:, prefix:, infix:, like_semantics:, i_like_semantics:, db:)
|
8
8
|
@filter_key_object = filter_key_object
|
9
9
|
@prefix = prefix
|
10
10
|
@infix = infix
|
@@ -12,8 +12,9 @@ module Rokaki
|
|
12
12
|
@i_like_semantics = i_like_semantics
|
13
13
|
@filter_methods = []
|
14
14
|
@filter_templates = []
|
15
|
+
@db = db
|
15
16
|
end
|
16
|
-
attr_reader :filter_key_object, :prefix, :infix, :like_semantics, :i_like_semantics
|
17
|
+
attr_reader :filter_key_object, :prefix, :infix, :like_semantics, :i_like_semantics, :db
|
17
18
|
attr_accessor :filter_methods, :filter_templates
|
18
19
|
|
19
20
|
def call # _chain_nested_filter
|
@@ -135,10 +136,16 @@ module Rokaki
|
|
135
136
|
end
|
136
137
|
|
137
138
|
def build_like_query(type:, query:, filter:, mode:, key:, leaf:)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
if db == :postgres
|
140
|
+
query = "where(\"#{key}.#{leaf} #{type} ANY (ARRAY[?])\", "
|
141
|
+
query += "prepare_terms(#{filter}, :#{mode}))"
|
142
|
+
else
|
143
|
+
query = "where(\"#{key}.#{leaf} #{type} :query\", "
|
144
|
+
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
145
|
+
query += "query: \"%\#{#{filter}}\")" if mode == :prefix
|
146
|
+
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
147
|
+
end
|
148
|
+
|
142
149
|
query
|
143
150
|
end
|
144
151
|
|
data/lib/rokaki/filter_model.rb
CHANGED
@@ -7,6 +7,19 @@ module Rokaki
|
|
7
7
|
base.extend(ClassMethods)
|
8
8
|
end
|
9
9
|
|
10
|
+
def prepare_terms(param, mode)
|
11
|
+
if param.is_a? Array
|
12
|
+
return param.map { |term| "%#{term}%" } if mode == :circumfix
|
13
|
+
return param.map { |term| "%#{term}" } if mode == :prefix
|
14
|
+
return param.map { |term| "#{term}%" } if mode == :suffix
|
15
|
+
else
|
16
|
+
return ["%#{param}%"] if mode == :circumfix
|
17
|
+
return ["%#{param}"] if mode == :prefix
|
18
|
+
return ["#{param}%"] if mode == :suffix
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
10
23
|
module ClassMethods
|
11
24
|
include Filterable::ClassMethods
|
12
25
|
|
@@ -15,6 +28,7 @@ module Rokaki
|
|
15
28
|
def filter(model, options)
|
16
29
|
filter_model(model)
|
17
30
|
|
31
|
+
@_filter_db = options[:db] || :postgres
|
18
32
|
like(options[:like]) if options[:like]
|
19
33
|
ilike(options[:ilike]) if options[:ilike]
|
20
34
|
filters(*options[:match]) if options[:match]
|
@@ -42,7 +56,8 @@ module Rokaki
|
|
42
56
|
prefix: filter_key_prefix,
|
43
57
|
infix: filter_key_infix,
|
44
58
|
like_semantics: @_like_semantics,
|
45
|
-
i_like_semantics: @i_like_semantics
|
59
|
+
i_like_semantics: @i_like_semantics,
|
60
|
+
db: @_filter_db
|
46
61
|
)
|
47
62
|
basic_filter.call
|
48
63
|
|
@@ -51,21 +66,14 @@ module Rokaki
|
|
51
66
|
@_chain_filters << basic_filter.filter_template
|
52
67
|
end
|
53
68
|
|
54
|
-
def like_semantics(type:, query:, filter:, mode:, key:)
|
55
|
-
query = "@model.where(\"#{key} #{type} :query\", "
|
56
|
-
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
57
|
-
query += "query: \"%\#{#{filter}}\")" if mode == :prefix
|
58
|
-
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
59
|
-
query
|
60
|
-
end
|
61
|
-
|
62
69
|
def _chain_nested_filter(filters_object)
|
63
70
|
nested_filter = NestedFilter.new(
|
64
71
|
filter_key_object: filters_object,
|
65
72
|
prefix: filter_key_prefix,
|
66
73
|
infix: filter_key_infix,
|
67
74
|
like_semantics: @_like_semantics,
|
68
|
-
i_like_semantics: @i_like_semantics
|
75
|
+
i_like_semantics: @i_like_semantics,
|
76
|
+
db: @_filter_db
|
69
77
|
)
|
70
78
|
nested_filter.call
|
71
79
|
|
@@ -82,9 +90,9 @@ module Rokaki
|
|
82
90
|
@model.reflect_on_association(association).klass.table_name
|
83
91
|
end
|
84
92
|
|
85
|
-
def filter_model(
|
86
|
-
@model = (
|
87
|
-
class_eval "def
|
93
|
+
def filter_model(model_class)
|
94
|
+
@model = (model_class.is_a?(Class) ? model_class : Object.const_get(model_class.capitalize))
|
95
|
+
class_eval "def set_model; @model ||= #{@model}; end;"
|
88
96
|
end
|
89
97
|
|
90
98
|
def like(args)
|
@@ -132,7 +140,7 @@ module Rokaki
|
|
132
140
|
# filter_model method
|
133
141
|
#
|
134
142
|
def define_results
|
135
|
-
results_def = 'def results; model;'
|
143
|
+
results_def = 'def results; @model || set_model;'
|
136
144
|
@_chain_filters.each do |item|
|
137
145
|
results_def += item
|
138
146
|
end
|
data/lib/rokaki/version.rb
CHANGED
data/rokaki.gemspec
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.7.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-
|
11
|
+
date: 2019-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pg
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
description: A dsl for filtering data in web requests
|
154
168
|
email:
|
155
169
|
- steve@martian.media
|