attr_json 0.5.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +54 -11
- data/Appraisals +8 -1
- data/CHANGELOG.md +32 -0
- data/Gemfile +3 -3
- data/README.md +102 -8
- data/attr_json.gemspec +2 -2
- data/gemfiles/rails_5_0.gemfile +2 -2
- data/gemfiles/rails_5_1.gemfile +2 -2
- data/gemfiles/rails_5_2.gemfile +2 -2
- data/gemfiles/rails_6_0.gemfile +18 -0
- data/gemfiles/rails_edge.gemfile +19 -0
- data/gemfiles/rails_edge_6.gemfile +3 -3
- data/lib/attr_json.rb +0 -1
- data/lib/attr_json/attribute_definition.rb +6 -0
- data/lib/attr_json/attribute_definition/registry.rb +5 -0
- data/lib/attr_json/config.rb +12 -2
- data/lib/attr_json/model.rb +39 -6
- data/lib/attr_json/record.rb +64 -20
- data/lib/attr_json/record/query_builder.rb +15 -3
- data/lib/attr_json/record/query_scopes.rb +6 -0
- data/lib/attr_json/serialization_coder_from_type.rb +40 -0
- data/lib/attr_json/type/model.rb +8 -5
- data/lib/attr_json/type/polymorphic_model.rb +2 -0
- data/lib/attr_json/version.rb +1 -1
- metadata +16 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6bbeb0707de928eae27b0bceafa5691486a2784d3065c71f91757e825bbaa94
|
4
|
+
data.tar.gz: 64b4d70c31b1b9499ee74f764940b283d45231ec6f4809cec35459e7d6ed9288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91aab7ce45bf723d4c76d9b2756ad65650bef1b223b2214bc9091118a8e4a04cb347fbac2438e7aaab4ed302f92c26f88b23f602e626b494f1aa5251f81473d7
|
7
|
+
data.tar.gz: 7862793a46004520e65cbb8b98a4857ec5441d6f0456dd8e368c4af7be8fafaefd8f0ef780f38f7361ea45b1117dbee4fe384492e44f5044aa295ee56488a99b
|
data/.travis.yml
CHANGED
@@ -1,21 +1,64 @@
|
|
1
1
|
#
|
2
|
-
dist: trusty
|
3
2
|
sudo: false
|
4
3
|
addons:
|
5
4
|
postgresql: '9.4'
|
6
5
|
chrome: stable
|
7
6
|
language: ruby
|
8
7
|
cache: bundler
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
|
9
|
+
# rvm:
|
10
|
+
# - 2.4.5
|
11
|
+
# - 2.5.3
|
12
|
+
# - 2.6.5
|
13
|
+
# - 2.7.0
|
14
|
+
# gemfile:
|
15
|
+
# - gemfiles/rails_5_0.gemfile
|
16
|
+
# - gemfiles/rails_5_1.gemfile
|
17
|
+
# - gemfiles/rails_5_2.gemfile
|
18
|
+
# - gemfiles/rails_6_0.gemfile
|
19
|
+
# - gemfiles/rails_edge.gemfile
|
20
|
+
|
17
21
|
before_install:
|
18
|
-
- gem install bundler -v
|
22
|
+
- gem install bundler -v "~> 2.0"
|
23
|
+
|
19
24
|
matrix:
|
25
|
+
include:
|
26
|
+
- rvm: 2.4.5
|
27
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
28
|
+
|
29
|
+
- rvm: 2.4.5
|
30
|
+
gemfile: gemfiles/rails_5_1.gemfile
|
31
|
+
|
32
|
+
- rvm: 2.4.5
|
33
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
34
|
+
|
35
|
+
- rvm: 2.5.3
|
36
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
37
|
+
|
38
|
+
- rvm: 2.5.3
|
39
|
+
gemfile: gemfiles/rails_5_1.gemfile
|
40
|
+
|
41
|
+
- rvm: 2.5.3
|
42
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
43
|
+
|
44
|
+
- rvm: 2.5.3
|
45
|
+
gemfile: gemfiles/rails_6_0.gemfile
|
46
|
+
|
47
|
+
- rvm: 2.6.5
|
48
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
49
|
+
|
50
|
+
- rvm: 2.6.5
|
51
|
+
gemfile: gemfiles/rails_6_0.gemfile
|
52
|
+
|
53
|
+
- rvm: 2.7.0
|
54
|
+
gemfile: gemfiles/rails_6_0.gemfile
|
55
|
+
|
56
|
+
- rvm: 2.7.0
|
57
|
+
gemfile: gemfiles/rails_edge.gemfile
|
58
|
+
|
20
59
|
allow_failures:
|
21
|
-
- gemfile: gemfiles/
|
60
|
+
- gemfile: gemfiles/rails_edge.gemfile
|
61
|
+
fast_finish: true
|
62
|
+
|
63
|
+
|
64
|
+
|
data/Appraisals
CHANGED
@@ -25,10 +25,17 @@ appraise "rails-5-2" do
|
|
25
25
|
gem "pg", "~> 1.0"
|
26
26
|
end
|
27
27
|
|
28
|
+
appraise "rails-6-0" do
|
29
|
+
gem 'combustion', "~> 1.0"
|
30
|
+
|
31
|
+
gem "rails", ">= 6.0.0.beta1", "< 6.1"
|
32
|
+
gem "pg", "~> 1.0"
|
33
|
+
end
|
34
|
+
|
28
35
|
appraise "rails-edge-6" do
|
29
36
|
# Edge rails needs unreleased combustion
|
30
37
|
# https://github.com/pat/combustion/issues/92
|
31
|
-
gem 'combustion',
|
38
|
+
gem 'combustion', "~> 1.0"
|
32
39
|
|
33
40
|
gem "rails", git: "https://github.com/rails/rails.git", branch: "master"
|
34
41
|
gem "pg", "~> 1.0"
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Changelog
|
2
|
+
Notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased](https://github.com/jrochkind/attr_json/compare/v1.2.0...HEAD)
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
## [1.2.0](https://github.com/jrochkind/attr_json/compare/v1.1.0...v1.2.0)
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
* attr_json_config(bad_cast: :as_nil) to avoid raising on data that can't be cast to a
|
16
|
+
AttrJson::Model, instead just casting to nil. https://github.com/jrochkind/attr_json/pull/95
|
17
|
+
|
18
|
+
* Documented and tested support for using ActiveRecord serialize to map one AttrJson::Model
|
19
|
+
to an entire column on it's own. https://github.com/jrochkind/attr_json/pull/89 and
|
20
|
+
https://github.com/jrochkind/attr_json/pull/93
|
21
|
+
|
22
|
+
* Better synchronization with ActiveRecord attributes when using rails_attribute:true, and a configurable true default_rails_attribute. Thanks @volkanunsal . https://github.com/jrochkind/attr_json/pull/94
|
23
|
+
|
24
|
+
### Changed
|
25
|
+
|
26
|
+
* AttrJson::Model#== now requires same class for equality. And doesn't raise on certain arguments. https://github.com/jrochkind/attr_json/pull/90 Thanks @caiofilipemr for related bug report.
|
27
|
+
|
28
|
+
## [1.1.0](https://github.com/jrochkind/attr_json/compare/v1.0.0...v1.1.0)
|
29
|
+
|
30
|
+
### Added
|
31
|
+
|
32
|
+
* not_jsonb_contains query method, like `jsonb_contains` but negated. https://github.com/jrochkind/attr_json/pull/85
|
data/Gemfile
CHANGED
@@ -10,7 +10,7 @@ gemspec
|
|
10
10
|
# We also have these development dependencies here in the Gemfile instead of the
|
11
11
|
# gemspec so appraisal can override them from our Appraisal file.
|
12
12
|
|
13
|
-
gem 'combustion', '~>
|
13
|
+
gem 'combustion', '~> 1.1'
|
14
14
|
|
15
15
|
# all of rails is NOT a dependency, just activerecord.
|
16
16
|
# But we use it for integration testing with combustion. Hmm, a bit annoying
|
@@ -24,13 +24,13 @@ gem 'rails'
|
|
24
24
|
gem 'railties'
|
25
25
|
|
26
26
|
gem "pg"
|
27
|
-
gem "rspec-rails", "~>
|
27
|
+
gem "rspec-rails", "~> 4.0"
|
28
28
|
gem "simple_form", ">= 4.0"
|
29
29
|
gem 'cocoon', ">= 1.2"
|
30
30
|
gem 'jquery-rails'
|
31
31
|
|
32
32
|
gem 'capybara', "~> 3.0"
|
33
|
-
gem
|
33
|
+
gem 'webdrivers', '~> 4.0'
|
34
34
|
gem "selenium-webdriver"
|
35
35
|
|
36
36
|
gem "byebug"
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/attr_json.svg)](https://badge.fury.io/rb/attr_json)
|
4
4
|
|
5
5
|
|
6
|
-
ActiveRecord attributes stored serialized in a json column, super smooth. For Rails 5.0, 5.1,
|
6
|
+
ActiveRecord attributes stored serialized in a json column, super smooth. For Rails 5.0, 5.1, 5.2, or 6.0. Ruby 2.4+.
|
7
7
|
|
8
8
|
Typed and cast like Active Record. Supporting [nested models](#nested), [dirty tracking](#dirty), some [querying](#querying) (with postgres [jsonb](https://www.postgresql.org/docs/9.5/static/datatype-json.html) contains), and [working smoothy with form builders](#forms).
|
9
9
|
|
@@ -11,8 +11,6 @@ Typed and cast like Active Record. Supporting [nested models](#nested), [dirty t
|
|
11
11
|
|
12
12
|
[Why might you want or not want this?](#why)
|
13
13
|
|
14
|
-
AttrJson is pre-1.0. The functionality that is documented here _is_ already implemented (these docs are real, not vaporware) and seems pretty solid. It may still have backwards-incompat changes before 1.0 release. Review and feedback is very welcome.
|
15
|
-
|
16
14
|
Developed for postgres, but most features should work with MySQL json columns too, although
|
17
15
|
has not yet been tested with MySQL.
|
18
16
|
|
@@ -140,6 +138,9 @@ MyModel.jsonb_contains(my_string: "foo", my_integer: 100).first
|
|
140
138
|
# Implemented with scopes, this is an ordinary relation, you can
|
141
139
|
# combine it with whatever, just like ordinary `where`.
|
142
140
|
|
141
|
+
MyModel.not_jsonb_contains(my:string: "foo", my_integer: 100).to_sql
|
142
|
+
# SELECT "products".* FROM "products" WHERE NOT (products.json_attributes @> ('{"my_string":"foo","my_integer":100}')::jsonb)
|
143
|
+
|
143
144
|
# typecasts much like ActiveRecord on query too:
|
144
145
|
MyModel.jsonb_contains(my_string: "foo", my_integer: "100")
|
145
146
|
# no problem
|
@@ -227,6 +228,26 @@ m.attr_jsons_before_type_cast
|
|
227
228
|
|
228
229
|
You can nest AttrJson::Model objects inside each other, as deeply as you like.
|
229
230
|
|
231
|
+
### Model-type defaults
|
232
|
+
|
233
|
+
If you want to set a default for an AttrJson::Model type, you should use a proc argument for
|
234
|
+
the default, to avoid accidentally re-using a shared global default value, similar to issues
|
235
|
+
people have with ruby Hash default.
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
attr_json :lang_and_value, LangAndValue.to_type, default: -> { LangAndValue.new(lang: "en", value: "default") }
|
239
|
+
```
|
240
|
+
|
241
|
+
You can also use a Hash value that will be cast to your model, no need for proc argument
|
242
|
+
in this case.
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
attr_json :lang_and_value, LangAndValue.to_type, default: { lang: "en", value: "default" }
|
246
|
+
```
|
247
|
+
|
248
|
+
|
249
|
+
### Polymorphic model types
|
250
|
+
|
230
251
|
There is some support for "polymorphic" attributes that can hetereogenously contain instances of different AttrJson::Model classes, see comment docs at [AttrJson::Type::PolymorphicModel](./lib/attr_json/type/polymorphic_model.rb).
|
231
252
|
|
232
253
|
|
@@ -285,6 +306,77 @@ always mean 'contains' -- the previous query needs a `my_labels.hello`
|
|
285
306
|
which is a hash that includes the key/value, `lang: en`, it can have
|
286
307
|
other key/values in it too. String values will need to match exactly.
|
287
308
|
|
309
|
+
## Single AttrJson::Model serialized to an entire json column
|
310
|
+
|
311
|
+
The main use case of the gem is set up to let you combine multiple primitives and nested models
|
312
|
+
under different keys combined in a single json or jsonb column.
|
313
|
+
|
314
|
+
But you may also want to have one AttrJson::Model class that serializes to map one model class, as
|
315
|
+
a hash, to an entire json column on it's own.
|
316
|
+
|
317
|
+
`AttrJson::Model` can supply a simple coder for the [ActiveRecord serialization](https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html)
|
318
|
+
feature to easily do that.
|
319
|
+
|
320
|
+
```ruby
|
321
|
+
class MyModel
|
322
|
+
include AttrJson::Model
|
323
|
+
|
324
|
+
attr_json :some_string, :string
|
325
|
+
attr_json :some_int, :int
|
326
|
+
end
|
327
|
+
|
328
|
+
class MyTable < ApplicationRecord
|
329
|
+
serialize :some_json_column, MyModel.to_serialization_coder
|
330
|
+
end
|
331
|
+
|
332
|
+
MyTable.create(some_json_column: MyModel.new(some_string: "string"))
|
333
|
+
|
334
|
+
# will cast from hash for you
|
335
|
+
MyTable.create(some_json_column: { some_int: 12 })
|
336
|
+
|
337
|
+
# etc
|
338
|
+
```
|
339
|
+
|
340
|
+
To avoid errors raised at inconvenient times, we recommend you set these settings to make 'bad'
|
341
|
+
data turn into `nil`, consistent with most ActiveRecord types:
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
class MyModel
|
345
|
+
include AttrJson::Model
|
346
|
+
|
347
|
+
attr_json_config(bad_cast: :as_nil, unknown_key: :strip)
|
348
|
+
# ...
|
349
|
+
end
|
350
|
+
```
|
351
|
+
|
352
|
+
And/or define a setter method to cast, and raise early on data problems:
|
353
|
+
|
354
|
+
```ruby
|
355
|
+
class MyTable < ApplicationRecord
|
356
|
+
serialize :some_json_column, MyModel.to_serialization_coder
|
357
|
+
|
358
|
+
def some_json_column=(val)
|
359
|
+
super( )
|
360
|
+
end
|
361
|
+
end
|
362
|
+
```
|
363
|
+
|
364
|
+
Serializing a model to an entire json column is a relatively recent feature, please let us know how it's working for you.
|
365
|
+
|
366
|
+
<a name="arbitrary-json-data"></a>
|
367
|
+
## Storing Arbitrary JSON data
|
368
|
+
|
369
|
+
Arbitrary JSON data (hashes, arrays, primitives of any depth) can be stored within attributes by using the rails built in `ActiveModel::Type::Value` as the attribute type. This is basically a "no-op" value type -- JSON alone will be used to serialize/deserialize whatever values you put there, because of the json type on the container field.
|
370
|
+
|
371
|
+
```ruby
|
372
|
+
class MyModel < ActiveRecord::Base
|
373
|
+
include AttrJson::Record
|
374
|
+
|
375
|
+
attr_json :arbitrary_hash, ActiveModel::Type::Value.new
|
376
|
+
end
|
377
|
+
|
378
|
+
```
|
379
|
+
|
288
380
|
|
289
381
|
<a name="forms"></a>
|
290
382
|
## Forms and Form Builders
|
@@ -293,7 +385,7 @@ Use with Rails form builders is supported pretty painlessly. Including with [sim
|
|
293
385
|
|
294
386
|
If you have nested AttrJson::Models you'd like to use in your forms much like Rails associated records: Where you would use Rails `accepts_nested_attributes_for`, instead `include AttrJson::NestedAttributes` and use `attr_json_accepts_nested_attributes_for`. Multiple levels of nesting are supported.
|
295
387
|
|
296
|
-
To get simple_form to properly detect your attribute types, define your attributes with `rails_attribute: true`.
|
388
|
+
To get simple_form to properly detect your attribute types, define your attributes with `rails_attribute: true`. You can default rails_attribute to true with `attr_json_config(default_rails_attribute: true)`
|
297
389
|
|
298
390
|
For more info, see doc page on [Use with Forms and Form Builders](doc_src/forms.md).
|
299
391
|
|
@@ -383,16 +475,16 @@ to prevent overwriting other updates from processes.
|
|
383
475
|
|
384
476
|
## State of Code, and To Be Done
|
385
477
|
|
386
|
-
|
478
|
+
The functionality that is here seems pretty solid, and is being used by jrochkind in a production app.
|
387
479
|
|
388
|
-
|
389
|
-
|
390
|
-
I do not yet use this myself in production, and may not for a while. I generally am reluctant to release something as 1.0 with implied suitable for production when I'm not yet using it in production myself, but may with enough feedback. A couple others are already using in production.
|
480
|
+
We are committed to [semantic versioning](https://semver.org/) and will endeavor to release no backwards breaking changes without a major version. We are also serious about minimizing backwards incompat releases altogether (ie minimiing major version releases).
|
391
481
|
|
392
482
|
Feedback of any kind of _very welcome_, please feel free to use the issue tracker.
|
393
483
|
|
394
484
|
Except for the jsonb_contains stuff using postgres jsonb contains operator, I don't believe any postgres-specific features are used. It ought to work with MySQL, testing and feedback welcome. (Or a PR to test on MySQL?). My own interest is postgres.
|
395
485
|
|
486
|
+
This is still mostly a single-maintainer operation, so has all the sustainability risks of that. Although there are other people using and contributing to it, check out the Github Issues and Pull Request tabs yourself to get a sense.
|
487
|
+
|
396
488
|
### Possible future features:
|
397
489
|
|
398
490
|
* partial updates for json hashes would be really nice: Using postgres jsonb merge operators to only overwrite what changed. In my initial attempts, AR doesn't make it easy to customize this.
|
@@ -450,3 +542,5 @@ There is a `./bin/console` that will give you a console in the context of attr_j
|
|
450
542
|
* Didn't actually notice existing [json_attributes](https://github.com/joel/json_attributes)
|
451
543
|
until I was well on my way here. I think it's not updated for Rails5 or type-aware,
|
452
544
|
haven't looked at it too much.
|
545
|
+
|
546
|
+
* [store_model](https://github.com/DmitryTsepelev/store_model) was created after `attr_json`, and has some overlapping functionality.
|
data/attr_json.gemspec
CHANGED
@@ -45,10 +45,10 @@ attributes use as much of the existing ActiveRecord architecture as we can.}
|
|
45
45
|
# Only to get CI to work on versions of Rails other than we release with,
|
46
46
|
# should never release a gem with RAILS_GEM set!
|
47
47
|
unless ENV['APPRAISAL_INITIALIZED'] || ENV["TRAVIS"]
|
48
|
-
spec.add_runtime_dependency "activerecord", ">= 5.0.0", "<
|
48
|
+
spec.add_runtime_dependency "activerecord", ">= 5.0.0", "< 6.1"
|
49
49
|
end
|
50
50
|
|
51
|
-
spec.add_development_dependency "bundler"
|
51
|
+
spec.add_development_dependency "bundler"
|
52
52
|
spec.add_development_dependency "rake", ">= 10.0"
|
53
53
|
spec.add_development_dependency "rspec", "~> 3.7"
|
54
54
|
spec.add_development_dependency "database_cleaner", "~> 1.5"
|
data/gemfiles/rails_5_0.gemfile
CHANGED
@@ -6,12 +6,12 @@ gem "combustion", "~> 0.9.0"
|
|
6
6
|
gem "rails", "~> 5.0.0"
|
7
7
|
gem "railties"
|
8
8
|
gem "pg", "~> 0.18"
|
9
|
-
gem "rspec-rails", "~>
|
9
|
+
gem "rspec-rails", "~> 4.0"
|
10
10
|
gem "simple_form", ">= 4.0"
|
11
11
|
gem "cocoon", ">= 1.2"
|
12
12
|
gem "jquery-rails"
|
13
13
|
gem "capybara", "~> 3.0"
|
14
|
-
gem "
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
15
|
gem "selenium-webdriver"
|
16
16
|
gem "byebug"
|
17
17
|
gem "rails-ujs", require: false
|
data/gemfiles/rails_5_1.gemfile
CHANGED
@@ -6,12 +6,12 @@ gem "combustion", "~> 0.9.0"
|
|
6
6
|
gem "rails", "~> 5.1.0"
|
7
7
|
gem "railties"
|
8
8
|
gem "pg", "~> 1.0"
|
9
|
-
gem "rspec-rails", "~>
|
9
|
+
gem "rspec-rails", "~> 4.0"
|
10
10
|
gem "simple_form", ">= 4.0"
|
11
11
|
gem "cocoon", ">= 1.2"
|
12
12
|
gem "jquery-rails"
|
13
13
|
gem "capybara", "~> 3.0"
|
14
|
-
gem "
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
15
|
gem "selenium-webdriver"
|
16
16
|
gem "byebug"
|
17
17
|
|
data/gemfiles/rails_5_2.gemfile
CHANGED
@@ -6,12 +6,12 @@ gem "combustion", "~> 0.9.0"
|
|
6
6
|
gem "rails", "~> 5.2.0"
|
7
7
|
gem "railties"
|
8
8
|
gem "pg", "~> 1.0"
|
9
|
-
gem "rspec-rails", "~>
|
9
|
+
gem "rspec-rails", "~> 4.0"
|
10
10
|
gem "simple_form", ">= 4.0"
|
11
11
|
gem "cocoon", ">= 1.2"
|
12
12
|
gem "jquery-rails"
|
13
13
|
gem "capybara", "~> 3.0"
|
14
|
-
gem "
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
15
|
gem "selenium-webdriver"
|
16
16
|
gem "byebug"
|
17
17
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "combustion", "~> 1.0"
|
6
|
+
gem "rails", ">= 6.0.0.beta1", "< 6.1"
|
7
|
+
gem "railties"
|
8
|
+
gem "pg", "~> 1.0"
|
9
|
+
gem "rspec-rails", "~> 4.0"
|
10
|
+
gem "simple_form", ">= 4.0"
|
11
|
+
gem "cocoon", ">= 1.2"
|
12
|
+
gem "jquery-rails"
|
13
|
+
gem "capybara", "~> 3.0"
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
|
+
gem "selenium-webdriver"
|
16
|
+
gem "byebug"
|
17
|
+
|
18
|
+
gemspec path: "../"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "combustion", "~> 1.0"
|
6
|
+
gem "rails", git: "https://github.com/rails/rails.git", branch: "master"
|
7
|
+
gem "railties"
|
8
|
+
gem "pg", "~> 1.0"
|
9
|
+
gem "rspec-rails", "~> 3.7"
|
10
|
+
gem "simple_form", ">= 4.0"
|
11
|
+
gem "cocoon", ">= 1.2"
|
12
|
+
gem "jquery-rails"
|
13
|
+
gem "capybara", "~> 3.0"
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
|
+
gem "selenium-webdriver"
|
16
|
+
gem "byebug"
|
17
|
+
gem "coffee-rails"
|
18
|
+
|
19
|
+
gemspec path: "../"
|
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "combustion",
|
5
|
+
gem "combustion", "~> 1.0"
|
6
6
|
gem "rails", git: "https://github.com/rails/rails.git", branch: "master"
|
7
7
|
gem "railties"
|
8
8
|
gem "pg", "~> 1.0"
|
9
|
-
gem "rspec-rails", "~>
|
9
|
+
gem "rspec-rails", "~> 4.0"
|
10
10
|
gem "simple_form", ">= 4.0"
|
11
11
|
gem "cocoon", ">= 1.2"
|
12
12
|
gem "jquery-rails"
|
13
13
|
gem "capybara", "~> 3.0"
|
14
|
-
gem "
|
14
|
+
gem "webdrivers", "~> 4.0"
|
15
15
|
gem "selenium-webdriver"
|
16
16
|
gem "byebug"
|
17
17
|
gem "coffee-rails"
|
data/lib/attr_json.rb
CHANGED
@@ -78,6 +78,12 @@
|
|
78
78
|
@default != NO_DEFAULT_PROVIDED
|
79
79
|
end
|
80
80
|
|
81
|
+
# Can be value or proc!
|
82
|
+
def default_argument
|
83
|
+
return nil unless has_default?
|
84
|
+
@default
|
85
|
+
end
|
86
|
+
|
81
87
|
def provide_default!
|
82
88
|
unless has_default?
|
83
89
|
raise ArgumentError.new("This #{self.class.name} does not have a default defined!")
|
@@ -54,6 +54,11 @@ module AttrJson
|
|
54
54
|
@name_to_definition.values
|
55
55
|
end
|
56
56
|
|
57
|
+
# Returns all registered attributes as an array of symbols
|
58
|
+
def attribute_names
|
59
|
+
@name_to_definition.keys
|
60
|
+
end
|
61
|
+
|
57
62
|
def container_attributes
|
58
63
|
@store_key_to_definition.keys.collect(&:to_s)
|
59
64
|
end
|
data/lib/attr_json/config.rb
CHANGED
@@ -3,10 +3,20 @@ module AttrJson
|
|
3
3
|
# and rails class_attribute. Instead, you set to new Config object
|
4
4
|
# changed with {#merge}.
|
5
5
|
class Config
|
6
|
-
RECORD_ALLOWED_KEYS = %i{
|
7
|
-
|
6
|
+
RECORD_ALLOWED_KEYS = %i{
|
7
|
+
default_container_attribute
|
8
|
+
default_rails_attribute
|
9
|
+
default_accepts_nested_attributes
|
10
|
+
}
|
11
|
+
|
12
|
+
MODEL_ALLOWED_KEYS = %i{
|
13
|
+
unknown_key
|
14
|
+
bad_cast
|
15
|
+
}
|
16
|
+
|
8
17
|
DEFAULTS = {
|
9
18
|
default_container_attribute: "json_attributes",
|
19
|
+
default_rails_attribute: false,
|
10
20
|
unknown_key: :raise
|
11
21
|
}
|
12
22
|
|
data/lib/attr_json/model.rb
CHANGED
@@ -7,6 +7,8 @@ require 'attr_json/attribute_definition/registry'
|
|
7
7
|
require 'attr_json/type/model'
|
8
8
|
require 'attr_json/model/cocoon_compat'
|
9
9
|
|
10
|
+
require 'attr_json/serialization_coder_from_type'
|
11
|
+
|
10
12
|
module AttrJson
|
11
13
|
|
12
14
|
# Meant for use in a plain class, turns it into an ActiveModel::Model
|
@@ -30,9 +32,39 @@ module AttrJson
|
|
30
32
|
#
|
31
33
|
# class Something
|
32
34
|
# include AttrJson::Model
|
33
|
-
# attr_json_config(unknown_key: :
|
35
|
+
# attr_json_config(unknown_key: :allow)
|
36
|
+
# #...
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# Similarly, trying to set a Model-valued attribute with an object that
|
40
|
+
# can't be cast to a Hash or Model at all will normally raise a
|
41
|
+
# AttrJson::Type::Model::BadCast error, but you can set config `bad_cast: :as_nil`
|
42
|
+
# to make it cast to nil, more like typical ActiveRecord cast.
|
43
|
+
#
|
44
|
+
# class Something
|
45
|
+
# include AttrJson::Model
|
46
|
+
# attr_json_config(bad_cast: :as_nil)
|
34
47
|
# #...
|
35
48
|
# end
|
49
|
+
#
|
50
|
+
# ## ActiveRecord `serialize`
|
51
|
+
#
|
52
|
+
# If you want to map a single AttrJson::Model to a json/jsonb column, you
|
53
|
+
# can use ActiveRecord `serialize` feature.
|
54
|
+
#
|
55
|
+
# https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
|
56
|
+
#
|
57
|
+
# We provide a simple shim to give you the right API for a "coder" for AR serialize:
|
58
|
+
#
|
59
|
+
# class ValueModel
|
60
|
+
# include AttrJson::Model
|
61
|
+
# attr_json :some_string, :string
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# class SomeModel < ApplicationRecord
|
65
|
+
# serialize :some_json_column, ValueModel.to_serialize_coder
|
66
|
+
# end
|
67
|
+
#
|
36
68
|
module Model
|
37
69
|
extend ActiveSupport::Concern
|
38
70
|
|
@@ -88,6 +120,10 @@ module AttrJson
|
|
88
120
|
@type ||= AttrJson::Type::Model.new(self)
|
89
121
|
end
|
90
122
|
|
123
|
+
def to_serialization_coder
|
124
|
+
@serialization_coder ||= AttrJson::SerializationCoderFromType.new(to_type)
|
125
|
+
end
|
126
|
+
|
91
127
|
# Type can be an instance of an ActiveModel::Type::Value subclass, or a symbol that will
|
92
128
|
# be looked up in `ActiveModel::Type.lookup`
|
93
129
|
#
|
@@ -240,12 +276,9 @@ module AttrJson
|
|
240
276
|
end
|
241
277
|
|
242
278
|
# Two AttrJson::Model objects are equal if they are the same class
|
243
|
-
#
|
244
|
-
# TODO: Should we allow subclasses to be equal, or should they have to be the
|
245
|
-
# exact same class?
|
279
|
+
# AND their #attributes are equal.
|
246
280
|
def ==(other_object)
|
247
|
-
|
248
|
-
other_object.attributes == self.attributes
|
281
|
+
other_object.class == self.class && other_object.attributes == self.attributes
|
249
282
|
end
|
250
283
|
|
251
284
|
# ActiveRecord objects [have a](https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/nested_attributes.rb#L367-L374)
|
data/lib/attr_json/record.rb
CHANGED
@@ -26,6 +26,37 @@ module AttrJson
|
|
26
26
|
self.attr_json_registry = AttrJson::AttributeDefinition::Registry.new
|
27
27
|
end
|
28
28
|
|
29
|
+
protected
|
30
|
+
|
31
|
+
# adapted from ActiveRecord query_attribute method
|
32
|
+
# https://github.com/rails/rails/blob/v5.2.3/activerecord/lib/active_record/attribute_methods/query.rb#L12
|
33
|
+
#
|
34
|
+
# Sadly we could not re-use Rails code here, becuase the built-in method assumes attribute
|
35
|
+
# can be obtained with `self[attr_name]`, which you can not with attr_json (is that bad?), as
|
36
|
+
# well as `self.class.columns_hash[attr_name]` which you definitely can not (which is probably not bad),
|
37
|
+
# and has no way to use the value-translation semantics independently of that. May be a problem if
|
38
|
+
# ActiveRecord changes it's query method semantics in the future, will have to be sync'd here.
|
39
|
+
#
|
40
|
+
# Used to implement query methods on attr_json attributes, like `attr_json :foo, :string`, method `#foo?`
|
41
|
+
def self.attr_json_query_method(record, attribute)
|
42
|
+
value = record.send(attribute)
|
43
|
+
|
44
|
+
case value
|
45
|
+
when true
|
46
|
+
true
|
47
|
+
when false, nil, ActiveModel::Type::Boolean::FALSE_VALUES
|
48
|
+
false
|
49
|
+
else
|
50
|
+
if value.respond_to?(:to_i) && ( Numeric === value || value.to_s !~ /[^0-9]/ )
|
51
|
+
!value.to_i.zero?
|
52
|
+
elsif value.respond_to?(:zero?)
|
53
|
+
!value.zero?
|
54
|
+
else
|
55
|
+
!value.blank?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
29
60
|
class_methods do
|
30
61
|
# Access or set class-wide json_attribute_config. Inherited by sub-classes,
|
31
62
|
# but setting on sub-classes is unique to subclass. Similar to how
|
@@ -88,10 +119,11 @@ module AttrJson
|
|
88
119
|
# @option options [Boolean] :rails_attribute (false) Create an actual ActiveRecord
|
89
120
|
# `attribute` for name param. A Rails attribute isn't needed for our functionality,
|
90
121
|
# but registering thusly will let the type be picked up by simple_form and
|
91
|
-
# other tools that may look for it via Rails attribute APIs.
|
122
|
+
# other tools that may look for it via Rails attribute APIs. Default can be changed
|
123
|
+
# with `attr_json_config(default_rails_attribute: true)`
|
92
124
|
def attr_json(name, type, **options)
|
93
125
|
options = {
|
94
|
-
rails_attribute:
|
126
|
+
rails_attribute: self.attr_json_config.default_rails_attribute,
|
95
127
|
validate: true,
|
96
128
|
container_attribute: self.attr_json_config.default_container_attribute,
|
97
129
|
accepts_nested_attributes: self.attr_json_config.default_accepts_nested_attributes
|
@@ -129,34 +161,46 @@ module AttrJson
|
|
129
161
|
# We don't actually use this for anything, we provide our own covers. But registering
|
130
162
|
# it with usual system will let simple_form and maybe others find it.
|
131
163
|
if options[:rails_attribute]
|
132
|
-
|
164
|
+
attr_json_definition = attr_json_registry[name]
|
165
|
+
|
166
|
+
attribute_args = attr_json_definition.has_default? ? { default: attr_json_definition.default_argument } : {}
|
167
|
+
self.attribute name.to_sym, attr_json_definition.type, **attribute_args
|
168
|
+
|
169
|
+
# Ensure that rails attributes tracker knows about value we just fetched
|
170
|
+
# for this particular attribute. Yes, we are registering an after_find for each
|
171
|
+
# attr_json registered with rails_attribute:true, using the `name` from above under closure. .
|
172
|
+
after_find do
|
173
|
+
value = public_send(name)
|
174
|
+
if value && has_attribute?(name.to_sym)
|
175
|
+
write_attribute(name.to_sym, value)
|
176
|
+
self.send(:clear_attribute_changes, [name.to_sym])
|
177
|
+
end
|
178
|
+
end
|
133
179
|
end
|
134
180
|
|
135
181
|
_attr_jsons_module.module_eval do
|
182
|
+
# For getter and setter, we used to use read_store_attribute/write_store_attribute
|
183
|
+
# copied from Rails store_accessor implementation.
|
184
|
+
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
185
|
+
#
|
186
|
+
# But in fact just getting/setting in the hash provided to us by ActiveRecord json type
|
187
|
+
# container works BETTER for dirty tracking. We had a test that only passed doing it
|
188
|
+
# this simple way.
|
189
|
+
|
136
190
|
define_method("#{name}=") do |value|
|
191
|
+
super(value) if defined?(super)
|
137
192
|
attribute_def = self.class.attr_json_registry.fetch(name.to_sym)
|
138
|
-
|
139
|
-
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
140
|
-
|
141
|
-
# special handling for nil, sorry, because if name key was previously
|
142
|
-
# not present, write_store_attribute by default will decide there was
|
143
|
-
# no change and refuse to make the change. TODO messy.
|
144
|
-
if value.nil? && !public_send(attribute_def.container_attribute).has_key?(attribute_def.store_key)
|
145
|
-
public_send :"#{attribute_def.container_attribute}_will_change!"
|
146
|
-
public_send(attribute_def.container_attribute)[attribute_def.store_key] = nil
|
147
|
-
else
|
148
|
-
# use of `write_store_attribute` is copied from Rails store_accessor implementation.
|
149
|
-
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
150
|
-
write_store_attribute(attribute_def.container_attribute, attribute_def.store_key, attribute_def.cast(value))
|
151
|
-
end
|
193
|
+
public_send(attribute_def.container_attribute)[attribute_def.store_key] = attribute_def.cast(value)
|
152
194
|
end
|
153
195
|
|
154
196
|
define_method("#{name}") do
|
155
197
|
attribute_def = self.class.attr_json_registry.fetch(name.to_sym)
|
198
|
+
public_send(attribute_def.container_attribute)[attribute_def.store_key]
|
199
|
+
end
|
156
200
|
|
157
|
-
|
158
|
-
#
|
159
|
-
|
201
|
+
define_method("#{name}?") do
|
202
|
+
# implementation of `query_store_attribute` is based on Rails `query_attribute` implementation
|
203
|
+
AttrJson::Record.attr_json_query_method(self, name)
|
160
204
|
end
|
161
205
|
end
|
162
206
|
|
@@ -10,6 +10,20 @@ module AttrJson
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def contains_relation
|
13
|
+
contains_relation_impl do |relation, query, params|
|
14
|
+
relation.where(query, params)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def contains_not_relation
|
19
|
+
contains_relation_impl do |relation, query, params|
|
20
|
+
relation.where.not(query, params)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def contains_relation_impl
|
13
27
|
result_relation = relation
|
14
28
|
|
15
29
|
group_attributes_by_container.each do |container_attribute, attributes|
|
@@ -18,14 +32,12 @@ module AttrJson
|
|
18
32
|
attributes.each do |key, value|
|
19
33
|
add_to_param_hash!(param_hash, key, value)
|
20
34
|
end
|
21
|
-
result_relation = result_relation
|
35
|
+
result_relation = yield(result_relation, "#{relation.table_name}.#{container_attribute} @> (?)::jsonb", param_hash.to_json)
|
22
36
|
end
|
23
37
|
|
24
38
|
result_relation
|
25
39
|
end
|
26
40
|
|
27
|
-
protected
|
28
|
-
|
29
41
|
def merge_param_hash!(original, new)
|
30
42
|
original.deep_merge!(new) do |key, old_val, new_val|
|
31
43
|
if old_val.is_a?(Array) && old_val.first.is_a?(Hash) && new_val.is_a?(Array) && new_val.first.is_a?(Hash)
|
@@ -17,6 +17,8 @@ module AttrJson
|
|
17
17
|
#
|
18
18
|
# some_model.jsonb_contains(a_string: "foo").first
|
19
19
|
#
|
20
|
+
# some_model.not_jsonb_contains(a_string: "bar").first
|
21
|
+
#
|
20
22
|
# See more in {file:README} docs.
|
21
23
|
module QueryScopes
|
22
24
|
extend ActiveSupport::Concern
|
@@ -29,6 +31,10 @@ module AttrJson
|
|
29
31
|
scope(:jsonb_contains, lambda do |attributes|
|
30
32
|
QueryBuilder.new(self, attributes).contains_relation
|
31
33
|
end)
|
34
|
+
|
35
|
+
scope(:not_jsonb_contains, lambda do |attributes|
|
36
|
+
QueryBuilder.new(self, attributes).contains_not_relation
|
37
|
+
end)
|
32
38
|
end
|
33
39
|
end
|
34
40
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AttrJson
|
2
|
+
|
3
|
+
# A little wrapper to provide an object that provides #dump and #load method for use
|
4
|
+
# as a coder second-argument for [ActiveRecord Serialization](https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html),
|
5
|
+
# that simply delegates to #serialize and #deserialize from a ActiveModel::Type object.
|
6
|
+
#
|
7
|
+
# Created to be used with an AttrJson::Model type (AttrJson::Type::Model), but hypothetically
|
8
|
+
# could be a shim from anything with serialize/deserialize to dump/load instead.
|
9
|
+
#
|
10
|
+
# class ValueModel
|
11
|
+
# include AttrJson::Model
|
12
|
+
# attr_json :some_string, :string
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# class SomeModel < ApplicationRecord
|
16
|
+
# serialize :some_json_column, ValueModel.to_serialize_coder
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Note when used with an AttrJson::Model, it will dump/load from a HASH, not a
|
20
|
+
# string. It assumes it's writing to a Json(b) column that wants/provides hashes,
|
21
|
+
# not strings.
|
22
|
+
class SerializationCoderFromType
|
23
|
+
attr_reader :type
|
24
|
+
def initialize(type)
|
25
|
+
@type = type
|
26
|
+
end
|
27
|
+
|
28
|
+
# Dump and load methods to support ActiveRecord Serialization
|
29
|
+
# too.
|
30
|
+
def dump(value)
|
31
|
+
type.serialize(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Dump and load methods to support ActiveRecord Serialization
|
35
|
+
# too. https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
|
36
|
+
def load(value)
|
37
|
+
type.deserialize(value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/attr_json/type/model.rb
CHANGED
@@ -7,6 +7,7 @@ module AttrJson
|
|
7
7
|
# You create one with AttrJson::Model::Type.new(attr_json_model_class),
|
8
8
|
# but normally that's only done in AttrJson::Model.to_type, there isn't
|
9
9
|
# an anticipated need to create from any other place.
|
10
|
+
#
|
10
11
|
class Model < ::ActiveModel::Type::Value
|
11
12
|
class BadCast < ArgumentError ; end
|
12
13
|
|
@@ -35,11 +36,13 @@ module AttrJson
|
|
35
36
|
elsif v.respond_to?(:to_h)
|
36
37
|
# TODO Maybe we ought not to do this on #to_h?
|
37
38
|
model.new_from_serializable(v.to_h)
|
39
|
+
elsif model.attr_json_config.bad_cast == :as_nil
|
40
|
+
# This was originally default behavior, to be like existing ActiveRecord
|
41
|
+
# which kind of silently does this for non-castable basic values. That
|
42
|
+
# ended up being confusing in the basic case, so now we raise by default,
|
43
|
+
# but this is still configurable.
|
44
|
+
nil
|
38
45
|
else
|
39
|
-
# Bad input. Originally we were trying to return nil, to be like
|
40
|
-
# existing ActiveRecord which kind of silently does a basic value
|
41
|
-
# with null input. But that ended up making things confusing, let's
|
42
|
-
# just raise.
|
43
46
|
raise BadCast.new("Can not cast from #{v.inspect} to #{self.type}")
|
44
47
|
end
|
45
48
|
end
|
@@ -50,7 +53,7 @@ module AttrJson
|
|
50
53
|
elsif v.kind_of?(model)
|
51
54
|
v.serializable_hash
|
52
55
|
else
|
53
|
-
cast(v).serializable_hash
|
56
|
+
(cast_v = cast(v)) && cast_v.serializable_hash
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
@@ -51,6 +51,8 @@ module AttrJson
|
|
51
51
|
# MyRecord.jsonb_contains(author: { name: "foo", type: "Corporation"})
|
52
52
|
# MyRecord.jsonb_contains(author: Corporation.new(name: "foo"))
|
53
53
|
#
|
54
|
+
# Additionally, there is not_jsonb_contains, which creates the same query terms like jsonb_contains, but negated.
|
55
|
+
#
|
54
56
|
class PolymorphicModel < ActiveModel::Type::Value
|
55
57
|
class TypeError < ::TypeError ; end
|
56
58
|
|
data/lib/attr_json/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 5.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '6.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,21 +29,21 @@ dependencies:
|
|
29
29
|
version: 5.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '6.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: bundler
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - "
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '0'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- ".travis.yml"
|
134
134
|
- ".yardopts"
|
135
135
|
- Appraisals
|
136
|
+
- CHANGELOG.md
|
136
137
|
- Gemfile
|
137
138
|
- LICENSE.txt
|
138
139
|
- README.md
|
@@ -149,6 +150,8 @@ files:
|
|
149
150
|
- gemfiles/rails_5_0.gemfile
|
150
151
|
- gemfiles/rails_5_1.gemfile
|
151
152
|
- gemfiles/rails_5_2.gemfile
|
153
|
+
- gemfiles/rails_6_0.gemfile
|
154
|
+
- gemfiles/rails_edge.gemfile
|
152
155
|
- gemfiles/rails_edge_6.gemfile
|
153
156
|
- lib/attr_json.rb
|
154
157
|
- lib/attr_json/attribute_definition.rb
|
@@ -164,6 +167,7 @@ files:
|
|
164
167
|
- lib/attr_json/record/dirty.rb
|
165
168
|
- lib/attr_json/record/query_builder.rb
|
166
169
|
- lib/attr_json/record/query_scopes.rb
|
170
|
+
- lib/attr_json/serialization_coder_from_type.rb
|
167
171
|
- lib/attr_json/type/array.rb
|
168
172
|
- lib/attr_json/type/container_attribute.rb
|
169
173
|
- lib/attr_json/type/model.rb
|
@@ -176,7 +180,7 @@ licenses:
|
|
176
180
|
metadata:
|
177
181
|
homepage_uri: https://github.com/jrochkind/attr_json
|
178
182
|
source_code_uri: https://github.com/jrochkind/attr_json
|
179
|
-
post_install_message:
|
183
|
+
post_install_message:
|
180
184
|
rdoc_options: []
|
181
185
|
require_paths:
|
182
186
|
- lib
|
@@ -191,9 +195,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
195
|
- !ruby/object:Gem::Version
|
192
196
|
version: '0'
|
193
197
|
requirements: []
|
194
|
-
|
195
|
-
|
196
|
-
signing_key:
|
198
|
+
rubygems_version: 3.0.3
|
199
|
+
signing_key:
|
197
200
|
specification_version: 4
|
198
201
|
summary: ActiveRecord attributes stored serialized in a json column, super smooth.
|
199
202
|
test_files: []
|