jsonb_accessor 1.0.0.beta.2 → 1.0.0.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -1
- data/Appraisals +1 -1
- data/README.md +35 -2
- data/db/migrate/20150407031737_set_up_testing_db.rb +1 -1
- data/gemfiles/activerecord_5.0.0.gemfile +1 -1
- data/gemfiles/activerecord_5.0.0.gemfile.lock +39 -39
- data/jsonb_accessor.gemspec +1 -1
- data/lib/jsonb_accessor/macro.rb +51 -13
- data/lib/jsonb_accessor/query_builder.rb +55 -2
- data/lib/jsonb_accessor/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: daa3bf1bf3902f9507356358bb715623a66f622a
|
4
|
+
data.tar.gz: b6f917cb7dab2ad61077a23a2b94d8a65545b6f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d3f263eb28a0b7f2d0b1f813cc0a9d24b2b1fd0814eca2916ca474d150eb751287e064b82464f541224a53a4b6576bffc35012a56a4ea84bf240646e5c3a288
|
7
|
+
data.tar.gz: 5a41d9c6cd1b5d45b3d8f76b974493c668a28453575d0247fb896cc842edfcc898d4d3aedc6158c54e8786cdcb0b962c7bf7be942b169699951aa4695fb561c3
|
data/.rubocop.yml
CHANGED
@@ -23,9 +23,11 @@ Metrics/MethodLength:
|
|
23
23
|
Enabled: false
|
24
24
|
Metrics/ModuleLength:
|
25
25
|
Enabled: false
|
26
|
+
Metrics/PerceivedComplexity:
|
27
|
+
Enabled: false
|
26
28
|
Metrics/BlockLength:
|
27
29
|
Enabled: false
|
28
|
-
|
30
|
+
Security/YAMLLoad:
|
29
31
|
Enabled: false
|
30
32
|
Style/AlignParameters:
|
31
33
|
Enabled: false
|
data/Appraisals
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,7 @@ This README reflects the most recent 1.0 beta. Method names and interfaces may s
|
|
27
27
|
Add this line to your application's `Gemfile`:
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
gem "jsonb_accessor", "1.0.0.beta.
|
30
|
+
gem "jsonb_accessor", "1.0.0.beta.3"
|
31
31
|
```
|
32
32
|
|
33
33
|
And then execute:
|
@@ -71,6 +71,8 @@ class Product < ActiveRecord::Base
|
|
71
71
|
end
|
72
72
|
```
|
73
73
|
|
74
|
+
A brief note about defaults: `default` works pretty much as you would expect in practice, but it actually becomes part of a defaults hash that is the `default` value for the jsonb column (in the above example it would be `:data`).
|
75
|
+
|
74
76
|
You can also pass in a `store_key` option.
|
75
77
|
|
76
78
|
```ruby
|
@@ -103,12 +105,18 @@ class Product < ActiveRecord::Base
|
|
103
105
|
end
|
104
106
|
```
|
105
107
|
|
106
|
-
Jsonb Accessor will add a `scope` to `Product` called `data_where`.
|
108
|
+
Jsonb Accessor will add a `scope` to `Product` called like the json column with `_where` suffix, in our case `data_where`.
|
107
109
|
|
108
110
|
```ruby
|
109
111
|
Product.all.data_where(name: "Granite Towel", price: 17)
|
110
112
|
```
|
111
113
|
|
114
|
+
Similarly, it will also add a `data_where_not` `scope` to `Product`.
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
Product.all.data_where_not(name: "Plasma Fork")
|
118
|
+
```
|
119
|
+
|
112
120
|
For number fields you can query using `<` or `>`or use plain english if that's what you prefer.
|
113
121
|
|
114
122
|
```ruby
|
@@ -157,6 +165,15 @@ Product.all.jsonb_contains(:data, reviewed_at: 10.minutes.ago, p: 12) # Using th
|
|
157
165
|
|
158
166
|
**Note:** Under the hood, `jsonb_contains` uses the [`@>` operator in Postgres](https://www.postgresql.org/docs/9.5/static/functions-json.html) so when you include an array query, the stored array and the array used for the query do not need to match exactly. For example, when queried with `[1, 2]`, records that have arrays of `[2, 1, 3]` will be returned.
|
159
167
|
|
168
|
+
### `jsonb_excludes`
|
169
|
+
|
170
|
+
Returns all records that exclude the given JSON paths. Pretty much the opposite of `jsonb_contains`. Note that this will automatically exclude all records that contain `null` in their jsonb column (the `data` column, in the example below).
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Product.all.jsonb_excludes(:data, title: "foo")
|
174
|
+
Product.all.jsonb_excludes(:data, reviewed_at: 10.minutes.ago, p: 12) # Using the store key
|
175
|
+
```
|
176
|
+
|
160
177
|
### `jsonb_number_where`
|
161
178
|
|
162
179
|
Returns all records that match the given criteria.
|
@@ -178,6 +195,14 @@ It supports:
|
|
178
195
|
|
179
196
|
and it is indifferent to strings/symbols.
|
180
197
|
|
198
|
+
### `jsonb_number_where_not`
|
199
|
+
|
200
|
+
Returns all records that do not match the given criteria. It's the opposite of `jsonb_number_where`. Note that this will automatically exclude all records that contain `null` in their jsonb column (the `data` column, in the example below).
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
Product.all.jsonb_number_where_not(:data, :price_in_cents, :greater_than, 300)
|
204
|
+
```
|
205
|
+
|
181
206
|
### `jsonb_time_where`
|
182
207
|
|
183
208
|
Returns all records that match the given criteria.
|
@@ -188,6 +213,14 @@ Product.all.jsonb_time_where(:data, :reviewed_at, :before, 2.days.ago)
|
|
188
213
|
|
189
214
|
It supports `before` and `after` and is indifferent to strings/symbols.
|
190
215
|
|
216
|
+
### `jsonb_time_where_not`
|
217
|
+
|
218
|
+
Returns all records that match the given criteria. The opposite of `jsonb_time_where`. Note that this will automatically exclude all records that contain `null` in their jsonb column (the `data` column, in the example below).
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
Product.all.jsonb_time_where_not(:data, :reviewed_at, :before, 2.days.ago)
|
222
|
+
```
|
223
|
+
|
191
224
|
## Single-Table Inheritance
|
192
225
|
|
193
226
|
One of the big issues with `ActiveRecord` single-table inheritance (STI)
|
@@ -1,33 +1,33 @@
|
|
1
1
|
PATH
|
2
|
-
remote:
|
2
|
+
remote: ..
|
3
3
|
specs:
|
4
|
-
jsonb_accessor (1.0.0.beta.
|
5
|
-
activerecord (>= 5.0
|
4
|
+
jsonb_accessor (1.0.0.beta.3)
|
5
|
+
activerecord (>= 5.0)
|
6
6
|
pg (>= 0.18.1)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
actionpack (5.0.
|
12
|
-
actionview (= 5.0.
|
13
|
-
activesupport (= 5.0.
|
11
|
+
actionpack (5.0.2)
|
12
|
+
actionview (= 5.0.2)
|
13
|
+
activesupport (= 5.0.2)
|
14
14
|
rack (~> 2.0)
|
15
15
|
rack-test (~> 0.6.3)
|
16
16
|
rails-dom-testing (~> 2.0)
|
17
17
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
18
|
-
actionview (5.0.
|
19
|
-
activesupport (= 5.0.
|
18
|
+
actionview (5.0.2)
|
19
|
+
activesupport (= 5.0.2)
|
20
20
|
builder (~> 3.1)
|
21
21
|
erubis (~> 2.7.0)
|
22
22
|
rails-dom-testing (~> 2.0)
|
23
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.
|
24
|
-
activemodel (5.0.
|
25
|
-
activesupport (= 5.0.
|
26
|
-
activerecord (5.0.
|
27
|
-
activemodel (= 5.0.
|
28
|
-
activesupport (= 5.0.
|
23
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
24
|
+
activemodel (5.0.2)
|
25
|
+
activesupport (= 5.0.2)
|
26
|
+
activerecord (5.0.2)
|
27
|
+
activemodel (= 5.0.2)
|
28
|
+
activesupport (= 5.0.2)
|
29
29
|
arel (~> 7.0)
|
30
|
-
activesupport (5.0.
|
30
|
+
activesupport (5.0.2)
|
31
31
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
32
32
|
i18n (~> 0.7)
|
33
33
|
minitest (~> 5.1)
|
@@ -39,48 +39,48 @@ GEM
|
|
39
39
|
arel (7.1.4)
|
40
40
|
ast (2.3.0)
|
41
41
|
awesome_print (1.7.0)
|
42
|
-
builder (3.2.
|
42
|
+
builder (3.2.3)
|
43
43
|
coderay (1.1.1)
|
44
|
-
concurrent-ruby (1.0.
|
44
|
+
concurrent-ruby (1.0.5)
|
45
45
|
database_cleaner (1.5.3)
|
46
|
-
diff-lcs (1.
|
46
|
+
diff-lcs (1.3)
|
47
47
|
erubis (2.7.0)
|
48
|
-
i18n (0.
|
48
|
+
i18n (0.8.1)
|
49
49
|
loofah (2.0.3)
|
50
50
|
nokogiri (>= 1.5.9)
|
51
51
|
method_source (0.8.2)
|
52
52
|
mini_portile2 (2.1.0)
|
53
|
-
minitest (5.
|
54
|
-
nokogiri (1.
|
53
|
+
minitest (5.10.1)
|
54
|
+
nokogiri (1.7.0.1)
|
55
55
|
mini_portile2 (~> 2.1.0)
|
56
|
-
parser (2.
|
56
|
+
parser (2.4.0.0)
|
57
57
|
ast (~> 2.2)
|
58
|
-
pg (0.
|
58
|
+
pg (0.20.0)
|
59
59
|
powerpack (0.1.1)
|
60
60
|
pry (0.10.4)
|
61
61
|
coderay (~> 1.1.0)
|
62
62
|
method_source (~> 0.8.1)
|
63
63
|
slop (~> 3.4)
|
64
|
-
pry-doc (0.
|
64
|
+
pry-doc (0.10.0)
|
65
65
|
pry (~> 0.9)
|
66
|
-
yard (~> 0.
|
66
|
+
yard (~> 0.9)
|
67
67
|
pry-nav (0.2.4)
|
68
68
|
pry (>= 0.9.10, < 0.11.0)
|
69
69
|
rack (2.0.1)
|
70
70
|
rack-test (0.6.3)
|
71
71
|
rack (>= 1.0)
|
72
|
-
rails-dom-testing (2.0.
|
72
|
+
rails-dom-testing (2.0.2)
|
73
73
|
activesupport (>= 4.2.0, < 6.0)
|
74
|
-
nokogiri (~> 1.6
|
74
|
+
nokogiri (~> 1.6)
|
75
75
|
rails-html-sanitizer (1.0.3)
|
76
76
|
loofah (~> 2.0)
|
77
|
-
railties (5.0.
|
78
|
-
actionpack (= 5.0.
|
79
|
-
activesupport (= 5.0.
|
77
|
+
railties (5.0.2)
|
78
|
+
actionpack (= 5.0.2)
|
79
|
+
activesupport (= 5.0.2)
|
80
80
|
method_source
|
81
81
|
rake (>= 0.8.7)
|
82
82
|
thor (>= 0.18.1, < 2.0)
|
83
|
-
rainbow (2.1
|
83
|
+
rainbow (2.2.1)
|
84
84
|
rake (10.5.0)
|
85
85
|
rspec (3.5.0)
|
86
86
|
rspec-core (~> 3.5.0)
|
@@ -95,8 +95,8 @@ GEM
|
|
95
95
|
diff-lcs (>= 1.2.0, < 2.0)
|
96
96
|
rspec-support (~> 3.5.0)
|
97
97
|
rspec-support (3.5.0)
|
98
|
-
rubocop (0.
|
99
|
-
parser (>= 2.3.
|
98
|
+
rubocop (0.47.1)
|
99
|
+
parser (>= 2.3.3.1, < 3.0)
|
100
100
|
powerpack (~> 0.1)
|
101
101
|
rainbow (>= 1.99.1, < 3.0)
|
102
102
|
ruby-progressbar (~> 1.7)
|
@@ -109,18 +109,18 @@ GEM
|
|
109
109
|
activerecord (>= 4.2.7, < 5.1.0)
|
110
110
|
railties (>= 4.2.7, < 5.1.0)
|
111
111
|
rake (~> 10.0)
|
112
|
-
thor (0.19.
|
113
|
-
thread_safe (0.3.
|
112
|
+
thor (0.19.4)
|
113
|
+
thread_safe (0.3.6)
|
114
114
|
tzinfo (1.2.2)
|
115
115
|
thread_safe (~> 0.1)
|
116
|
-
unicode-display_width (1.1.
|
117
|
-
yard (0.9.
|
116
|
+
unicode-display_width (1.1.3)
|
117
|
+
yard (0.9.8)
|
118
118
|
|
119
119
|
PLATFORMS
|
120
120
|
ruby
|
121
121
|
|
122
122
|
DEPENDENCIES
|
123
|
-
activerecord (
|
123
|
+
activerecord (~> 5.0.0)
|
124
124
|
appraisal
|
125
125
|
awesome_print
|
126
126
|
bundler (~> 1.9)
|
@@ -137,4 +137,4 @@ DEPENDENCIES
|
|
137
137
|
standalone_migrations
|
138
138
|
|
139
139
|
BUNDLED WITH
|
140
|
-
1.
|
140
|
+
1.14.6
|
data/jsonb_accessor.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency "activerecord", ">= 5.0
|
23
|
+
spec.add_dependency "activerecord", ">= 5.0"
|
24
24
|
spec.add_dependency "pg", ">= 0.18.1"
|
25
25
|
|
26
26
|
spec.add_development_dependency "appraisal"
|
data/lib/jsonb_accessor/macro.rb
CHANGED
@@ -3,16 +3,50 @@ module JsonbAccessor
|
|
3
3
|
module Macro
|
4
4
|
module ClassMethods
|
5
5
|
def jsonb_accessor(jsonb_attribute, field_types)
|
6
|
-
field_names = field_types.keys
|
7
6
|
names_and_store_keys = field_types.each_with_object({}) do |(name, type), mapping|
|
8
7
|
_type, options = Array(type)
|
9
8
|
mapping[name.to_s] = (options.try(:delete, :store_key) || name).to_s
|
10
9
|
end
|
10
|
+
|
11
11
|
# Defines virtual attributes for each jsonb field.
|
12
12
|
field_types.each do |name, type|
|
13
13
|
attribute name, *type
|
14
14
|
end
|
15
15
|
|
16
|
+
store_key_mapping_method_name = "jsonb_store_key_mapping_for_#{jsonb_attribute}"
|
17
|
+
# Defines methods on the model class
|
18
|
+
class_methods = Module.new do
|
19
|
+
# Allows us to get a mapping of field names to store keys scoped to the column
|
20
|
+
define_method(store_key_mapping_method_name) do
|
21
|
+
superclass_mapping = superclass.try(store_key_mapping_method_name) || {}
|
22
|
+
superclass_mapping.merge(names_and_store_keys)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# We extend with class methods here so we can use the results of methods it defines to define more useful methods later
|
26
|
+
extend class_methods
|
27
|
+
|
28
|
+
# Get field names to default values mapping
|
29
|
+
names_and_defaults = field_types.each_with_object({}) do |(name, type), mapping|
|
30
|
+
_type, options = Array(type)
|
31
|
+
field_default = options.try(:delete, :default)
|
32
|
+
mapping[name.to_s] = field_default if field_default
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get store keys to default values mapping
|
36
|
+
store_keys_and_defaults = ::JsonbAccessor::QueryBuilder.convert_keys_to_store_keys(names_and_defaults, public_send(store_key_mapping_method_name))
|
37
|
+
|
38
|
+
# Define jsonb_defaults_mapping_for_<jsonb_attribute>
|
39
|
+
defaults_mapping_method_name = "jsonb_defaults_mapping_for_#{jsonb_attribute}"
|
40
|
+
class_methods.instance_eval do
|
41
|
+
define_method(defaults_mapping_method_name) do
|
42
|
+
superclass_mapping = superclass.try(defaults_mapping_method_name) || {}
|
43
|
+
superclass_mapping.merge(store_keys_and_defaults)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
all_defaults_mapping = public_send(defaults_mapping_method_name)
|
48
|
+
attribute jsonb_attribute, :jsonb, default: all_defaults_mapping if all_defaults_mapping.present?
|
49
|
+
|
16
50
|
# Setters are in a module to allow users to override them and still be able to use `super`.
|
17
51
|
setters = Module.new do
|
18
52
|
# Overrides the setter created by `attribute` above to make sure the jsonb attribute is kept in sync.
|
@@ -25,16 +59,17 @@ module JsonbAccessor
|
|
25
59
|
end
|
26
60
|
|
27
61
|
# Overrides the jsonb attribute setter to make sure the jsonb fields are kept in sync.
|
28
|
-
define_method("#{jsonb_attribute}=") do |
|
29
|
-
|
30
|
-
|
31
|
-
new_value[store_key] = indifferent_value[name]
|
32
|
-
end
|
62
|
+
define_method("#{jsonb_attribute}=") do |given_value|
|
63
|
+
value = given_value || {}
|
64
|
+
names_to_store_keys = self.class.public_send(store_key_mapping_method_name)
|
33
65
|
|
34
|
-
|
66
|
+
empty_store_key_attributes = names_to_store_keys.values.each_with_object({}) { |name, defaults| defaults[name] = nil }
|
67
|
+
empty_named_attributes = names_to_store_keys.keys.each_with_object({}) { |name, defaults| defaults[name] = nil }
|
35
68
|
|
36
|
-
|
37
|
-
|
69
|
+
store_key_attributes = ::JsonbAccessor::QueryBuilder.convert_keys_to_store_keys(value, names_to_store_keys)
|
70
|
+
write_attribute(jsonb_attribute, empty_store_key_attributes.merge(store_key_attributes))
|
71
|
+
|
72
|
+
empty_named_attributes.merge(value).each { |name, attribute_value| write_attribute(name, attribute_value) }
|
38
73
|
end
|
39
74
|
end
|
40
75
|
include setters
|
@@ -51,12 +86,15 @@ module JsonbAccessor
|
|
51
86
|
|
52
87
|
# <jsonb_attribute>_where scope
|
53
88
|
scope("#{jsonb_attribute}_where", lambda do |attributes|
|
54
|
-
store_key_attributes =
|
55
|
-
store_key = names_and_store_keys[name.to_s]
|
56
|
-
new_attributes[store_key] = value
|
57
|
-
end
|
89
|
+
store_key_attributes = ::JsonbAccessor::QueryBuilder.convert_keys_to_store_keys(attributes, all.model.public_send(store_key_mapping_method_name))
|
58
90
|
jsonb_where(jsonb_attribute, store_key_attributes)
|
59
91
|
end)
|
92
|
+
|
93
|
+
# <jsonb_attribute>_where_not scope
|
94
|
+
scope("#{jsonb_attribute}_where_not", lambda do |attributes|
|
95
|
+
store_key_attributes = ::JsonbAccessor::QueryBuilder.convert_keys_to_store_keys(attributes, all.model.public_send(store_key_mapping_method_name))
|
96
|
+
jsonb_where_not(jsonb_attribute, store_key_attributes)
|
97
|
+
end)
|
60
98
|
end
|
61
99
|
end
|
62
100
|
end
|
@@ -41,21 +41,56 @@ module JsonbAccessor
|
|
41
41
|
|
42
42
|
module QueryBuilder
|
43
43
|
extend ActiveSupport::Concern
|
44
|
+
InvalidColumnName = Class.new(StandardError)
|
45
|
+
|
46
|
+
def self.validate_column_name!(query, column_name)
|
47
|
+
if query.model.columns.none? { |column| column.name == column_name.to_s }
|
48
|
+
raise InvalidColumnName, "a column named `#{column_name}` does not exist on the `#{query.model.table_name}` table"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.convert_keys_to_store_keys(attributes, store_key_mapping)
|
53
|
+
attributes.each_with_object({}) do |(name, value), new_attributes|
|
54
|
+
store_key = store_key_mapping[name.to_s]
|
55
|
+
new_attributes[store_key] = value
|
56
|
+
end
|
57
|
+
end
|
44
58
|
|
45
59
|
included do
|
46
|
-
scope(:jsonb_contains,
|
47
|
-
|
60
|
+
scope(:jsonb_contains, lambda do |column_name, attributes|
|
61
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
62
|
+
where("#{table_name}.#{column_name} @> (?)::jsonb", attributes.to_json)
|
63
|
+
end)
|
64
|
+
|
65
|
+
scope(:jsonb_excludes, lambda do |column_name, attributes|
|
66
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
67
|
+
where.not("#{table_name}.#{column_name} @> (?)::jsonb", attributes.to_json)
|
68
|
+
end)
|
48
69
|
|
49
70
|
scope(:jsonb_number_where, lambda do |column_name, field_name, given_operator, value|
|
71
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
50
72
|
operator = JsonbAccessor::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
51
73
|
where("(#{table_name}.#{column_name} ->> ?)::float #{operator} ?", field_name, value)
|
52
74
|
end)
|
53
75
|
|
76
|
+
scope(:jsonb_number_where_not, lambda do |column_name, field_name, given_operator, value|
|
77
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
78
|
+
operator = JsonbAccessor::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
79
|
+
where.not("(#{table_name}.#{column_name} ->> ?)::float #{operator} ?", field_name, value)
|
80
|
+
end)
|
81
|
+
|
54
82
|
scope(:jsonb_time_where, lambda do |column_name, field_name, given_operator, value|
|
83
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
55
84
|
operator = JsonbAccessor::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
56
85
|
where("(#{table_name}.#{column_name} ->> ?)::timestamp #{operator} ?", field_name, value)
|
57
86
|
end)
|
58
87
|
|
88
|
+
scope(:jsonb_time_where_not, lambda do |column_name, field_name, given_operator, value|
|
89
|
+
JsonbAccessor::QueryBuilder.validate_column_name!(all, column_name)
|
90
|
+
operator = JsonbAccessor::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
91
|
+
where.not("(#{table_name}.#{column_name} ->> ?)::timestamp #{operator} ?", field_name, value)
|
92
|
+
end)
|
93
|
+
|
59
94
|
scope(:jsonb_where, lambda do |column_name, attributes|
|
60
95
|
query = all
|
61
96
|
contains_attributes = {}
|
@@ -73,6 +108,24 @@ module JsonbAccessor
|
|
73
108
|
|
74
109
|
query.jsonb_contains(column_name, contains_attributes)
|
75
110
|
end)
|
111
|
+
|
112
|
+
scope(:jsonb_where_not, lambda do |column_name, attributes|
|
113
|
+
query = all
|
114
|
+
excludes_attributes = {}
|
115
|
+
|
116
|
+
attributes.each do |name, value|
|
117
|
+
case value
|
118
|
+
when IS_NUMBER_QUERY_ARGUMENTS
|
119
|
+
value.each { |operator, query_value| query = query.jsonb_number_where_not(column_name, name, operator, query_value) }
|
120
|
+
when IS_TIME_QUERY_ARGUMENTS
|
121
|
+
value.each { |operator, query_value| query = query.jsonb_time_where_not(column_name, name, operator, query_value) }
|
122
|
+
else
|
123
|
+
excludes_attributes[name] = value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
excludes_attributes.empty? ? query : query.jsonb_excludes(column_name, excludes_attributes)
|
128
|
+
end)
|
76
129
|
end
|
77
130
|
end
|
78
131
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonb_accessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
4
|
+
version: 1.0.0.beta.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Crismali
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2017-03-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 5.0
|
21
|
+
version: '5.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 5.0
|
28
|
+
version: '5.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: pg
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|