activejsonmodel 0.1.3 → 0.1.6

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: 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