glue_gun_dsl 0.1.24 → 0.1.27
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/glue_gun/model.rb +122 -32
- data/lib/glue_gun/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 697e6798ae2b2c4c3db3f4e3cd9b2c65ccc8081386636c08366e4d023cb04afe
|
4
|
+
data.tar.gz: f7a025244f1b5627691676d784658d2a14a289914533e17f4c1daca896c6ebdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d32f478f2e294ae9510abb04b0ac5b5490c8468918879363f790eebc5167d7c3e28ec5edf9675301a2a211b7f5493bcf24c1884295598e9cf859f5b6b146f21
|
7
|
+
data.tar.gz: ee627464ed957cffac221bd2d701e9a9deba768e1cac558349878d101b67281a2c5977379f79496af43ed7bdbc392489c60e7d3fec2d09445b2e35526d2d256f
|
data/lib/glue_gun/model.rb
CHANGED
@@ -3,6 +3,40 @@ module GlueGun
|
|
3
3
|
module Model
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
class ServiceRegistry
|
7
|
+
attr_accessor :services
|
8
|
+
|
9
|
+
def register(k, v)
|
10
|
+
@services ||= {}
|
11
|
+
@services[k.to_sym] = v
|
12
|
+
end
|
13
|
+
|
14
|
+
def options
|
15
|
+
services.keys
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(k, v)
|
19
|
+
register(k, v)
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](k)
|
23
|
+
return nil if k.nil?
|
24
|
+
|
25
|
+
@services ||= {}
|
26
|
+
@services.dig(k.to_sym)
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_key
|
30
|
+
return unless services.keys.count == 1
|
31
|
+
|
32
|
+
services.keys.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def default
|
36
|
+
default_key.present? ? services[default_key] : nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
6
40
|
included do
|
7
41
|
include GlueGun::Shared
|
8
42
|
|
@@ -16,6 +50,13 @@ module GlueGun
|
|
16
50
|
# Set default service attribute name based on the class name
|
17
51
|
self.service_attribute_name = "#{name.demodulize.underscore}_service".to_sym
|
18
52
|
|
53
|
+
class_attribute :service_registry
|
54
|
+
self.service_registry = ServiceRegistry.new
|
55
|
+
|
56
|
+
# Set default option key based on the class name
|
57
|
+
class_attribute :option_key
|
58
|
+
self.option_key = "#{name.demodulize.underscore}_type".to_sym
|
59
|
+
|
19
60
|
def assign_attributes(attributes)
|
20
61
|
return if attributes.blank?
|
21
62
|
|
@@ -31,14 +72,8 @@ module GlueGun
|
|
31
72
|
end
|
32
73
|
|
33
74
|
class_methods do
|
34
|
-
def service(
|
35
|
-
|
36
|
-
self.service_class = class_or_proc
|
37
|
-
elsif block_given?
|
38
|
-
self.service_class_resolver = block
|
39
|
-
else
|
40
|
-
raise ArgumentError, "You must provide a service class, factory, or a block to resolve the service class."
|
41
|
-
end
|
75
|
+
def service(key, service_class)
|
76
|
+
service_registry[key] = service_class
|
42
77
|
end
|
43
78
|
|
44
79
|
def find_or_create_by!(attributes)
|
@@ -77,8 +112,10 @@ module GlueGun
|
|
77
112
|
end
|
78
113
|
|
79
114
|
def initialize(attributes = {})
|
80
|
-
attributes
|
115
|
+
attributes = {} if attributes.nil?
|
116
|
+
attributes[:root_dir] ||= detect_root_dir
|
81
117
|
attributes = attributes.deep_symbolize_keys
|
118
|
+
attributes[option_key] ||= resolve_service_type(attributes, true)
|
82
119
|
db_attributes = self.class.extract_db_attributes(attributes)
|
83
120
|
super(db_attributes)
|
84
121
|
build_service_object(attributes)
|
@@ -119,14 +156,26 @@ module GlueGun
|
|
119
156
|
instance_variable_set("@#{service_attribute_name}", service_instance)
|
120
157
|
end
|
121
158
|
|
159
|
+
def resolve_service_type(attributes, initializing = false)
|
160
|
+
attrs = if initializing || !persisted? || attributes.key?(self.class.option_key)
|
161
|
+
attributes
|
162
|
+
else
|
163
|
+
{ self.class.option_key => send(self.class.option_key) }
|
164
|
+
end
|
165
|
+
attrs[self.class.option_key] || self.class.service_registry.default_key
|
166
|
+
end
|
167
|
+
|
122
168
|
def resolve_service_class(attributes)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
raise
|
169
|
+
type = resolve_service_type(attributes)
|
170
|
+
service_class = self.class.service_registry[type] || self.class.service_registry.default
|
171
|
+
|
172
|
+
unless service_class
|
173
|
+
available_types = self.class.service_registry.options
|
174
|
+
raise ArgumentError,
|
175
|
+
"#{self.class} requires argument #{self.class.option_key}. Invalid option key received: #{type}. Allowed options are: #{available_types}"
|
129
176
|
end
|
177
|
+
|
178
|
+
service_class
|
130
179
|
end
|
131
180
|
|
132
181
|
def extract_service_attributes(attributes, service_class)
|
@@ -162,29 +211,45 @@ module GlueGun
|
|
162
211
|
end.symbolize_keys
|
163
212
|
end
|
164
213
|
|
214
|
+
def serialize_dependency(dependency, dep_instance = nil)
|
215
|
+
dep_instance = service_object.send(dependency) if dep_instance.nil?
|
216
|
+
return nil unless dep_instance.present?
|
217
|
+
|
218
|
+
return dep_instance.map { |dep| serialize_dependency(dependency, dep) } if dep_instance.is_a?(Array)
|
219
|
+
|
220
|
+
opts = service_object.dependency_definitions[dependency].option_configs
|
221
|
+
selected_option = opts.detect do |_k, v|
|
222
|
+
dep_instance.class == v.class_name
|
223
|
+
end&.first
|
224
|
+
unless selected_option.present?
|
225
|
+
raise "Don't know how to serialize dependency of type #{dependency}, available options are #{opts.keys}. You didn't specify an option."
|
226
|
+
end
|
227
|
+
|
228
|
+
serialized = dep_instance.respond_to?(:serialize) ? dep_instance.serialize : dep_instance.attributes.deep_compact
|
229
|
+
{
|
230
|
+
selected_option => serialized
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
def service_object
|
235
|
+
instance_variable_get("@#{service_attribute_name}")
|
236
|
+
end
|
237
|
+
|
238
|
+
def service_class
|
239
|
+
service_object.class
|
240
|
+
end
|
241
|
+
|
165
242
|
def serialize_service_object
|
166
|
-
|
167
|
-
service_klass = service_object.class
|
168
|
-
attrs = service_klass.respond_to?(:serialize) ? service_klass.serialize(service_object) : service_object.attributes
|
243
|
+
attrs = service_object.respond_to?(:serialize) ? service_object.serialize : service_object.attributes.deep_compact
|
169
244
|
deps = allowed_names(service_object.dependency_definitions.keys).inject({}) do |hash, dep|
|
170
245
|
hash.tap do
|
171
|
-
|
172
|
-
next
|
173
|
-
|
174
|
-
opts = service_object.dependency_definitions[dep].option_configs
|
175
|
-
selected_option = opts.detect do |_k, v|
|
176
|
-
this_dep.class == v.class_name
|
177
|
-
end&.first
|
178
|
-
unless selected_option.present?
|
179
|
-
raise "Don't know how to serialize dependency of type #{dep}, available options are #{opts.keys}. You didn't specify an option."
|
180
|
-
end
|
246
|
+
serialized = serialize_dependency(dep)
|
247
|
+
next if serialized.nil?
|
181
248
|
|
182
|
-
hash[dep] =
|
183
|
-
selected_option => service_object.send(dep).attributes
|
184
|
-
}
|
249
|
+
hash[dep] = serialized
|
185
250
|
end
|
186
251
|
end
|
187
|
-
json = serializable!(attrs.merge(deps
|
252
|
+
json = serializable!(attrs.merge(deps).deep_symbolize_keys)
|
188
253
|
write_attribute(:configuration, json.to_json)
|
189
254
|
end
|
190
255
|
|
@@ -207,12 +272,37 @@ module GlueGun
|
|
207
272
|
json
|
208
273
|
end
|
209
274
|
|
275
|
+
def deserialize_dependency(serialized, definition)
|
276
|
+
return serialized.map { |dep| deserialize_dependency(dep, definition) } if serialized.is_a?(Array)
|
277
|
+
|
278
|
+
dep_name = serialized.keys.first
|
279
|
+
selected_option = definition.option_configs[dep_name]
|
280
|
+
dependency_class = selected_option.class_name
|
281
|
+
arguments = serialized[dep_name]
|
282
|
+
|
283
|
+
dependency_class.respond_to?(:deserialize) ? dependency_class.deserialize(arguments) : arguments
|
284
|
+
{
|
285
|
+
dep_name => arguments
|
286
|
+
}
|
287
|
+
end
|
288
|
+
|
289
|
+
def deserialize_dependencies(serialized_data, service_class)
|
290
|
+
serialized_deps = (serialized_data.keys & allowed_names(service_class.dependency_definitions.keys))
|
291
|
+
serialized_deps.each do |name|
|
292
|
+
serialized = serialized_data[name]
|
293
|
+
definition = service_class.dependency_definitions[name]
|
294
|
+
serialized_data[name] = deserialize_dependency(serialized, definition)
|
295
|
+
end
|
296
|
+
serialized_data
|
297
|
+
end
|
298
|
+
|
210
299
|
def deserialize_service_object
|
211
300
|
serialized_data = JSON.parse(read_attribute(:configuration) || "{}")
|
212
301
|
serialized_data.deep_symbolize_keys!
|
213
302
|
service_class = resolve_service_class(serialized_data)
|
214
303
|
serialized_data = deserialize_associations(serialized_data)
|
215
304
|
serialized_data = service_class.deserialize(serialized_data) if service_class.respond_to?(:deserialize)
|
305
|
+
serialized_data = deserialize_dependencies(serialized_data, service_class)
|
216
306
|
service_instance = build_service_object(serialized_data)
|
217
307
|
instance_variable_set("@#{service_attribute_name}", service_instance)
|
218
308
|
end
|
data/lib/glue_gun/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glue_gun_dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Shollenberger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|