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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7da479ed93b1e8e6aa8e91e080356e71b39061a647960175c49ef0f5a1b90855
4
- data.tar.gz: 021aaa044351b96fec1566c1e900f816908cc9a7dcd53d7d8b2a547e7d120872
3
+ metadata.gz: a46db4e821b0a8fb7f661ed539c18c6509b0a644b3bc0f790c0619ab72ff4108
4
+ data.tar.gz: f6ae9809a6a82c9a1de24ecf7d79b9f0cc6cab530579751df919832c0fa3593e
5
5
  SHA512:
6
- metadata.gz: 6f4b5be13f85b953aced1c4269539d5abe5c2611a22bbc3fdda2c19c8254e872116b51ec235e856015e0574f8439d761d3eb433c6f94499683590084814b560d
7
- data.tar.gz: fb29f358eca0b1186afd6cb1417538bac16731a8a2c1faf06c9526afd7e00bc93bcbdfd642b1a8912b02fbe39318842e8730a738586e64ed5df5d7915e94a6b2
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.5.1)
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
- query = "@model.where(\"#{key} #{type} :query\", "
63
- query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
64
- query += "query: \"%\#{#{filter}}\")" if mode == :prefix
65
- query += "query: \"\#{#{filter}}%\")" if mode == :suffix
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
- query = "where(\"#{key}.#{leaf} #{type} :query\", "
139
- query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
140
- query += "query: \"%\#{#{filter}}\")" if mode == :prefix
141
- query += "query: \"\#{#{filter}}%\")" if mode == :suffix
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
 
@@ -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(model)
86
- @model = (model.is_a?(Class) ? model : Object.const_get(model.capitalize))
87
- class_eval "def model; @model ||= #{@model}; end;"
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
@@ -1,3 +1,3 @@
1
1
  module Rokaki
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/rokaki.gemspec CHANGED
@@ -41,4 +41,5 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency 'rake', '~> 10.0'
42
42
  spec.add_development_dependency 'rspec', '~> 3.0'
43
43
  spec.add_development_dependency 'sqlite3'
44
+ spec.add_development_dependency 'pg'
44
45
  end
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.6.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-07 00:00:00.000000000 Z
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