glue_gun_dsl 0.1.23 → 0.1.26

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: e38dfcee3bde86f31b597d6dccf5138fb7200050a05904a055b7d8f201192ab0
4
- data.tar.gz: 9b031f91fd59f57d8a10edef069d0ec656e04b8440d55af1354dda0cbfa124e4
3
+ metadata.gz: ea68a31c6e7206e0aeeb14467b1335a39047b49d870fd79cde4ce334c7c6d860
4
+ data.tar.gz: 67eb48676fc5502ca0869041ecd6c5a7d653005ea14777fe315828eca035fd42
5
5
  SHA512:
6
- metadata.gz: b25d5acc5cc955c9c3b20147c6bbf81c2911860f7e7f32b48b4f21273bf7c1f992f05c6b21ed2e6353b3ace8ac39023f87dcbd100fc9041731bea3a62b5bdf2b
7
- data.tar.gz: 69736bb98acb9e1365879c0f68f7c401cc6b675e4c7c21af9fee87c0ea074dc76fc103413a386b5b76b1c8e44534f2c3e2f163ed2242389e14dc80fc7c02e923
6
+ metadata.gz: 6830bf72b7f05306b46eb9b987f2bd15facc0510c1e2983b2c0a51802807f39518a5d6829dc499a54138a47e797e433ea16ee2b7ef1131b594e50677a64fcefc
7
+ data.tar.gz: 450f8dd49be6d2b0cdc9d840f4c03f404c1b7aaf69664ed3666b7e0cbef948952754e71ee12484a634b4661cb2e3a42e99eabc2e3d246319f3cc75e7c7598969
@@ -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
 
@@ -15,17 +49,31 @@ module GlueGun
15
49
 
16
50
  # Set default service attribute name based on the class name
17
51
  self.service_attribute_name = "#{name.demodulize.underscore}_service".to_sym
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
+
60
+ def assign_attributes(attributes)
61
+ return if attributes.blank?
62
+
63
+ attributes = attributes.deep_symbolize_keys
64
+ db_attributes = self.class.extract_db_attributes(attributes)
65
+
66
+ # Assign database attributes
67
+ super(db_attributes)
68
+
69
+ assign_service_attributes(attributes)
70
+ end
71
+ alias_method :attributes=, :assign_attributes
18
72
  end
19
73
 
20
74
  class_methods do
21
- def service(class_or_proc = nil, &block)
22
- if class_or_proc.is_a?(Class)
23
- self.service_class = class_or_proc
24
- elsif block_given?
25
- self.service_class_resolver = block
26
- else
27
- raise ArgumentError, "You must provide a service class, factory, or a block to resolve the service class."
28
- end
75
+ def service(key, service_class)
76
+ service_registry[key] = service_class
29
77
  end
30
78
 
31
79
  def find_or_create_by!(attributes)
@@ -35,11 +83,7 @@ module GlueGun
35
83
 
36
84
  record = where(db_attributes).first_or_initialize(attributes)
37
85
 
38
- if record.new_record?
39
- record.save!
40
- else
41
- record.send(:build_service_object, attributes)
42
- end
86
+ record.save! if record.new_record?
43
87
  yield record if block_given?
44
88
 
45
89
  record
@@ -52,11 +96,7 @@ module GlueGun
52
96
 
53
97
  record = where(db_attributes).first_or_initialize(attributes)
54
98
 
55
- if record.new_record?
56
- record.save
57
- else
58
- record.send(:build_service_object, attributes)
59
- end
99
+ record.save if record.new_record?
60
100
  yield record if block_given?
61
101
 
62
102
  record
@@ -72,13 +112,30 @@ module GlueGun
72
112
  end
73
113
 
74
114
  def initialize(attributes = {})
75
- attributes[:root_dir] = detect_root_dir
115
+ attributes[:root_dir] ||= detect_root_dir
76
116
  attributes = attributes.deep_symbolize_keys
117
+ attributes[option_key] ||= resolve_service_type(attributes, true)
77
118
  db_attributes = self.class.extract_db_attributes(attributes)
78
119
  super(db_attributes)
79
120
  build_service_object(attributes)
80
121
  end
81
122
 
123
+ def assign_service_attributes(attributes)
124
+ return if attributes.blank?
125
+
126
+ service_object = instance_variable_get("@#{service_attribute_name}")
127
+ return unless service_object.present?
128
+
129
+ extract_service_attributes(attributes, service_object.class).each do |attr_name, value|
130
+ unless service_object.respond_to?("#{attr_name}=")
131
+ raise NoMethodError, "Undefined attribute #{attr_name} for #{service_object.class.name}"
132
+ end
133
+
134
+ service_object.send("#{attr_name}=", value)
135
+ attribute_will_change!(attr_name.to_s)
136
+ end
137
+ end
138
+
82
139
  private
83
140
 
84
141
  def build_service_object(attributes)
@@ -98,14 +155,26 @@ module GlueGun
98
155
  instance_variable_set("@#{service_attribute_name}", service_instance)
99
156
  end
100
157
 
158
+ def resolve_service_type(attributes, initializing = false)
159
+ attrs = if initializing || !persisted? || attributes.key?(self.class.option_key)
160
+ attributes
161
+ else
162
+ { self.class.option_key => send(self.class.option_key) }
163
+ end
164
+ attrs[self.class.option_key] || self.class.service_registry.default_key
165
+ end
166
+
101
167
  def resolve_service_class(attributes)
102
- if self.class.service_class
103
- self.class.service_class
104
- elsif self.class.service_class_resolver
105
- self.class.service_class_resolver.call(attributes)
106
- else
107
- raise "Service class not defined for #{self.class.name}"
168
+ type = resolve_service_type(attributes)
169
+ service_class = self.class.service_registry[type] || self.class.service_registry.default
170
+
171
+ unless service_class
172
+ available_types = self.class.service_registry.options
173
+ raise ArgumentError,
174
+ "#{self.class} requires argument #{self.class.option_key}. Invalid option key received: #{type}. Allowed options are: #{available_types}"
108
175
  end
176
+
177
+ service_class
109
178
  end
110
179
 
111
180
  def extract_service_attributes(attributes, service_class)
@@ -158,8 +227,9 @@ module GlueGun
158
227
  raise "Don't know how to serialize dependency of type #{dep}, available options are #{opts.keys}. You didn't specify an option."
159
228
  end
160
229
 
230
+ serialized = this_dep.respond_to?(:serialize) ? this_dep.serialize : this_dep.attributes
161
231
  hash[dep] = {
162
- selected_option => service_object.send(dep).attributes
232
+ selected_option => serialized
163
233
  }
164
234
  end
165
235
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GlueGun
4
- VERSION = "0.1.23"
4
+ VERSION = "0.1.26"
5
5
  end
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.23
4
+ version: 0.1.26
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-23 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel