rokaki 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +28 -2
- data/lib/rokaki/filter_model.rb +49 -27
- data/lib/rokaki/filterable.rb +1 -1
- data/lib/rokaki/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1731cab4173cbacc31862d09d6825ee0a6158ec70845bf78dfe3c9ed5cfa1edd
|
4
|
+
data.tar.gz: c9ff65505f778861b286f94196791bb7a36c79933e8b8136604ea1d9f97579da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee38b03675197b3cc8f9dca7f64e0475ea3c5265163de87e9110b0976f08ab6030a7e4b3a1540050ec8870ec64942af2982e9a688309e1100cc851eb6534aa6d
|
7
|
+
data.tar.gz: 9eb901aa514cd3efa3731193340033b3fc48a55e2ba76b398ecc289756a912531abda70a3604f2cf5d71d2799b5161ce11283b442267ad73e3cc94ad197df851
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -47,9 +47,10 @@ This maps attributes `date`, `author_first_name` and `author_last_name` to a fil
|
|
47
47
|
You can specify a `filter_key_prefix` and a `filter_key_infix` to change the structure of the accessors.
|
48
48
|
|
49
49
|
`filter_key_prefix :__` would result in key accessors like `__author_first_name`
|
50
|
+
|
50
51
|
`filter_key_infix :__` would result in key accessors like `author__first_name`
|
51
52
|
|
52
|
-
|
53
|
+
## ActiveRecord
|
53
54
|
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:-
|
54
55
|
|
55
56
|
```
|
@@ -80,7 +81,32 @@ filter = ArticleFilter.new(filters: params[:filters])
|
|
80
81
|
|
81
82
|
filtered_results = filter.results
|
82
83
|
|
83
|
-
|
84
|
+
```
|
85
|
+
|
86
|
+
### 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
|
+
|
89
|
+
|
90
|
+
```
|
91
|
+
class ArticleFilter
|
92
|
+
include FilterModel
|
93
|
+
|
94
|
+
filters :date, :title, author: [:first_name, :last_name]
|
95
|
+
like title: :circumfix
|
96
|
+
|
97
|
+
attr_accessor :filters
|
98
|
+
|
99
|
+
def initialize(filters:, model: Article)
|
100
|
+
@filters = filters
|
101
|
+
@model = model
|
102
|
+
end
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
Would produce a query with a LIKE which circumfixes '%' around the filter term, like:-
|
107
|
+
|
108
|
+
```
|
109
|
+
@model = @model.where('title LIKE :query', query: "%#{title}%")
|
84
110
|
```
|
85
111
|
|
86
112
|
|
data/lib/rokaki/filter_model.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rokaki
|
2
4
|
module FilterModel
|
3
5
|
include Filterable
|
@@ -7,6 +9,7 @@ module Rokaki
|
|
7
9
|
|
8
10
|
module ClassMethods
|
9
11
|
include Filterable::ClassMethods
|
12
|
+
|
10
13
|
private
|
11
14
|
|
12
15
|
def filters(*filter_keys)
|
@@ -22,44 +25,62 @@ module Rokaki
|
|
22
25
|
end
|
23
26
|
|
24
27
|
def _chain_filter(key)
|
25
|
-
|
28
|
+
filter = "#{filter_key_prefix}#{key}"
|
29
|
+
class_eval "def #{filter_key_prefix}filter_#{key};" \
|
30
|
+
"#{_chain_filter_type(key)} end;",
|
31
|
+
__FILE__, __LINE__ - 2
|
32
|
+
|
33
|
+
@_chain_filters << "@model = #{filter_key_prefix}filter_#{key} if #{filter};"
|
34
|
+
end
|
35
|
+
|
36
|
+
def _chain_filter_type(key)
|
37
|
+
filter = "#{filter_key_prefix}#{key}"
|
38
|
+
|
39
|
+
query = ""
|
40
|
+
if @_like_semantics && mode = @_like_semantics[key]
|
41
|
+
query = "@model.where(\"#{key} LIKE :query\", "
|
42
|
+
if mode == :circumfix
|
43
|
+
query += "query: \"%\#{#{filter}}%\")"
|
44
|
+
end
|
45
|
+
if mode == :prefix
|
46
|
+
query += "query: \"%\#{#{filter}}\")"
|
47
|
+
end
|
48
|
+
if mode == :suffix
|
49
|
+
query += "query: \"\#{#{filter}}%\")"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
query = "@model.where(#{filter}: #{key})"
|
53
|
+
end
|
54
|
+
"#{query};"
|
26
55
|
end
|
27
56
|
|
28
57
|
def _build_deep_chain(keys)
|
29
|
-
name =
|
58
|
+
name = filter_key_prefix.to_s
|
30
59
|
count = keys.size - 1
|
31
60
|
|
32
|
-
joins =
|
33
|
-
where =
|
34
|
-
out =
|
61
|
+
joins = ''
|
62
|
+
where = ''
|
63
|
+
out = ''
|
35
64
|
|
36
65
|
leaf = keys.pop
|
37
66
|
|
38
|
-
keys.each_with_index do |key,
|
39
|
-
|
40
|
-
|
41
|
-
|
67
|
+
keys.each_with_index do |key, _i|
|
68
|
+
next unless keys.length == 1
|
69
|
+
name = "#{filter_key_prefix}#{key}#{filter_key_infix}#{leaf}"
|
70
|
+
joins = ":#{key}"
|
42
71
|
|
43
|
-
|
44
|
-
end
|
72
|
+
where = "{ #{key.to_s.pluralize}: { #{leaf}: #{name} } }"
|
45
73
|
end
|
46
74
|
|
47
|
-
# keys.each_with_index do |key, i|
|
48
|
-
# name += key.to_s
|
49
|
-
# name += filter_key_infix.to_s unless count == i
|
50
|
-
|
51
|
-
# joins += "{ #{key.to_s}: " unless count == i
|
52
|
-
# where += "{ #{key.to_s.pluralize}: " unless count == i
|
53
|
-
# out += " }" unless count == i
|
54
|
-
|
55
|
-
# joins += key.to_s if count == i
|
56
|
-
# where += name if count == i
|
57
|
-
# end
|
58
75
|
|
59
76
|
joins = joins += out
|
60
77
|
where = where += out
|
61
78
|
|
62
|
-
|
79
|
+
class_eval "def #{filter_key_prefix.to_s}filter_#{name};"\
|
80
|
+
"@model.joins(#{joins}).where(#{where}); end;",
|
81
|
+
__FILE__, __LINE__ - 2
|
82
|
+
|
83
|
+
@_chain_filters << "@model = #{filter_key_prefix}filter_#{name} if #{name};"
|
63
84
|
end
|
64
85
|
|
65
86
|
def _chain_nested(filters_object)
|
@@ -76,8 +97,9 @@ module Rokaki
|
|
76
97
|
@model = model
|
77
98
|
end
|
78
99
|
|
79
|
-
def like(
|
80
|
-
|
100
|
+
def like(args)
|
101
|
+
raise ArgumentError, 'argument mush be a hash' unless args.is_a? Hash
|
102
|
+
@_like_semantics = (@_like_semantics || {}).merge(args)
|
81
103
|
end
|
82
104
|
|
83
105
|
def deep_chain(keys, value)
|
@@ -102,12 +124,12 @@ module Rokaki
|
|
102
124
|
end
|
103
125
|
|
104
126
|
def define_results
|
105
|
-
results_def =
|
127
|
+
results_def = 'def results;'
|
106
128
|
@_chain_filters.each do |item|
|
107
129
|
results_def += item
|
108
130
|
end
|
109
131
|
results_def += '@model;end;'
|
110
|
-
class_eval results_def
|
132
|
+
class_eval results_def, __FILE__, __LINE__
|
111
133
|
end
|
112
134
|
end
|
113
135
|
end
|
data/lib/rokaki/filterable.rb
CHANGED
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.3.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-09-
|
11
|
+
date: 2019-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|