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 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