rokaki 0.4.1 → 0.5.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: e5d32983f1791295aadabcc64fafca2e7cda63e679b0e37fcf38fc41085679e5
4
- data.tar.gz: f1125b9db501745d1d3cad0da31b378f90fd1e5b44b2cdf0e8a2429eea91dea2
3
+ metadata.gz: ebc3f6bb8aab2597c36dd7876792e22395a56a8d099b18cb0d48157e178e81bf
4
+ data.tar.gz: df20e88198f10346531fa5e5ffde6c8627ef5d19192119b07362865175e7357a
5
5
  SHA512:
6
- metadata.gz: fcac7ca5e906933335255fb59c63b2e8114a864cd8a6c9f2868c9e64a25566c6c00d9439c01dc372b123443e953cd45930ceb93bc80cd43dc3f6da48ad029f83
7
- data.tar.gz: c9f3742c1ec502b04453ab373eff82646c67b8d134981b67838666f185d5b6d36fefc0371ee386d60fda6a17f6e2e90d52a17e6de5963bb501d365a8e4eb4c24
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
@@ -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 = "@model.where(\"#{key} LIKE :query\", "
58
- query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
59
- query += "query: \"%\#{#{filter}}\")" if mode == :prefix
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|
@@ -1,3 +1,3 @@
1
1
  module Rokaki
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  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.4.1
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-16 00:00:00.000000000 Z
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/like.rb
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