activejsonmodel 0.1.3 → 0.1.6

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: f12f2a8c7d4739513ed25aa68753babdcee91046a61bbb853be921f6886d34ea
4
- data.tar.gz: 977442b81243736fb2fe2ecec108d1e2abfcc4d24c5a2e0a0df24cad388a731e
3
+ metadata.gz: dc97da5d920f8d4bd3086c08d7e785867d6aad6d76549ac5d4642d0dc7905269
4
+ data.tar.gz: be4f3c6d7b7eadee052cc42d7e7b7e3c4df3f7d86d9d673c6ae0c6dcd34f09f2
5
5
  SHA512:
6
- metadata.gz: be403bfb95151340f132ed221037c95f814c0c8b7ad056ed3bac3425b31034d76cc20ac798a29eb512d6eed5bdf7c2b755dc8341c553ba383ab7c760b75ff8e7
7
- data.tar.gz: a8c6ffe2e5e4f67c0835e068a0b45355f2f76681e94e068f7123c5b684a8f4f7f7cefb764fc4b1a8806c1544a5091444efe04afb55c8d04e0656a93eb03a1ee7
6
+ metadata.gz: 0ffe713e2616fff952482e90adab32f709634e6976040f7dd0c43fa34c5db81de5cf0f8f3829f83cfd9d54730618411d9b8003cfe1e415cf51111dc529a990cd
7
+ data.tar.gz: f28fee77d5d862f8615b146e7526d6593393518988f7ced44f1871914350e429dc0b1c44763674a1c1946f29699efa1bf3b1c114b87891a5133f1ac098a6352c
@@ -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
@@ -44,11 +48,18 @@ if Gem.find_files("symmetric-encryption").any? &&
44
48
  end
45
49
 
46
50
  def serialize(value)
47
- case value
48
- when @clazz
49
- ::ActiveSupport::JSON.encode(@clazz.dump(value))
50
- when Array, Hash
51
- ::ActiveSupport::JSON.encode(value)
51
+ if value.respond_to?(:dump_to_json)
52
+ SymmetricEncryption.encrypt(
53
+ value.dump_to_json,
54
+ random_iv: true,
55
+ type: :json
56
+ )
57
+ elsif ::Hash === value || ::HashWithIndifferentAccess === value || ::Array === value
58
+ SymmetricEncryption.encrypt(
59
+ value,
60
+ random_iv: true,
61
+ type: :json
62
+ )
52
63
  else
53
64
  super
54
65
  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)
@@ -56,10 +63,9 @@ if Gem.find_files("active_record").any?
56
63
  end
57
64
 
58
65
  def serialize(value)
59
- case value
60
- when @clazz
61
- ::ActiveSupport::JSON.encode(@clazz.dump(value))
62
- when Array, Hash
66
+ if value.respond_to?(:dump_to_json)
67
+ ::ActiveSupport::JSON.encode(value.dump_to_json)
68
+ elsif ::Hash === value || ::HashWithIndifferentAccess === value || ::Array === value
63
69
  ::ActiveSupport::JSON.encode(value)
64
70
  else
65
71
  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 ||= ActiveRecordType.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 ||= ActiveRecordEncryptedType.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 ||= ActiveRecordType.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 ||= ActiveRecordEncryptedType.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,21 @@ 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
+ # For polymorphic objects, it's possible that there won't be
568
+ # a base-class relationship, so just assume that if the
569
+ # object is an ActiveJsonModel object, it's good.
570
+ if val.respond_to?(:dump_to_json)
571
+ val
572
+ elsif val.is_a?(::Hash) || val.is_a?(::HashWithIndifferentAccess)
573
+ self.load(val)
574
+ end
575
+ end
576
+
550
577
  # Register a new after load callback which is invoked after the instance is loaded from JSON
551
578
  #
552
579
  # @param method_name [Symbol, String] the name of the method to be invoked
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJsonModel
4
- VERSION = "0.1.3".freeze
4
+ VERSION = "0.1.6".freeze
5
5
  end
@@ -4,8 +4,10 @@ require "active_support"
4
4
  module ActiveJsonModel
5
5
  extend ActiveSupport::Autoload
6
6
 
7
- autoload :VERSION, "active_json_model/version"
8
- autoload :Model, "active_json_model/model"
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
9
  autoload :Array, "active_json_model/array"
10
+ autoload :Model, "active_json_model/model"
10
11
  autoload :Utils, "active_json_model/utils"
12
+ autoload :VERSION, "active_json_model/version"
11
13
  end
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.3
4
+ version: 0.1.6
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-09-02 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