activejsonmodel 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f2bf815c387423461ead46e38e315eb8ad0c866f4745ae9d67882a36e7e0b0c
4
- data.tar.gz: 59abf0fbc153f61787fd422962e5f23c74d69276de65d0483d82b3b8b1d618ac
3
+ metadata.gz: 6358d312dd78f6dec607bfcc0417e3bb716c8029d19502701d2c96704107d0f7
4
+ data.tar.gz: 0da1d126eead2748545c9455ac94a4b79c94e4278526ef9f78332104c63f121a
5
5
  SHA512:
6
- metadata.gz: db6f3794674d502cdc6ffc2b7c25e23e93685cb1255eba0c5a42fb3b431f170b6e70b874d630eaa3319a5a4f81660aa24ab4141b92f864f2a478f5931f67a660
7
- data.tar.gz: 8ca90836a7bae3ef2cc78bfe10035486c3612fc3f6c8117568320de1082b0b447fb08d4cc909e23253328396b336e0a194b98db9c0d4a5c421737106186df42d
6
+ metadata.gz: 3e9d4ec02edfcdfc3ac5eea8ed235094e37d18be43e4980d1fc789219856c73fe442116c53362f5e36e91ca1a79f3a5845f7da85e6a0822dc0271e7a2b6c7e45
7
+ data.tar.gz: 78b47a73bc4f50e8309655b01dbac8851377630941e1e85fba9c30e02e4f5a7c0c0a326c1bfd5e6fc3f0c0f04437a23e8b948a1295e235d609abfa91d0b2a40f
data/README.md CHANGED
@@ -214,12 +214,12 @@ end
214
214
 
215
215
  ```bash
216
216
  $ rake release
217
- activejsonmodel x.x.x built to pkg/activejsonmodel-x.x.x.gem.
217
+ active_json_model x.x.x built to pkg/active_json_model-x.x.x.gem.
218
218
  Tagged vx.x.x.
219
219
  Pushed git commits and release tag.
220
220
  Pushing gem to https://rubygems.org...
221
- Successfully registered gem: activejsonmodel (x.x.x)
222
- Pushed activejsonmodel x.x.x to rubygems.org
221
+ Successfully registered gem: active_json_model (x.x.x)
222
+ Pushed active_json_model x.x.x to rubygems.org
223
223
  Don't forget to publish the release on GitHub!
224
224
  ```
225
225
 
@@ -18,25 +18,29 @@ if Gem.find_files("symmetric-encryption").any? &&
18
18
  # end
19
19
  # end
20
20
  #
21
- # class Integration < ActiveRecord::Base
21
+ # class User < ActiveRecord::Base
22
22
  # attribute :credentials, Credentials.encrypted_attribute_type
23
23
  # end
24
+ #
25
+ # Alternatively, the type can be registered ahead of time:
26
+ #
27
+ # # config/initializers/types.rb
28
+ # ActiveRecord::Type.register(:credentials_encrypted_type, Credentials.encrypted_attribute_type)
29
+ #
30
+ # Then the custom type can be used as:
31
+ #
32
+ # class User < ActiveRecord::Base
33
+ # attribute :credentials, :credentials_encrypted_type
34
+ # end
35
+ #
24
36
  class ActiveRecordEncryptedType < ::ActiveJsonModel::ActiveRecordType
25
37
  def type
26
38
  :string
27
39
  end
28
40
 
29
- def cast(value)
30
- if value.is_a?(@clazz)
31
- value
32
- elsif value.is_a?(::Array)
33
- @clazz.load(value)
34
- end
35
- end
36
-
37
41
  def deserialize(value)
38
42
  if String === value
39
- decoded = SymmetricEncryption.decrypt(value, type: :json) rescue nil
43
+ decoded = SymmetricEncryption.decrypt(value, type: :json) rescue nil
40
44
  @clazz.load(decoded)
41
45
  else
42
46
  super
@@ -46,9 +50,17 @@ if Gem.find_files("symmetric-encryption").any? &&
46
50
  def serialize(value)
47
51
  case value
48
52
  when @clazz
49
- ::ActiveSupport::JSON.encode(@clazz.dump(value))
50
- when Array, Hash
51
- ::ActiveSupport::JSON.encode(value)
53
+ SymmetricEncryption.encrypt(
54
+ @clazz.dump(value),
55
+ random_iv: true,
56
+ type: :json
57
+ )
58
+ when ::Hash, ::HashWithIndifferentAccess, ::Array
59
+ SymmetricEncryption.encrypt(
60
+ value,
61
+ random_iv: true,
62
+ type: :json
63
+ )
52
64
  else
53
65
  super
54
66
  end
@@ -15,10 +15,21 @@ if Gem.find_files("active_record").any?
15
15
  # end
16
16
  # end
17
17
  #
18
- # class Integration < ActiveRecord::Base
18
+ # class User < ActiveRecord::Base
19
19
  # attribute :credentials, Credentials.attribute_type
20
20
  # end
21
21
  #
22
+ # Alternatively, the type can be registered ahead of time:
23
+ #
24
+ # # config/initializers/types.rb
25
+ # ActiveRecord::Type.register(:credentials_type, Credentials.attribute_type)
26
+ #
27
+ # Then the custom type can be used as:
28
+ #
29
+ # class User < ActiveRecord::Base
30
+ # attribute :credentials, :credentials_type
31
+ # end
32
+ #
22
33
  # This is based on:
23
34
  # https://jetrockets.pro/blog/rails-5-attributes-api-value-objects-and-jsonb
24
35
  class ActiveRecordType < ::ActiveRecord::Type::Value
@@ -39,11 +50,7 @@ if Gem.find_files("active_record").any?
39
50
  end
40
51
 
41
52
  def cast(value)
42
- if value.is_a?(@clazz)
43
- value
44
- elsif value.is_a?(::Array)
45
- @clazz.load(value)
46
- end
53
+ @clazz.active_json_model_cast(value)
47
54
  end
48
55
 
49
56
  def deserialize(value)
@@ -59,7 +66,7 @@ if Gem.find_files("active_record").any?
59
66
  case value
60
67
  when @clazz
61
68
  ::ActiveSupport::JSON.encode(@clazz.dump(value))
62
- when Array, Hash
69
+ when ::Hash, ::HashWithIndifferentAccess, ::Array
63
70
  ::ActiveSupport::JSON.encode(value)
64
71
  else
65
72
  super
@@ -6,7 +6,7 @@ require 'active_support'
6
6
  require_relative './json_attribute'
7
7
  require_relative './after_load_callback'
8
8
 
9
- if defined?(::ActiveRecord)
9
+ if Gem.find_files("active_record").any?
10
10
  require_relative './active_record_type'
11
11
  require_relative './active_record_encrypted_type'
12
12
  end
@@ -238,7 +238,11 @@ module ActiveJsonModel
238
238
  #
239
239
  # Note that this array_data would be stored as jsonb in the database
240
240
  def attribute_type
241
- @attribute_type ||= ActiveModelJsonSerializableType.new(self)
241
+ if Gem.find_files("active_record").any?
242
+ @attribute_type ||= ::ActiveJsonModel::ActiveRecordType.new(self)
243
+ else
244
+ raise RuntimeError.new('ActiveRecord must be installed to use attribute_type')
245
+ end
242
246
  end
243
247
 
244
248
  # Allow this model to be used as ActiveRecord attribute type in Rails 5+.
@@ -253,7 +257,15 @@ module ActiveJsonModel
253
257
  # Note that this array_data would be stored as a string in the database, encrypted using
254
258
  # a symmetric key at the application level.
255
259
  def encrypted_attribute_type
256
- @encrypted_attribute_type ||= ActiveModelJsonSerializableEncryptedType.new(self)
260
+ if Gem.find_files("active_record").any?
261
+ if Gem.find_files("symmetric-encryption").any?
262
+ @encrypted_attribute_type ||= ::ActiveJsonModel::ActiveRecordEncryptedType.new(self)
263
+ else
264
+ raise RuntimeError.new('symmetric-encryption must be installed to use attribute_type')
265
+ end
266
+ else
267
+ raise RuntimeError.new('active_record must be installed to use attribute_type')
268
+ end
257
269
  end
258
270
  end
259
271
 
@@ -605,6 +617,26 @@ module ActiveJsonModel
605
617
  end
606
618
  end
607
619
 
620
+ # Convert a value that might already be an instance of this class from underlying data.
621
+ # Used to delegate potential loading from ActiveRecord attributes
622
+ #
623
+ # @param vals either an instance of this model or an array-like object
624
+ def active_json_model_cast(vals)
625
+ if vals.is_a?(self)
626
+ vals
627
+ elsif vals.is_a?(::Array)
628
+ if vals.length == 0
629
+ self.new(values: vals)
630
+ elsif vals[0].respond_to?(:dump_to_json)
631
+ self.new(values: vals)
632
+ else
633
+ self.load(vals)
634
+ end
635
+ elsif vals.nil?
636
+ self.new(values: [])
637
+ end
638
+ end
639
+
608
640
  # Define a polymorphic factory to choose the concrete class for the list model. Note that because the array_data passed
609
641
  # to the block is an array of models, you must account for what the behavior is if there are no elements.
610
642
  #
@@ -5,7 +5,7 @@ require 'json'
5
5
  require_relative './json_attribute'
6
6
  require_relative './after_load_callback'
7
7
 
8
- if defined?(::ActiveRecord)
8
+ if Gem.find_files("active_record").any?
9
9
  require_relative './active_record_type'
10
10
  require_relative './active_record_encrypted_type'
11
11
  end
@@ -275,7 +275,11 @@ module ActiveJsonModel
275
275
  #
276
276
  # Note that this data would be stored as jsonb in the database
277
277
  def attribute_type
278
- @attribute_type ||= ActiveModelJsonSerializableType.new(self)
278
+ if Gem.find_files("active_record").any?
279
+ @attribute_type ||= ::ActiveJsonModel::ActiveRecordType.new(self)
280
+ else
281
+ raise RuntimeError.new('ActiveRecord must be installed to use attribute_type')
282
+ end
279
283
  end
280
284
 
281
285
  # Allow this model to be used as ActiveRecord attribute type in Rails 5+.
@@ -290,7 +294,15 @@ module ActiveJsonModel
290
294
  # Note that this data would be stored as a string in the database, encrypted using
291
295
  # a symmetric key at the application level.
292
296
  def encrypted_attribute_type
293
- @encrypted_attribute_type ||= ActiveModelJsonSerializableEncryptedType.new(self)
297
+ if Gem.find_files("active_record").any?
298
+ if Gem.find_files("symmetric-encryption").any?
299
+ @encrypted_attribute_type ||= ::ActiveJsonModel::ActiveRecordEncryptedType.new(self)
300
+ else
301
+ raise RuntimeError.new('symmetric-encryption must be installed to use attribute_type')
302
+ end
303
+ else
304
+ raise RuntimeError.new('active_record must be installed to use attribute_type')
305
+ end
294
306
  end
295
307
  end
296
308
 
@@ -547,6 +559,18 @@ module ActiveJsonModel
547
559
  end
548
560
  end
549
561
 
562
+ # Convert a value that might already be an instance of this class from underlying data.
563
+ # Used to delegate potential loading from ActiveRecord attributes
564
+ #
565
+ # @param val either an instance of this model or a Hash like object
566
+ def active_json_model_cast(val)
567
+ if val.is_a?(self)
568
+ val
569
+ elsif val.is_a?(::Hash) || val.is_a?(::HashWithIndifferentAccess)
570
+ self.load(val)
571
+ end
572
+ end
573
+
550
574
  # Register a new after load callback which is invoked after the instance is loaded from JSON
551
575
  #
552
576
  # @param method_name [Symbol, String] the name of the method to be invoked
File without changes
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJsonModel
4
- VERSION = "0.1.2".freeze
4
+ VERSION = "0.1.5".freeze
5
5
  end
@@ -1,8 +1,13 @@
1
1
  require 'active_model'
2
+ require "active_support"
2
3
 
3
4
  module ActiveJsonModel
4
- autoload :VERSION, "activejsonmodel/version"
5
- autoload :Model, "activejsonmodel/model"
6
- autoload :Array, "activejsonmodel/array"
7
- autoload :Utils, "activejsonmodel/utils"
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :ActiveRecordEncryptedType, "active_json_model/active_record_encrypted_type" unless Gem.find_files("active_record").none? || Gem.find_files("symmetric-encryption").none?
8
+ autoload :ActiveRecordType, "active_json_model/active_record_type" unless Gem.find_files("active_record").none?
9
+ autoload :Array, "active_json_model/array"
10
+ autoload :Model, "active_json_model/model"
11
+ autoload :Utils, "active_json_model/utils"
12
+ autoload :VERSION, "active_json_model/version"
8
13
  end
@@ -0,0 +1,4 @@
1
+ # This file is here to make sure Rail's autoloading of gems works
2
+ # When requiring manually, use:
3
+ # require 'active_json_model'
4
+ require_relative './active_json_model'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejsonmodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Morlok
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-22 00:00:00.000000000 Z
11
+ date: 2022-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -50,7 +50,12 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '7.1'
53
- description:
53
+ description: |
54
+ A library for creating Active Models that can serialize/deserialize to JSON. This includes full support for validation
55
+ and change detection through nested models. You can write polymorphic models or arrays of models and get full support
56
+ for natural serialization.
57
+
58
+ Active JSON Model can optionally be combined with Active Record to create nested child models via JSON/JSONB columns.
54
59
  email:
55
60
  - ryan.morlok@morlok.com
56
61
  executables: []
@@ -60,14 +65,15 @@ files:
60
65
  - LICENSE.txt
61
66
  - README.md
62
67
  - lib/active_json_model.rb
63
- - lib/activejsonmodel/active_record_encrypted_type.rb
64
- - lib/activejsonmodel/active_record_type.rb
65
- - lib/activejsonmodel/after_load_callback.rb
66
- - lib/activejsonmodel/array.rb
67
- - lib/activejsonmodel/json_attribute.rb
68
- - lib/activejsonmodel/model.rb
69
- - lib/activejsonmodel/utils.rb
70
- - lib/activejsonmodel/version.rb
68
+ - lib/active_json_model/active_record_encrypted_type.rb
69
+ - lib/active_json_model/active_record_type.rb
70
+ - lib/active_json_model/after_load_callback.rb
71
+ - lib/active_json_model/array.rb
72
+ - lib/active_json_model/json_attribute.rb
73
+ - lib/active_json_model/model.rb
74
+ - lib/active_json_model/utils.rb
75
+ - lib/active_json_model/version.rb
76
+ - lib/activejsonmodel.rb
71
77
  homepage: https://github.com/rmorlok/activejsonmodel
72
78
  licenses:
73
79
  - MIT