rokaki 0.2.0 → 0.3.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 +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
|