jsonb_accessor 1.0.0.beta.5 → 1.2.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/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/.travis.yml +7 -4
- data/Appraisals +1 -3
- data/README.md +35 -10
- data/gemfiles/activerecord_5.0.0.gemfile +0 -1
- data/gemfiles/activerecord_5.1.0.gemfile +1 -2
- data/jsonb_accessor.gemspec +7 -7
- data/lib/jsonb_accessor.rb +1 -0
- data/lib/jsonb_accessor/macro.rb +31 -11
- data/lib/jsonb_accessor/query_builder.rb +23 -92
- data/lib/jsonb_accessor/query_helper.rb +114 -0
- data/lib/jsonb_accessor/version.rb +1 -1
- metadata +38 -39
- data/gemfiles/activerecord_5.0.0.gemfile.lock +0 -141
- data/gemfiles/activerecord_5.1.0.gemfile.lock +0 -141
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80ed7aa0b3f529122a97b2a00b4f81011ef18014
|
4
|
+
data.tar.gz: 407d572cea056870ce66d7b92c89d1b3e15bdb2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be4ffe5fc2318edc84b98ffee5296d30d2a9d03817540c4622f04875d0a41c19022c19c0c998357f6730cad37103ce79c43b46c5aa08a46dce8078b77f03752d
|
7
|
+
data.tar.gz: c02e7189b7354d5d112aa9414e9cb4e5329d57b97b75b4d07a7e64da1abab04c63a0419509335fd557728eb48df1183d2a2d00c9c84ed7216ac4461205ec1c4d
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.1
|
data/.travis.yml
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
3
|
+
- 2.3.8
|
4
|
+
- 2.4.5
|
5
|
+
- 2.5.3
|
6
|
+
- 2.6.1
|
5
7
|
addons:
|
6
|
-
postgresql:
|
8
|
+
postgresql: "9.4"
|
7
9
|
before_install:
|
8
10
|
- gem update --system
|
9
11
|
- gem --version
|
10
|
-
- gem install bundler
|
12
|
+
- gem install bundler:2.1.4
|
11
13
|
before_script:
|
12
14
|
- bundle exec rake db:create
|
13
15
|
- bundle exec rake db:migrate
|
16
|
+
install: bundle _2.1.4_ install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
|
14
17
|
cache: bundler
|
15
18
|
gemfile:
|
16
19
|
- gemfiles/activerecord_5.0.0.gemfile
|
data/Appraisals
CHANGED
data/README.md
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
# JSONb Accessor
|
2
2
|
|
3
|
-
Created by [<img src="https://raw.githubusercontent.com/
|
3
|
+
Created by [<img src="https://raw.githubusercontent.com/madeintandem/jsonb_accessor/master/tandem-logo.png" alt="Tandem Logo" />](https://www.madeintandem.com/)
|
4
4
|
|
5
|
-
[](http://badge.fury.io/rb/jsonb_accessor) [](http://badge.fury.io/rb/jsonb_accessor) [](https://travis-ci.org/madeintandem/jsonb_accessor) <img src="https://raw.githubusercontent.com/madeintandem/jsonb_accessor/master/json-bee.png" alt="JSONb Accessor Logo" align="right" />
|
6
6
|
|
7
|
-
Adds typed `jsonb` backed fields as first class citizens to your `ActiveRecord` models. This gem is similar in spirit to [HstoreAccessor](https://github.com/
|
7
|
+
Adds typed `jsonb` backed fields as first class citizens to your `ActiveRecord` models. This gem is similar in spirit to [HstoreAccessor](https://github.com/madeintandem/hstore_accessor), but the `jsonb` column in PostgreSQL has a few distinct advantages, mostly around nested documents and support for collections.
|
8
8
|
|
9
9
|
It also adds generic scopes for querying `jsonb` columns.
|
10
10
|
|
11
|
-
## 1.0 Beta
|
12
|
-
|
13
|
-
This README reflects the most recent 1.0 beta. Method names and interfaces may still change.
|
14
|
-
|
15
11
|
## Table of Contents
|
16
12
|
|
17
13
|
* [Installation](#installation)
|
@@ -29,7 +25,7 @@ This README reflects the most recent 1.0 beta. Method names and interfaces may s
|
|
29
25
|
Add this line to your application's `Gemfile`:
|
30
26
|
|
31
27
|
```ruby
|
32
|
-
gem "jsonb_accessor", "1
|
28
|
+
gem "jsonb_accessor", "~> 1"
|
33
29
|
```
|
34
30
|
|
35
31
|
And then execute:
|
@@ -141,6 +137,14 @@ For time related fields you can query using `before` and `after`.
|
|
141
137
|
Product.all.data_where(reviewed_at: { before: Time.current.beginning_of_week, after: 4.weeks.ago })
|
142
138
|
```
|
143
139
|
|
140
|
+
If you want to search for records within a certain time, date, or number range, just pass in the range (Note: this is just shorthand for the above mentioned `before`/`after`/`less_than`/`less_than_or_equal_to`/`greater_than_or_equal_to`/etc options).
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
Product.all.data_where(price: 10..20)
|
144
|
+
Product.all.data_where(price: 10...20)
|
145
|
+
Product.all.data_where(reviewed_at: Time.current..3.days.from_now)
|
146
|
+
```
|
147
|
+
|
144
148
|
This scope is a convenient wrapper around the `jsonb_where` `scope` that saves you from having to convert the given keys to the store keys and from specifying the column.
|
145
149
|
|
146
150
|
### `jsonb_where`
|
@@ -164,6 +168,27 @@ Just the opposite of `jsonb_where`. Note that this will automatically exclude al
|
|
164
168
|
Product.all.jsonb_where_not(:data, reviewed_at: { before: Time.current }, p: { greater_than: 5 })
|
165
169
|
```
|
166
170
|
|
171
|
+
### `<jsonb_attribute>_order`
|
172
|
+
|
173
|
+
Orders your query according to values in the Jsonb Accessor fields similar to ActiveRecord's `order`.
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
Product.all.data_order(:price)
|
177
|
+
Product.all.data_order(:price, :reviewed_at)
|
178
|
+
Product.all.data_order(:price, reviewed_at: :desc)
|
179
|
+
```
|
180
|
+
|
181
|
+
It will convert your given keys into store keys if necessary.
|
182
|
+
|
183
|
+
### `jsonb_order`
|
184
|
+
|
185
|
+
Allows you to order by a Jsonb Accessor field.
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
Product.all.jsonb_order(:data, :price, :asc)
|
189
|
+
Product.all.jsonb_order(:data, :price, :desc)
|
190
|
+
```
|
191
|
+
|
167
192
|
### `jsonb_contains`
|
168
193
|
|
169
194
|
Returns all records that contain the given JSON paths.
|
@@ -284,7 +309,7 @@ From here any attributes specific to any sub-class can be stored in the
|
|
284
309
|
individual fields in an `jsonb` column.
|
285
310
|
|
286
311
|
This approach was originally conceived by Joe Hirn in [this blog
|
287
|
-
post](
|
312
|
+
post](https://madeintandem.com/blog/2013-3-single-table-inheritance-hstore-lovely-combination/).
|
288
313
|
|
289
314
|
## Validations
|
290
315
|
|
@@ -309,7 +334,7 @@ Run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
309
334
|
|
310
335
|
## Contributing
|
311
336
|
|
312
|
-
1. [Fork it](https://github.com/
|
337
|
+
1. [Fork it](https://github.com/madeintandem/jsonb_accessor/fork)
|
313
338
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
314
339
|
3. Add tests and changes (run the tests with `rake`)
|
315
340
|
4. Commit your changes (`git commit -am 'Add some feature'`)
|
data/jsonb_accessor.gemspec
CHANGED
@@ -23,18 +23,18 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
25
|
spec.add_dependency "activerecord", ">= 5.0"
|
26
|
+
spec.add_dependency "activesupport", ">= 5.0"
|
26
27
|
spec.add_dependency "pg", ">= 0.18.1"
|
27
28
|
|
28
|
-
spec.add_development_dependency "appraisal"
|
29
|
-
spec.add_development_dependency "bundler", "~> 1.
|
30
|
-
spec.add_development_dependency "database_cleaner", "~> 1.
|
29
|
+
spec.add_development_dependency "appraisal", "~> 2.2.0"
|
30
|
+
spec.add_development_dependency "bundler", "~> 2.1.4"
|
31
|
+
spec.add_development_dependency "database_cleaner", "~> 1.6.0"
|
31
32
|
spec.add_development_dependency "awesome_print"
|
32
33
|
spec.add_development_dependency "pry"
|
33
34
|
spec.add_development_dependency "pry-doc"
|
34
35
|
spec.add_development_dependency "pry-nav"
|
35
|
-
spec.add_development_dependency "rake", "
|
36
|
-
spec.add_development_dependency "rspec", "~> 3.
|
36
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.6.0"
|
37
38
|
spec.add_development_dependency "rubocop", "~> 0.48.1"
|
38
|
-
spec.add_development_dependency "
|
39
|
-
spec.add_development_dependency "standalone_migrations"
|
39
|
+
spec.add_development_dependency "standalone_migrations", "~> 5.2.0"
|
40
40
|
end
|
data/lib/jsonb_accessor.rb
CHANGED
data/lib/jsonb_accessor/macro.rb
CHANGED
@@ -11,7 +11,11 @@ module JsonbAccessor
|
|
11
11
|
|
12
12
|
# Defines virtual attributes for each jsonb field.
|
13
13
|
field_types.each do |name, type|
|
14
|
-
attribute name,
|
14
|
+
next attribute name, type unless type.is_a?(Array)
|
15
|
+
next attribute name, *type unless type.last.is_a?(Hash)
|
16
|
+
|
17
|
+
*args, keyword_args = type
|
18
|
+
attribute name, *args, **keyword_args
|
15
19
|
end
|
16
20
|
|
17
21
|
store_key_mapping_method_name = "jsonb_store_key_mapping_for_#{jsonb_attribute}"
|
@@ -34,7 +38,7 @@ module JsonbAccessor
|
|
34
38
|
end
|
35
39
|
|
36
40
|
# Get store keys to default values mapping
|
37
|
-
store_keys_and_defaults = ::JsonbAccessor::
|
41
|
+
store_keys_and_defaults = ::JsonbAccessor::QueryHelper.convert_keys_to_store_keys(names_and_defaults, public_send(store_key_mapping_method_name))
|
38
42
|
|
39
43
|
# Define jsonb_defaults_mapping_for_<jsonb_attribute>
|
40
44
|
defaults_mapping_method_name = "jsonb_defaults_mapping_for_#{jsonb_attribute}"
|
@@ -46,7 +50,14 @@ module JsonbAccessor
|
|
46
50
|
end
|
47
51
|
|
48
52
|
all_defaults_mapping = public_send(defaults_mapping_method_name)
|
49
|
-
|
53
|
+
# Fields may have procs as default value. This means `all_defaults_mapping` may contain procs as values. To make this work
|
54
|
+
# with the attributes API, we need to wrap `all_defaults_mapping` with a proc itself, making sure it returns a plain hash
|
55
|
+
# each time it is evaluated.
|
56
|
+
all_defaults_mapping_proc =
|
57
|
+
if all_defaults_mapping.present?
|
58
|
+
-> { all_defaults_mapping.map { |key, value| [key, value.respond_to?(:call) ? value.call : value] }.to_h }
|
59
|
+
end
|
60
|
+
attribute jsonb_attribute, :jsonb, default: all_defaults_mapping_proc if all_defaults_mapping_proc.present?
|
50
61
|
|
51
62
|
# Setters are in a module to allow users to override them and still be able to use `super`.
|
52
63
|
setters = Module.new do
|
@@ -67,7 +78,7 @@ module JsonbAccessor
|
|
67
78
|
empty_store_key_attributes = names_to_store_keys.values.each_with_object({}) { |name, defaults| defaults[name] = nil }
|
68
79
|
empty_named_attributes = names_to_store_keys.keys.each_with_object({}) { |name, defaults| defaults[name] = nil }
|
69
80
|
|
70
|
-
store_key_attributes = ::JsonbAccessor::
|
81
|
+
store_key_attributes = ::JsonbAccessor::QueryHelper.convert_keys_to_store_keys(value, names_to_store_keys)
|
71
82
|
write_attribute(jsonb_attribute, empty_store_key_attributes.merge(store_key_attributes))
|
72
83
|
|
73
84
|
empty_named_attributes.merge(value).each { |name, attribute_value| write_attribute(name, attribute_value) }
|
@@ -81,28 +92,37 @@ module JsonbAccessor
|
|
81
92
|
jsonb_values = public_send(jsonb_attribute) || {}
|
82
93
|
jsonb_values.each do |store_key, value|
|
83
94
|
name = names_and_store_keys.key(store_key)
|
84
|
-
|
95
|
+
next unless name
|
96
|
+
|
97
|
+
write_attribute(name, value)
|
98
|
+
clear_attribute_change(name) if persisted?
|
85
99
|
end
|
86
|
-
clear_changes_information if persisted?
|
87
100
|
end
|
88
101
|
end
|
89
102
|
|
90
103
|
# <jsonb_attribute>_where scope
|
91
104
|
scope("#{jsonb_attribute}_where", lambda do |attributes|
|
92
|
-
store_key_attributes = ::JsonbAccessor::
|
105
|
+
store_key_attributes = ::JsonbAccessor::QueryHelper.convert_keys_to_store_keys(attributes, all.model.public_send(store_key_mapping_method_name))
|
93
106
|
jsonb_where(jsonb_attribute, store_key_attributes)
|
94
107
|
end)
|
95
108
|
|
96
109
|
# <jsonb_attribute>_where_not scope
|
97
110
|
scope("#{jsonb_attribute}_where_not", lambda do |attributes|
|
98
|
-
store_key_attributes = ::JsonbAccessor::
|
111
|
+
store_key_attributes = ::JsonbAccessor::QueryHelper.convert_keys_to_store_keys(attributes, all.model.public_send(store_key_mapping_method_name))
|
99
112
|
jsonb_where_not(jsonb_attribute, store_key_attributes)
|
100
113
|
end)
|
101
114
|
|
102
115
|
# <jsonb_attribute>_order scope
|
103
|
-
scope("#{jsonb_attribute}_order", lambda do |
|
104
|
-
|
105
|
-
|
116
|
+
scope("#{jsonb_attribute}_order", lambda do |*args|
|
117
|
+
ordering_options = args.extract_options!
|
118
|
+
order_by_defaults = args.each_with_object({}) { |attribute, config| config[attribute] = :asc }
|
119
|
+
store_key_mapping = all.model.public_send(store_key_mapping_method_name)
|
120
|
+
|
121
|
+
order_by_defaults.merge(ordering_options).reduce(all) do |query, (name, direction)|
|
122
|
+
key = store_key_mapping[name.to_s]
|
123
|
+
order_query = jsonb_order(jsonb_attribute, key, direction)
|
124
|
+
query.merge(order_query)
|
125
|
+
end
|
106
126
|
end)
|
107
127
|
end
|
108
128
|
end
|
@@ -1,112 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JsonbAccessor
|
4
|
-
GREATER_THAN = ">"
|
5
|
-
GREATER_THAN_OR_EQUAL_TO = ">="
|
6
|
-
LESS_THAN = "<"
|
7
|
-
LESS_THAN_OR_EQUAL_TO = "<="
|
8
|
-
|
9
|
-
NUMBER_OPERATORS_MAP = {
|
10
|
-
GREATER_THAN => GREATER_THAN,
|
11
|
-
"greater_than" => GREATER_THAN,
|
12
|
-
"gt" => GREATER_THAN,
|
13
|
-
GREATER_THAN_OR_EQUAL_TO => GREATER_THAN_OR_EQUAL_TO,
|
14
|
-
"greater_than_or_equal_to" => GREATER_THAN_OR_EQUAL_TO,
|
15
|
-
"gte" => GREATER_THAN_OR_EQUAL_TO,
|
16
|
-
LESS_THAN => LESS_THAN,
|
17
|
-
"less_than" => LESS_THAN,
|
18
|
-
"lt" => LESS_THAN,
|
19
|
-
LESS_THAN_OR_EQUAL_TO => LESS_THAN_OR_EQUAL_TO,
|
20
|
-
"less_than_or_equal_to" => LESS_THAN_OR_EQUAL_TO,
|
21
|
-
"lte" => LESS_THAN_OR_EQUAL_TO
|
22
|
-
}.freeze
|
23
|
-
|
24
|
-
NUMBER_OPERATORS = NUMBER_OPERATORS_MAP.keys.freeze
|
25
|
-
|
26
|
-
TIME_OPERATORS_MAP = {
|
27
|
-
"after" => GREATER_THAN,
|
28
|
-
"before" => LESS_THAN
|
29
|
-
}.freeze
|
30
|
-
|
31
|
-
TIME_OPERATORS = TIME_OPERATORS_MAP.keys.freeze
|
32
|
-
|
33
|
-
IS_NUMBER_QUERY_ARGUMENTS = lambda do |arg|
|
34
|
-
arg.is_a?(Hash) &&
|
35
|
-
arg.keys.map(&:to_s).all? { |key| JsonbAccessor::NUMBER_OPERATORS.include?(key) }
|
36
|
-
end
|
37
|
-
|
38
|
-
IS_TIME_QUERY_ARGUMENTS = lambda do |arg|
|
39
|
-
arg.is_a?(Hash) &&
|
40
|
-
arg.keys.map(&:to_s).all? { |key| JsonbAccessor::TIME_OPERATORS.include?(key) }
|
41
|
-
end
|
42
|
-
|
43
|
-
ORDER_DIRECTIONS = [:asc, :desc, "asc", "desc"].freeze
|
44
|
-
|
45
4
|
module QueryBuilder
|
46
5
|
extend ActiveSupport::Concern
|
47
|
-
InvalidColumnName = Class.new(StandardError)
|
48
|
-
InvalidFieldName = Class.new(StandardError)
|
49
|
-
InvalidDirection = Class.new(StandardError)
|
50
|
-
|
51
|
-
def self.validate_column_name!(query, column_name)
|
52
|
-
if query.model.columns.none? { |column| column.name == column_name.to_s }
|
53
|
-
raise InvalidColumnName, "a column named `#{column_name}` does not exist on the `#{query.model.table_name}` table"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.validate_field_name!(query, column_name, field_name)
|
58
|
-
store_keys = query.model.public_send("jsonb_store_key_mapping_for_#{column_name}").values
|
59
|
-
if store_keys.exclude?(field_name.to_s)
|
60
|
-
valid_field_names = store_keys.map { |key| "`#{key}`" }.join(", ")
|
61
|
-
raise InvalidFieldName, "`#{field_name}` is not a valid field name, valid field names include: #{valid_field_names}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.validate_direction!(option)
|
66
|
-
if ORDER_DIRECTIONS.exclude?(option)
|
67
|
-
raise InvalidDirection, "`#{option}` is not a valid direction for ordering, only `asc` and `desc` are accepted"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.convert_keys_to_store_keys(attributes, store_key_mapping)
|
72
|
-
attributes.each_with_object({}) do |(name, value), new_attributes|
|
73
|
-
store_key = store_key_mapping[name.to_s]
|
74
|
-
new_attributes[store_key] = value
|
75
|
-
end
|
76
|
-
end
|
77
6
|
|
78
7
|
included do
|
79
8
|
scope(:jsonb_contains, lambda do |column_name, attributes|
|
80
|
-
JsonbAccessor::
|
9
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
81
10
|
where("#{table_name}.#{column_name} @> (?)::jsonb", attributes.to_json)
|
82
11
|
end)
|
83
12
|
|
84
13
|
scope(:jsonb_excludes, lambda do |column_name, attributes|
|
85
|
-
JsonbAccessor::
|
14
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
86
15
|
where.not("#{table_name}.#{column_name} @> (?)::jsonb", attributes.to_json)
|
87
16
|
end)
|
88
17
|
|
89
18
|
scope(:jsonb_number_where, lambda do |column_name, field_name, given_operator, value|
|
90
|
-
JsonbAccessor::
|
91
|
-
operator = JsonbAccessor::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
19
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
20
|
+
operator = JsonbAccessor::QueryHelper::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
92
21
|
where("(#{table_name}.#{column_name} ->> ?)::float #{operator} ?", field_name, value)
|
93
22
|
end)
|
94
23
|
|
95
24
|
scope(:jsonb_number_where_not, lambda do |column_name, field_name, given_operator, value|
|
96
|
-
JsonbAccessor::
|
97
|
-
operator = JsonbAccessor::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
25
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
26
|
+
operator = JsonbAccessor::QueryHelper::NUMBER_OPERATORS_MAP.fetch(given_operator.to_s)
|
98
27
|
where.not("(#{table_name}.#{column_name} ->> ?)::float #{operator} ?", field_name, value)
|
99
28
|
end)
|
100
29
|
|
101
30
|
scope(:jsonb_time_where, lambda do |column_name, field_name, given_operator, value|
|
102
|
-
JsonbAccessor::
|
103
|
-
operator = JsonbAccessor::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
31
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
32
|
+
operator = JsonbAccessor::QueryHelper::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
104
33
|
where("(#{table_name}.#{column_name} ->> ?)::timestamp #{operator} ?", field_name, value)
|
105
34
|
end)
|
106
35
|
|
107
36
|
scope(:jsonb_time_where_not, lambda do |column_name, field_name, given_operator, value|
|
108
|
-
JsonbAccessor::
|
109
|
-
operator = JsonbAccessor::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
37
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
38
|
+
operator = JsonbAccessor::QueryHelper::TIME_OPERATORS_MAP.fetch(given_operator.to_s)
|
110
39
|
where.not("(#{table_name}.#{column_name} ->> ?)::timestamp #{operator} ?", field_name, value)
|
111
40
|
end)
|
112
41
|
|
@@ -114,11 +43,10 @@ module JsonbAccessor
|
|
114
43
|
query = all
|
115
44
|
contains_attributes = {}
|
116
45
|
|
117
|
-
attributes.each do |name, value|
|
118
|
-
|
119
|
-
when IS_NUMBER_QUERY_ARGUMENTS
|
46
|
+
JsonbAccessor::QueryHelper.convert_ranges(attributes).each do |name, value|
|
47
|
+
if JsonbAccessor::QueryHelper.number_query_arguments?(value)
|
120
48
|
value.each { |operator, query_value| query = query.jsonb_number_where(column_name, name, operator, query_value) }
|
121
|
-
|
49
|
+
elsif JsonbAccessor::QueryHelper.time_query_arguments?(value)
|
122
50
|
value.each { |operator, query_value| query = query.jsonb_time_where(column_name, name, operator, query_value) }
|
123
51
|
else
|
124
52
|
contains_attributes[name] = value
|
@@ -133,10 +61,13 @@ module JsonbAccessor
|
|
133
61
|
excludes_attributes = {}
|
134
62
|
|
135
63
|
attributes.each do |name, value|
|
136
|
-
|
137
|
-
|
64
|
+
if value.is_a?(Range)
|
65
|
+
raise JsonbAccessor::QueryHelper::NotSupported, "`jsonb_where_not` scope does not accept ranges as arguments. Given `#{value}` for `#{name}` field"
|
66
|
+
end
|
67
|
+
|
68
|
+
if JsonbAccessor::QueryHelper.number_query_arguments?(value)
|
138
69
|
value.each { |operator, query_value| query = query.jsonb_number_where_not(column_name, name, operator, query_value) }
|
139
|
-
|
70
|
+
elsif JsonbAccessor::QueryHelper.time_query_arguments?(value)
|
140
71
|
value.each { |operator, query_value| query = query.jsonb_time_where_not(column_name, name, operator, query_value) }
|
141
72
|
else
|
142
73
|
excludes_attributes[name] = value
|
@@ -147,10 +78,10 @@ module JsonbAccessor
|
|
147
78
|
end)
|
148
79
|
|
149
80
|
scope(:jsonb_order, lambda do |column_name, field_name, direction|
|
150
|
-
JsonbAccessor::
|
151
|
-
JsonbAccessor::
|
152
|
-
JsonbAccessor::
|
153
|
-
order("(#{table_name}.#{column_name} -> '#{field_name}') #{direction}")
|
81
|
+
JsonbAccessor::QueryHelper.validate_column_name!(all, column_name)
|
82
|
+
JsonbAccessor::QueryHelper.validate_field_name!(all, column_name, field_name)
|
83
|
+
JsonbAccessor::QueryHelper.validate_direction!(direction)
|
84
|
+
order(Arel.sql("(#{table_name}.#{column_name} -> '#{field_name}') #{direction}"))
|
154
85
|
end)
|
155
86
|
end
|
156
87
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JsonbAccessor
|
4
|
+
module QueryHelper
|
5
|
+
# Errors
|
6
|
+
InvalidColumnName = Class.new(StandardError)
|
7
|
+
InvalidFieldName = Class.new(StandardError)
|
8
|
+
InvalidDirection = Class.new(StandardError)
|
9
|
+
NotSupported = Class.new(StandardError)
|
10
|
+
|
11
|
+
# Constants
|
12
|
+
GREATER_THAN = ">"
|
13
|
+
GREATER_THAN_OR_EQUAL_TO = ">="
|
14
|
+
LESS_THAN = "<"
|
15
|
+
LESS_THAN_OR_EQUAL_TO = "<="
|
16
|
+
|
17
|
+
NUMBER_OPERATORS_MAP = {
|
18
|
+
GREATER_THAN => GREATER_THAN,
|
19
|
+
"greater_than" => GREATER_THAN,
|
20
|
+
"gt" => GREATER_THAN,
|
21
|
+
GREATER_THAN_OR_EQUAL_TO => GREATER_THAN_OR_EQUAL_TO,
|
22
|
+
"greater_than_or_equal_to" => GREATER_THAN_OR_EQUAL_TO,
|
23
|
+
"gte" => GREATER_THAN_OR_EQUAL_TO,
|
24
|
+
LESS_THAN => LESS_THAN,
|
25
|
+
"less_than" => LESS_THAN,
|
26
|
+
"lt" => LESS_THAN,
|
27
|
+
LESS_THAN_OR_EQUAL_TO => LESS_THAN_OR_EQUAL_TO,
|
28
|
+
"less_than_or_equal_to" => LESS_THAN_OR_EQUAL_TO,
|
29
|
+
"lte" => LESS_THAN_OR_EQUAL_TO
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
NUMBER_OPERATORS = NUMBER_OPERATORS_MAP.keys.freeze
|
33
|
+
|
34
|
+
TIME_OPERATORS_MAP = {
|
35
|
+
"after" => GREATER_THAN,
|
36
|
+
"before" => LESS_THAN
|
37
|
+
}.freeze
|
38
|
+
|
39
|
+
TIME_OPERATORS = TIME_OPERATORS_MAP.keys.freeze
|
40
|
+
|
41
|
+
ORDER_DIRECTIONS = [:asc, :desc, "asc", "desc"].freeze
|
42
|
+
|
43
|
+
class << self
|
44
|
+
def validate_column_name!(query, column_name)
|
45
|
+
if query.model.columns.none? { |column| column.name == column_name.to_s }
|
46
|
+
raise InvalidColumnName, "a column named `#{column_name}` does not exist on the `#{query.model.table_name}` table"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_field_name!(query, column_name, field_name)
|
51
|
+
store_keys = query.model.public_send("jsonb_store_key_mapping_for_#{column_name}").values
|
52
|
+
if store_keys.exclude?(field_name.to_s)
|
53
|
+
valid_field_names = store_keys.map { |key| "`#{key}`" }.join(", ")
|
54
|
+
raise InvalidFieldName, "`#{field_name}` is not a valid field name, valid field names include: #{valid_field_names}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_direction!(option)
|
59
|
+
if ORDER_DIRECTIONS.exclude?(option)
|
60
|
+
raise InvalidDirection, "`#{option}` is not a valid direction for ordering, only `asc` and `desc` are accepted"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def convert_keys_to_store_keys(attributes, store_key_mapping)
|
65
|
+
attributes.each_with_object({}) do |(name, value), new_attributes|
|
66
|
+
store_key = store_key_mapping[name.to_s]
|
67
|
+
new_attributes[store_key] = value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def number_query_arguments?(arg)
|
72
|
+
arg.is_a?(Hash) && arg.keys.map(&:to_s).all? { |key| NUMBER_OPERATORS.include?(key) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def time_query_arguments?(arg)
|
76
|
+
arg.is_a?(Hash) && arg.keys.map(&:to_s).all? { |key| TIME_OPERATORS.include?(key) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def convert_number_ranges(attributes)
|
80
|
+
attributes.each_with_object({}) do |(name, value), new_attributes|
|
81
|
+
is_range = value.is_a?(Range)
|
82
|
+
|
83
|
+
new_attributes[name] = if is_range && value.first.is_a?(Numeric) && value.exclude_end?
|
84
|
+
{ greater_than_or_equal_to: value.first, less_than: value.end }
|
85
|
+
elsif is_range && value.first.is_a?(Numeric)
|
86
|
+
{ greater_than_or_equal_to: value.first, less_than_or_equal_to: value.end }
|
87
|
+
else
|
88
|
+
value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def convert_time_ranges(attributes)
|
94
|
+
attributes.each_with_object({}) do |(name, value), new_attributes|
|
95
|
+
is_range = value.is_a?(Range)
|
96
|
+
|
97
|
+
if is_range && (value.first.is_a?(Time) || value.first.is_a?(Date))
|
98
|
+
start_time = value.first
|
99
|
+
end_time = value.end
|
100
|
+
new_attributes[name] = { before: end_time, after: start_time }
|
101
|
+
else
|
102
|
+
new_attributes[name] = value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def convert_ranges(attributes)
|
108
|
+
%i[convert_number_ranges convert_time_ranges].reduce(attributes) do |new_attributes, converter_method|
|
109
|
+
public_send(converter_method, new_attributes)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
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.
|
4
|
+
version: 1.2.0
|
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: 2021-05-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -26,6 +26,20 @@ dependencies:
|
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '5.0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: activesupport
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '5.0'
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '5.0'
|
29
43
|
- !ruby/object:Gem::Dependency
|
30
44
|
name: pg
|
31
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,44 +58,44 @@ dependencies:
|
|
44
58
|
name: appraisal
|
45
59
|
requirement: !ruby/object:Gem::Requirement
|
46
60
|
requirements:
|
47
|
-
- - "
|
61
|
+
- - "~>"
|
48
62
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
63
|
+
version: 2.2.0
|
50
64
|
type: :development
|
51
65
|
prerelease: false
|
52
66
|
version_requirements: !ruby/object:Gem::Requirement
|
53
67
|
requirements:
|
54
|
-
- - "
|
68
|
+
- - "~>"
|
55
69
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
70
|
+
version: 2.2.0
|
57
71
|
- !ruby/object:Gem::Dependency
|
58
72
|
name: bundler
|
59
73
|
requirement: !ruby/object:Gem::Requirement
|
60
74
|
requirements:
|
61
75
|
- - "~>"
|
62
76
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
77
|
+
version: 2.1.4
|
64
78
|
type: :development
|
65
79
|
prerelease: false
|
66
80
|
version_requirements: !ruby/object:Gem::Requirement
|
67
81
|
requirements:
|
68
82
|
- - "~>"
|
69
83
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
84
|
+
version: 2.1.4
|
71
85
|
- !ruby/object:Gem::Dependency
|
72
86
|
name: database_cleaner
|
73
87
|
requirement: !ruby/object:Gem::Requirement
|
74
88
|
requirements:
|
75
89
|
- - "~>"
|
76
90
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.
|
91
|
+
version: 1.6.0
|
78
92
|
type: :development
|
79
93
|
prerelease: false
|
80
94
|
version_requirements: !ruby/object:Gem::Requirement
|
81
95
|
requirements:
|
82
96
|
- - "~>"
|
83
97
|
- !ruby/object:Gem::Version
|
84
|
-
version: 1.
|
98
|
+
version: 1.6.0
|
85
99
|
- !ruby/object:Gem::Dependency
|
86
100
|
name: awesome_print
|
87
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,30 +156,30 @@ dependencies:
|
|
142
156
|
name: rake
|
143
157
|
requirement: !ruby/object:Gem::Requirement
|
144
158
|
requirements:
|
145
|
-
- - "
|
159
|
+
- - ">="
|
146
160
|
- !ruby/object:Gem::Version
|
147
|
-
version:
|
161
|
+
version: 12.3.3
|
148
162
|
type: :development
|
149
163
|
prerelease: false
|
150
164
|
version_requirements: !ruby/object:Gem::Requirement
|
151
165
|
requirements:
|
152
|
-
- - "
|
166
|
+
- - ">="
|
153
167
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
168
|
+
version: 12.3.3
|
155
169
|
- !ruby/object:Gem::Dependency
|
156
170
|
name: rspec
|
157
171
|
requirement: !ruby/object:Gem::Requirement
|
158
172
|
requirements:
|
159
173
|
- - "~>"
|
160
174
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
175
|
+
version: 3.6.0
|
162
176
|
type: :development
|
163
177
|
prerelease: false
|
164
178
|
version_requirements: !ruby/object:Gem::Requirement
|
165
179
|
requirements:
|
166
180
|
- - "~>"
|
167
181
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
182
|
+
version: 3.6.0
|
169
183
|
- !ruby/object:Gem::Dependency
|
170
184
|
name: rubocop
|
171
185
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,34 +194,20 @@ dependencies:
|
|
180
194
|
- - "~>"
|
181
195
|
- !ruby/object:Gem::Version
|
182
196
|
version: 0.48.1
|
183
|
-
- !ruby/object:Gem::Dependency
|
184
|
-
name: shoulda-matchers
|
185
|
-
requirement: !ruby/object:Gem::Requirement
|
186
|
-
requirements:
|
187
|
-
- - ">="
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
version: '0'
|
190
|
-
type: :development
|
191
|
-
prerelease: false
|
192
|
-
version_requirements: !ruby/object:Gem::Requirement
|
193
|
-
requirements:
|
194
|
-
- - ">="
|
195
|
-
- !ruby/object:Gem::Version
|
196
|
-
version: '0'
|
197
197
|
- !ruby/object:Gem::Dependency
|
198
198
|
name: standalone_migrations
|
199
199
|
requirement: !ruby/object:Gem::Requirement
|
200
200
|
requirements:
|
201
|
-
- - "
|
201
|
+
- - "~>"
|
202
202
|
- !ruby/object:Gem::Version
|
203
|
-
version:
|
203
|
+
version: 5.2.0
|
204
204
|
type: :development
|
205
205
|
prerelease: false
|
206
206
|
version_requirements: !ruby/object:Gem::Requirement
|
207
207
|
requirements:
|
208
|
-
- - "
|
208
|
+
- - "~>"
|
209
209
|
- !ruby/object:Gem::Version
|
210
|
-
version:
|
210
|
+
version: 5.2.0
|
211
211
|
description: Adds typed jsonb backed fields to your ActiveRecord models.
|
212
212
|
email:
|
213
213
|
- michael@crismali.com
|
@@ -235,13 +235,12 @@ files:
|
|
235
235
|
- db/migrate/20150407031737_set_up_testing_db.rb
|
236
236
|
- db/schema.rb
|
237
237
|
- gemfiles/activerecord_5.0.0.gemfile
|
238
|
-
- gemfiles/activerecord_5.0.0.gemfile.lock
|
239
238
|
- gemfiles/activerecord_5.1.0.gemfile
|
240
|
-
- gemfiles/activerecord_5.1.0.gemfile.lock
|
241
239
|
- jsonb_accessor.gemspec
|
242
240
|
- lib/jsonb_accessor.rb
|
243
241
|
- lib/jsonb_accessor/macro.rb
|
244
242
|
- lib/jsonb_accessor/query_builder.rb
|
243
|
+
- lib/jsonb_accessor/query_helper.rb
|
245
244
|
- lib/jsonb_accessor/version.rb
|
246
245
|
homepage: https://github.com/devmynd/jsonb_accessor
|
247
246
|
licenses:
|
@@ -258,12 +257,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
258
257
|
version: '2.0'
|
259
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
260
259
|
requirements:
|
261
|
-
- - "
|
260
|
+
- - ">="
|
262
261
|
- !ruby/object:Gem::Version
|
263
|
-
version:
|
262
|
+
version: '0'
|
264
263
|
requirements: []
|
265
264
|
rubyforge_project:
|
266
|
-
rubygems_version: 2.
|
265
|
+
rubygems_version: 2.6.11
|
267
266
|
signing_key:
|
268
267
|
specification_version: 4
|
269
268
|
summary: Adds typed jsonb backed fields to your ActiveRecord models.
|
@@ -1,141 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: ..
|
3
|
-
specs:
|
4
|
-
jsonb_accessor (1.0.0.beta.5)
|
5
|
-
activerecord (>= 5.0)
|
6
|
-
pg (>= 0.18.1)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
actionpack (5.0.2)
|
12
|
-
actionview (= 5.0.2)
|
13
|
-
activesupport (= 5.0.2)
|
14
|
-
rack (~> 2.0)
|
15
|
-
rack-test (~> 0.6.3)
|
16
|
-
rails-dom-testing (~> 2.0)
|
17
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
18
|
-
actionview (5.0.2)
|
19
|
-
activesupport (= 5.0.2)
|
20
|
-
builder (~> 3.1)
|
21
|
-
erubis (~> 2.7.0)
|
22
|
-
rails-dom-testing (~> 2.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
|
-
arel (~> 7.0)
|
30
|
-
activesupport (5.0.2)
|
31
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
32
|
-
i18n (~> 0.7)
|
33
|
-
minitest (~> 5.1)
|
34
|
-
tzinfo (~> 1.1)
|
35
|
-
appraisal (2.1.0)
|
36
|
-
bundler
|
37
|
-
rake
|
38
|
-
thor (>= 0.14.0)
|
39
|
-
arel (7.1.4)
|
40
|
-
ast (2.3.0)
|
41
|
-
awesome_print (1.7.0)
|
42
|
-
builder (3.2.3)
|
43
|
-
coderay (1.1.1)
|
44
|
-
concurrent-ruby (1.0.5)
|
45
|
-
database_cleaner (1.5.3)
|
46
|
-
diff-lcs (1.3)
|
47
|
-
erubis (2.7.0)
|
48
|
-
i18n (0.8.1)
|
49
|
-
loofah (2.0.3)
|
50
|
-
nokogiri (>= 1.5.9)
|
51
|
-
method_source (0.8.2)
|
52
|
-
mini_portile2 (2.1.0)
|
53
|
-
minitest (5.10.1)
|
54
|
-
nokogiri (1.7.0.1)
|
55
|
-
mini_portile2 (~> 2.1.0)
|
56
|
-
parser (2.4.0.0)
|
57
|
-
ast (~> 2.2)
|
58
|
-
pg (0.20.0)
|
59
|
-
powerpack (0.1.1)
|
60
|
-
pry (0.10.4)
|
61
|
-
coderay (~> 1.1.0)
|
62
|
-
method_source (~> 0.8.1)
|
63
|
-
slop (~> 3.4)
|
64
|
-
pry-doc (0.10.0)
|
65
|
-
pry (~> 0.9)
|
66
|
-
yard (~> 0.9)
|
67
|
-
pry-nav (0.2.4)
|
68
|
-
pry (>= 0.9.10, < 0.11.0)
|
69
|
-
rack (2.0.1)
|
70
|
-
rack-test (0.6.3)
|
71
|
-
rack (>= 1.0)
|
72
|
-
rails-dom-testing (2.0.2)
|
73
|
-
activesupport (>= 4.2.0, < 6.0)
|
74
|
-
nokogiri (~> 1.6)
|
75
|
-
rails-html-sanitizer (1.0.3)
|
76
|
-
loofah (~> 2.0)
|
77
|
-
railties (5.0.2)
|
78
|
-
actionpack (= 5.0.2)
|
79
|
-
activesupport (= 5.0.2)
|
80
|
-
method_source
|
81
|
-
rake (>= 0.8.7)
|
82
|
-
thor (>= 0.18.1, < 2.0)
|
83
|
-
rainbow (2.2.2)
|
84
|
-
rake
|
85
|
-
rake (10.5.0)
|
86
|
-
rspec (3.5.0)
|
87
|
-
rspec-core (~> 3.5.0)
|
88
|
-
rspec-expectations (~> 3.5.0)
|
89
|
-
rspec-mocks (~> 3.5.0)
|
90
|
-
rspec-core (3.5.4)
|
91
|
-
rspec-support (~> 3.5.0)
|
92
|
-
rspec-expectations (3.5.0)
|
93
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
94
|
-
rspec-support (~> 3.5.0)
|
95
|
-
rspec-mocks (3.5.0)
|
96
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
97
|
-
rspec-support (~> 3.5.0)
|
98
|
-
rspec-support (3.5.0)
|
99
|
-
rubocop (0.48.1)
|
100
|
-
parser (>= 2.3.3.1, < 3.0)
|
101
|
-
powerpack (~> 0.1)
|
102
|
-
rainbow (>= 1.99.1, < 3.0)
|
103
|
-
ruby-progressbar (~> 1.7)
|
104
|
-
unicode-display_width (~> 1.0, >= 1.0.1)
|
105
|
-
ruby-progressbar (1.8.1)
|
106
|
-
shoulda-matchers (3.1.1)
|
107
|
-
activesupport (>= 4.0.0)
|
108
|
-
slop (3.6.0)
|
109
|
-
standalone_migrations (5.0.0)
|
110
|
-
activerecord (>= 4.2.7, < 5.1.0)
|
111
|
-
railties (>= 4.2.7, < 5.1.0)
|
112
|
-
rake (~> 10.0)
|
113
|
-
thor (0.19.4)
|
114
|
-
thread_safe (0.3.6)
|
115
|
-
tzinfo (1.2.2)
|
116
|
-
thread_safe (~> 0.1)
|
117
|
-
unicode-display_width (1.2.1)
|
118
|
-
yard (0.9.8)
|
119
|
-
|
120
|
-
PLATFORMS
|
121
|
-
ruby
|
122
|
-
|
123
|
-
DEPENDENCIES
|
124
|
-
activerecord (~> 5.0.0)
|
125
|
-
appraisal
|
126
|
-
awesome_print
|
127
|
-
bundler (~> 1.9)
|
128
|
-
database_cleaner (~> 1.5.3)
|
129
|
-
jsonb_accessor!
|
130
|
-
pg
|
131
|
-
pry
|
132
|
-
pry-doc
|
133
|
-
pry-nav
|
134
|
-
rake (~> 10.0)
|
135
|
-
rspec (~> 3.2)
|
136
|
-
rubocop (~> 0.48.1)
|
137
|
-
shoulda-matchers
|
138
|
-
standalone_migrations
|
139
|
-
|
140
|
-
BUNDLED WITH
|
141
|
-
1.14.6
|
@@ -1,141 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: ..
|
3
|
-
specs:
|
4
|
-
jsonb_accessor (1.0.0.beta.5)
|
5
|
-
activerecord (>= 5.0)
|
6
|
-
pg (>= 0.18.1)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
actionpack (5.1.0)
|
12
|
-
actionview (= 5.1.0)
|
13
|
-
activesupport (= 5.1.0)
|
14
|
-
rack (~> 2.0)
|
15
|
-
rack-test (~> 0.6.3)
|
16
|
-
rails-dom-testing (~> 2.0)
|
17
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
18
|
-
actionview (5.1.0)
|
19
|
-
activesupport (= 5.1.0)
|
20
|
-
builder (~> 3.1)
|
21
|
-
erubi (~> 1.4)
|
22
|
-
rails-dom-testing (~> 2.0)
|
23
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
24
|
-
activemodel (5.1.0)
|
25
|
-
activesupport (= 5.1.0)
|
26
|
-
activerecord (5.1.0)
|
27
|
-
activemodel (= 5.1.0)
|
28
|
-
activesupport (= 5.1.0)
|
29
|
-
arel (~> 8.0)
|
30
|
-
activesupport (5.1.0)
|
31
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
32
|
-
i18n (~> 0.7)
|
33
|
-
minitest (~> 5.1)
|
34
|
-
tzinfo (~> 1.1)
|
35
|
-
appraisal (2.2.0)
|
36
|
-
bundler
|
37
|
-
rake
|
38
|
-
thor (>= 0.14.0)
|
39
|
-
arel (8.0.0)
|
40
|
-
ast (2.3.0)
|
41
|
-
awesome_print (1.7.0)
|
42
|
-
builder (3.2.3)
|
43
|
-
coderay (1.1.1)
|
44
|
-
concurrent-ruby (1.0.5)
|
45
|
-
database_cleaner (1.5.3)
|
46
|
-
diff-lcs (1.3)
|
47
|
-
erubi (1.6.0)
|
48
|
-
i18n (0.8.1)
|
49
|
-
loofah (2.0.3)
|
50
|
-
nokogiri (>= 1.5.9)
|
51
|
-
method_source (0.8.2)
|
52
|
-
mini_portile2 (2.1.0)
|
53
|
-
minitest (5.10.1)
|
54
|
-
nokogiri (1.7.1)
|
55
|
-
mini_portile2 (~> 2.1.0)
|
56
|
-
parser (2.4.0.0)
|
57
|
-
ast (~> 2.2)
|
58
|
-
pg (0.20.0)
|
59
|
-
powerpack (0.1.1)
|
60
|
-
pry (0.10.4)
|
61
|
-
coderay (~> 1.1.0)
|
62
|
-
method_source (~> 0.8.1)
|
63
|
-
slop (~> 3.4)
|
64
|
-
pry-doc (0.10.0)
|
65
|
-
pry (~> 0.9)
|
66
|
-
yard (~> 0.9)
|
67
|
-
pry-nav (0.2.4)
|
68
|
-
pry (>= 0.9.10, < 0.11.0)
|
69
|
-
rack (2.0.1)
|
70
|
-
rack-test (0.6.3)
|
71
|
-
rack (>= 1.0)
|
72
|
-
rails-dom-testing (2.0.2)
|
73
|
-
activesupport (>= 4.2.0, < 6.0)
|
74
|
-
nokogiri (~> 1.6)
|
75
|
-
rails-html-sanitizer (1.0.3)
|
76
|
-
loofah (~> 2.0)
|
77
|
-
railties (5.1.0)
|
78
|
-
actionpack (= 5.1.0)
|
79
|
-
activesupport (= 5.1.0)
|
80
|
-
method_source
|
81
|
-
rake (>= 0.8.7)
|
82
|
-
thor (>= 0.18.1, < 2.0)
|
83
|
-
rainbow (2.2.2)
|
84
|
-
rake
|
85
|
-
rake (10.5.0)
|
86
|
-
rspec (3.5.0)
|
87
|
-
rspec-core (~> 3.5.0)
|
88
|
-
rspec-expectations (~> 3.5.0)
|
89
|
-
rspec-mocks (~> 3.5.0)
|
90
|
-
rspec-core (3.5.4)
|
91
|
-
rspec-support (~> 3.5.0)
|
92
|
-
rspec-expectations (3.5.0)
|
93
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
94
|
-
rspec-support (~> 3.5.0)
|
95
|
-
rspec-mocks (3.5.0)
|
96
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
97
|
-
rspec-support (~> 3.5.0)
|
98
|
-
rspec-support (3.5.0)
|
99
|
-
rubocop (0.48.1)
|
100
|
-
parser (>= 2.3.3.1, < 3.0)
|
101
|
-
powerpack (~> 0.1)
|
102
|
-
rainbow (>= 1.99.1, < 3.0)
|
103
|
-
ruby-progressbar (~> 1.7)
|
104
|
-
unicode-display_width (~> 1.0, >= 1.0.1)
|
105
|
-
ruby-progressbar (1.8.1)
|
106
|
-
shoulda-matchers (3.1.1)
|
107
|
-
activesupport (>= 4.0.0)
|
108
|
-
slop (3.6.0)
|
109
|
-
standalone_migrations (5.2.1)
|
110
|
-
activerecord (>= 4.2.7, < 5.2.0)
|
111
|
-
railties (>= 4.2.7, < 5.2.0)
|
112
|
-
rake (~> 10.0)
|
113
|
-
thor (0.19.4)
|
114
|
-
thread_safe (0.3.6)
|
115
|
-
tzinfo (1.2.3)
|
116
|
-
thread_safe (~> 0.1)
|
117
|
-
unicode-display_width (1.2.1)
|
118
|
-
yard (0.9.9)
|
119
|
-
|
120
|
-
PLATFORMS
|
121
|
-
ruby
|
122
|
-
|
123
|
-
DEPENDENCIES
|
124
|
-
activerecord (~> 5.1.0)
|
125
|
-
appraisal
|
126
|
-
awesome_print
|
127
|
-
bundler (~> 1.9)
|
128
|
-
database_cleaner (~> 1.5.3)
|
129
|
-
jsonb_accessor!
|
130
|
-
pg
|
131
|
-
pry
|
132
|
-
pry-doc
|
133
|
-
pry-nav
|
134
|
-
rake (~> 10.0)
|
135
|
-
rspec (~> 3.2)
|
136
|
-
rubocop (~> 0.48.1)
|
137
|
-
shoulda-matchers
|
138
|
-
standalone_migrations
|
139
|
-
|
140
|
-
BUNDLED WITH
|
141
|
-
1.14.6
|