store_model 2.1.0 → 2.1.2
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 +4 -4
- data/lib/store_model/model.rb +16 -13
- data/lib/store_model/nested_attributes.rb +31 -8
- data/lib/store_model/types/one.rb +1 -3
- data/lib/store_model/types/raw_json.rb +20 -0
- data/lib/store_model/types.rb +2 -0
- data/lib/store_model/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db36f4fa51b9f71a34198ba18b921565d46a450c62e4892628dfee8e067bf4ff
|
4
|
+
data.tar.gz: 4e72e8f0fc7051105a09843040a4cfc61f248884ac2dcc8def0f6a95f9b8390f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c5073d90550cd90049cb0cc2555bfab36c4b036857319ac5bf0f0eeadaea70deabcf71e549c7e1348127f719ba9f03bda444fb700153b8bdbbb5ffdc3e36c0f
|
7
|
+
data.tar.gz: f5a3eed707850087dfc95c908725624352da067410b3fa69762764545fd83c243a99bfbf8a4b4ae53086fdff9094377769be720cf7497b0d82ae1d7ad736e411
|
data/lib/store_model/model.rb
CHANGED
@@ -7,7 +7,7 @@ require "store_model/nested_attributes"
|
|
7
7
|
|
8
8
|
module StoreModel
|
9
9
|
# When included into class configures it to handle JSON column
|
10
|
-
module Model
|
10
|
+
module Model # rubocop:disable Metrics/ModuleLength
|
11
11
|
def self.included(base) # :nodoc:
|
12
12
|
base.include ActiveModel::Model
|
13
13
|
base.include ActiveModel::Attributes
|
@@ -44,7 +44,10 @@ module StoreModel
|
|
44
44
|
StoreModel.config.serialize_enums_using_as_json
|
45
45
|
end
|
46
46
|
|
47
|
-
result = attributes.
|
47
|
+
result = @attributes.keys.each_with_object({}) do |key, values|
|
48
|
+
values[key] = serialized_attribute(key)
|
49
|
+
end.with_indifferent_access
|
50
|
+
|
48
51
|
result.merge!(unknown_attributes) if serialize_unknown_attributes
|
49
52
|
result.as_json(options).tap do |json|
|
50
53
|
serialize_enums!(json) if serialize_enums_using_as_json
|
@@ -175,17 +178,6 @@ module StoreModel
|
|
175
178
|
@unknown_attributes ||= {}
|
176
179
|
end
|
177
180
|
|
178
|
-
# Serialized values for storing in db
|
179
|
-
#
|
180
|
-
# @return [Hash]
|
181
|
-
def values_for_database
|
182
|
-
result = @attributes.keys.each_with_object({}) do |key, values|
|
183
|
-
values[key] = @attributes.fetch(key).value_for_database
|
184
|
-
end
|
185
|
-
result.merge!(unknown_attributes)
|
186
|
-
result
|
187
|
-
end
|
188
|
-
|
189
181
|
private
|
190
182
|
|
191
183
|
def attribute?(attribute)
|
@@ -207,5 +199,16 @@ module StoreModel
|
|
207
199
|
json[name] = public_send(name).as_json unless json[name].nil?
|
208
200
|
end
|
209
201
|
end
|
202
|
+
|
203
|
+
def serialized_attribute(attr_name)
|
204
|
+
attr = @attributes.fetch(attr_name)
|
205
|
+
if attr.value.is_a? StoreModel::Model
|
206
|
+
Types::RawJSONEncoder.new(attr.value_for_database)
|
207
|
+
elsif attr.value.is_a? Array
|
208
|
+
attr.value.as_json
|
209
|
+
else
|
210
|
+
attr.value_for_database
|
211
|
+
end
|
212
|
+
end
|
210
213
|
end
|
211
214
|
end
|
@@ -35,25 +35,45 @@ module StoreModel
|
|
35
35
|
#
|
36
36
|
# See https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for
|
37
37
|
def accepts_nested_attributes_for(*attributes)
|
38
|
-
|
38
|
+
options = attributes.extract_options!
|
39
39
|
|
40
|
-
attributes.each do |attribute
|
41
|
-
case
|
40
|
+
attributes.each do |attribute|
|
41
|
+
case nested_attribute_type(attribute)
|
42
42
|
when Types::OneBase, Types::ManyBase
|
43
|
-
|
43
|
+
options.reverse_merge!(allow_destroy: false, update_only: false)
|
44
|
+
define_store_model_attr_accessors(attribute, options)
|
44
45
|
else
|
45
|
-
super(attribute, options
|
46
|
+
super(*attribute, options)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
51
|
private
|
51
52
|
|
53
|
+
# If attribute defined in ActiveRecord model but you dont yet have database created
|
54
|
+
# you cannot access attribute types.
|
55
|
+
# To handle this case, we can use ActiveRecord::Attributes 'attributes_to_define_after_schema_loads'
|
56
|
+
# which stores information about custom defined attributes.
|
57
|
+
# See ActiveRecord::Attributes#atribute
|
58
|
+
# If #accepts_nested_attributes_for is used inside active model instance
|
59
|
+
# schema is not required to determine attribute type so we can still use attribute_types
|
60
|
+
# If schema loaded the attribute_types already populated and we can safely use it
|
61
|
+
# See ActiveRecord::ModelSchema#load_schema!
|
62
|
+
def nested_attribute_type(attribute)
|
63
|
+
if self < ActiveRecord::Base && !schema_loaded?
|
64
|
+
attributes_to_define_after_schema_loads[attribute.to_s]&.first
|
65
|
+
else
|
66
|
+
attribute_types[attribute.to_s]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
52
70
|
def define_store_model_attr_accessors(attribute, options)
|
53
|
-
case
|
71
|
+
case nested_attribute_type(attribute)
|
54
72
|
when Types::OneBase
|
55
73
|
define_association_setter_for_single(attribute, options)
|
56
|
-
|
74
|
+
define_method "#{attribute}_attributes=" do |*args, **kwargs|
|
75
|
+
send("#{attribute}=", *args, **kwargs)
|
76
|
+
end
|
57
77
|
when Types::ManyBase
|
58
78
|
define_association_setter_for_many(attribute, options)
|
59
79
|
end
|
@@ -88,7 +108,10 @@ module StoreModel
|
|
88
108
|
end
|
89
109
|
end
|
90
110
|
|
91
|
-
|
111
|
+
# Base
|
112
|
+
def assign_nested_attributes_for_collection_association(association, attributes, options = nil)
|
113
|
+
return super(association, attributes) unless options
|
114
|
+
|
92
115
|
attributes = attributes.values if attributes.is_a?(Hash)
|
93
116
|
|
94
117
|
if options&.dig(:allow_destroy)
|
@@ -46,9 +46,7 @@ module StoreModel
|
|
46
46
|
# @return [String] serialized value
|
47
47
|
def serialize(value)
|
48
48
|
case value
|
49
|
-
when @model_klass
|
50
|
-
ActiveSupport::JSON.encode(value.values_for_database)
|
51
|
-
when Hash
|
49
|
+
when @model_klass, Hash
|
52
50
|
ActiveSupport::JSON.encode(value)
|
53
51
|
else
|
54
52
|
super
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StoreModel
|
4
|
+
module Types
|
5
|
+
# Implements #encode_json and #as_json methods.
|
6
|
+
# By wrapping serialized objects in this type, it prevents duplicate
|
7
|
+
# JSON serialization passes on nested object. It is named as Encoder
|
8
|
+
# as it will not work to inflate typed attributes and is intended
|
9
|
+
# to be used internally.
|
10
|
+
class RawJSONEncoder < String
|
11
|
+
def encode_json(_encoder)
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json(_options = nil)
|
16
|
+
JSON.parse(self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/store_model/types.rb
CHANGED
data/lib/store_model/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: store_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DmitryTsepelev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/store_model/types/one_of.rb
|
116
116
|
- lib/store_model/types/one_polymorphic.rb
|
117
117
|
- lib/store_model/types/polymorphic_helper.rb
|
118
|
+
- lib/store_model/types/raw_json.rb
|
118
119
|
- lib/store_model/version.rb
|
119
120
|
homepage: https://github.com/DmitryTsepelev/store_model
|
120
121
|
licenses:
|