activejsonmodel 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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