rokaki 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -8
- data/lib/rokaki/filter_model/like_keys.rb +48 -0
- data/lib/rokaki/filter_model.rb +21 -4
- data/lib/rokaki/version.rb +1 -1
- metadata +3 -3
- data/lib/rokaki/filter_model/like.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebc3f6bb8aab2597c36dd7876792e22395a56a8d099b18cb0d48157e178e81bf
|
4
|
+
data.tar.gz: df20e88198f10346531fa5e5ffde6c8627ef5d19192119b07362865175e7357a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f419fea3a5e3e292d8f44c6006df9ee799d49b4a1aa14820441c2e76c21cb514b668079ea9b727bc64cfb65d107efb162d49a1176bfadc5037b588db2323352
|
7
|
+
data.tar.gz: c683abe335a7d84718da478711c10704830470771e92420cd3ad3540a1062dbb065865e58fdcea4e0d5478cf4ab43293413ed7e0c6337e6f8d8a19e760a67555
|
data/README.md
CHANGED
@@ -23,7 +23,7 @@ To use the basic DSL include the `Rokaki::Filterable` module
|
|
23
23
|
|
24
24
|
A simple example might be:-
|
25
25
|
|
26
|
-
```
|
26
|
+
```ruby
|
27
27
|
class FilterArticles
|
28
28
|
include Rokaki::Filterable
|
29
29
|
|
@@ -55,7 +55,7 @@ You can specify a `filter_key_prefix` and a `filter_key_infix` to change the str
|
|
55
55
|
## ActiveRecord
|
56
56
|
Include `Rokaki::FilterModel` in any ActiveRecord model (only AR >= 6.0.0 tested so far) you can generate the filter keys and the actual filter lookup code using the `filters` keyword on a model like so:-
|
57
57
|
|
58
|
-
```
|
58
|
+
```ruby
|
59
59
|
# Given the models
|
60
60
|
class Author < ActiveRecord::Base
|
61
61
|
has_many :articles, inverse_of: :author
|
@@ -86,17 +86,17 @@ filtered_results = filter.results
|
|
86
86
|
```
|
87
87
|
|
88
88
|
### Partial matching
|
89
|
-
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
|
+
You can use `like` (or, if you use postgres, the case insensitive `ilike`) 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:-
|
90
90
|
|
91
91
|
#### 1. The `filter` command syntax
|
92
92
|
|
93
93
|
|
94
|
-
```
|
94
|
+
```ruby
|
95
95
|
class ArticleFilter
|
96
96
|
include FilterModel
|
97
97
|
|
98
98
|
filter :article,
|
99
|
-
like: {
|
99
|
+
like: { # you can use ilike here instead if you use postgres and want case insensitive results
|
100
100
|
author: {
|
101
101
|
first_name: :circumfix,
|
102
102
|
last_name: :circumfix
|
@@ -117,12 +117,13 @@ Or
|
|
117
117
|
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`
|
118
118
|
|
119
119
|
|
120
|
-
```
|
120
|
+
```ruby
|
121
121
|
class ArticleFilter
|
122
122
|
include FilterModel
|
123
123
|
|
124
124
|
filters :date, :title, author: [:first_name, :last_name]
|
125
125
|
like title: :circumfix
|
126
|
+
# ilike title: :circumfix # case insensitive postgres mode
|
126
127
|
|
127
128
|
attr_accessor :filters
|
128
129
|
|
@@ -135,7 +136,7 @@ end
|
|
135
136
|
|
136
137
|
Or without the model in the initializer
|
137
138
|
|
138
|
-
```
|
139
|
+
```ruby
|
139
140
|
class ArticleFilter
|
140
141
|
include FilterModel
|
141
142
|
|
@@ -153,7 +154,7 @@ end
|
|
153
154
|
|
154
155
|
Would produce a query with a LIKE which circumfixes '%' around the filter term, like:-
|
155
156
|
|
156
|
-
```
|
157
|
+
```ruby
|
157
158
|
@model = @model.where('title LIKE :query', query: "%#{title}%")
|
158
159
|
```
|
159
160
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rokaki
|
4
|
+
module FilterModel
|
5
|
+
class LikeKeys
|
6
|
+
def initialize(args)
|
7
|
+
@args = args
|
8
|
+
@like_keys = []
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :args, :like_keys
|
12
|
+
|
13
|
+
def call
|
14
|
+
args.keys.each do |key|
|
15
|
+
like_keys << map_keys(args[key], key)
|
16
|
+
end
|
17
|
+
like_keys
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def map_keys(value, key)
|
23
|
+
key_result = {}
|
24
|
+
|
25
|
+
if value.is_a? Hash
|
26
|
+
value.keys.each do |sub_key|
|
27
|
+
sub_value = value[sub_key]
|
28
|
+
|
29
|
+
if sub_value.is_a? Symbol
|
30
|
+
if key_result[key].is_a? Array
|
31
|
+
key_result[key] << sub_key
|
32
|
+
else
|
33
|
+
key_result[key] = [ sub_key ]
|
34
|
+
end
|
35
|
+
|
36
|
+
elsif sub_value.is_a? Hash
|
37
|
+
key_result[key] = map_keys(sub_value, sub_key)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
key_result = key
|
42
|
+
end
|
43
|
+
|
44
|
+
key_result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/rokaki/filter_model.rb
CHANGED
@@ -16,6 +16,7 @@ module Rokaki
|
|
16
16
|
filter_model(model)
|
17
17
|
|
18
18
|
like(options[:like]) if options[:like]
|
19
|
+
ilike(options[:ilike]) if options[:ilike]
|
19
20
|
filters(*options[:match]) if options[:match]
|
20
21
|
end
|
21
22
|
|
@@ -54,10 +55,9 @@ module Rokaki
|
|
54
55
|
|
55
56
|
query = ''
|
56
57
|
if @_like_semantics && mode = @_like_semantics[key]
|
57
|
-
query =
|
58
|
-
|
59
|
-
query
|
60
|
-
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
58
|
+
query = like_semantics(type: 'LIKE', query: query, filter: filter, mode: mode, key: key)
|
59
|
+
elsif @i_like_semantics && mode = @i_like_semantics[key]
|
60
|
+
query = like_semantics(type: 'ILIKE', query: query, filter: filter, mode: mode, key: key)
|
61
61
|
else
|
62
62
|
query = "@model.where(#{filter}: #{key})"
|
63
63
|
end
|
@@ -65,6 +65,14 @@ module Rokaki
|
|
65
65
|
query
|
66
66
|
end
|
67
67
|
|
68
|
+
def like_semantics(type:, query:, filter:, mode:, key:)
|
69
|
+
query = "@model.where(\"#{key} #{type} :query\", "
|
70
|
+
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
71
|
+
query += "query: \"%\#{#{filter}}\")" if mode == :prefix
|
72
|
+
query += "query: \"\#{#{filter}}%\")" if mode == :suffix
|
73
|
+
query
|
74
|
+
end
|
75
|
+
|
68
76
|
def _build_deep_chain(keys)
|
69
77
|
name = filter_key_prefix.to_s
|
70
78
|
count = keys.size - 1
|
@@ -120,6 +128,15 @@ module Rokaki
|
|
120
128
|
filters(*key_builder.call)
|
121
129
|
end
|
122
130
|
|
131
|
+
def ilike(args)
|
132
|
+
raise ArgumentError, 'argument mush be a hash' unless args.is_a? Hash
|
133
|
+
@i_like_semantics = (@i_like_semantics || {}).merge(args)
|
134
|
+
|
135
|
+
key_builder = LikeKeys.new(args)
|
136
|
+
|
137
|
+
filters(*key_builder.call)
|
138
|
+
end
|
139
|
+
|
123
140
|
def deep_chain(keys, value)
|
124
141
|
if value.is_a? Hash
|
125
142
|
value.keys.map do |key|
|
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.5.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-10-
|
11
|
+
date: 2019-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -143,7 +143,7 @@ files:
|
|
143
143
|
- bin/setup
|
144
144
|
- lib/rokaki.rb
|
145
145
|
- lib/rokaki/filter_model.rb
|
146
|
-
- lib/rokaki/filter_model/
|
146
|
+
- lib/rokaki/filter_model/like_keys.rb
|
147
147
|
- lib/rokaki/filterable.rb
|
148
148
|
- lib/rokaki/version.rb
|
149
149
|
- rokaki.gemspec
|
File without changes
|