glue_gun_dsl 0.1.21 → 0.1.23

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: 1757d5bf22062e71a309eb62fd4b55aa830d36a7e7cde695f8525b960d5a0a89
4
- data.tar.gz: 8f591ab19ba6b88118834b65aa210166408bc127afba0551bb2792505e7abc64
3
+ metadata.gz: e38dfcee3bde86f31b597d6dccf5138fb7200050a05904a055b7d8f201192ab0
4
+ data.tar.gz: 9b031f91fd59f57d8a10edef069d0ec656e04b8440d55af1354dda0cbfa124e4
5
5
  SHA512:
6
- metadata.gz: c25769bebf3f9e450970506b45fa13c82281d223f3da07f1d3e667597678903da636422c24924525456f1063b4d142722729fc9bb240eec9801a6d67a1a5fae9
7
- data.tar.gz: 13e57e0b3cc63e2ed15e26d480d0622e6413476dae3fff9ba8bf1686fc6fa4c314baad22452b157982cd10699cbb6f6574c84130168d83874d817aef0dbc98e9
6
+ metadata.gz: b25d5acc5cc955c9c3b20147c6bbf81c2911860f7e7f32b48b4f21273bf7c1f992f05c6b21ed2e6353b3ace8ac39023f87dcbd100fc9041731bea3a62b5bdf2b
7
+ data.tar.gz: 69736bb98acb9e1365879c0f68f7c401cc6b675e4c7c21af9fee87c0ea074dc76fc103413a386b5b76b1c8e44534f2c3e2f163ed2242389e14dc80fc7c02e923
@@ -12,7 +12,7 @@ module GlueGun
12
12
  value
13
13
  end
14
14
 
15
- result[key] = compacted unless compacted.blank?
15
+ result[key] = compacted unless compacted.is_a?(String) && compacted.blank?
16
16
  end
17
17
  end
18
18
  end
data/lib/glue_gun/dsl.rb CHANGED
@@ -1,8 +1,11 @@
1
+ require_relative "shared"
1
2
  module GlueGun
2
3
  module DSL
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  included do
7
+ include GlueGun::Shared
8
+
6
9
  unless ancestors.include?(ActiveRecord::Base)
7
10
  include ActiveModel::Model
8
11
  include ActiveModel::Attributes
@@ -77,6 +80,8 @@ module GlueGun
77
80
  end
78
81
 
79
82
  module ClassMethods
83
+ extend GlueGun::Shared
84
+
80
85
  DEFAULT_TYPE = if ActiveModel.version >= Gem::Version.new("7")
81
86
  nil
82
87
  elsif ActiveModel.version >= Gem::Version.new("5")
@@ -156,7 +161,7 @@ module GlueGun
156
161
  end
157
162
 
158
163
  def detect_root_dir
159
- base_path = Module.const_source_location(name)&.first || ""
164
+ base_path = Module.const_source_location(self.class.name)&.first || ""
160
165
  File.dirname(base_path)
161
166
  end
162
167
  end
@@ -165,11 +170,6 @@ module GlueGun
165
170
  @initialized == true
166
171
  end
167
172
 
168
- def detect_root_dir
169
- base_path = Module.const_source_location(self.class.name)&.first || ""
170
- File.dirname(base_path)
171
- end
172
-
173
173
  def initialize_dependencies(attributes)
174
174
  self.class.dependency_definitions.each do |component_type, definition|
175
175
  value = attributes[component_type] || self.class.hardcoded_dependencies[component_type]
@@ -438,8 +438,13 @@ module GlueGun
438
438
  def determine_option_name(init_args, instance)
439
439
  option_name = nil
440
440
 
441
- # Use when block if defined
442
- if when_block
441
+ user_specified_option = init_args.is_a?(Hash) && init_args.keys.size == 1
442
+ user_specified_valid_option = user_specified_option && option_configs.key?(init_args.keys.first)
443
+
444
+ if user_specified_valid_option
445
+ option_name = init_args.keys.first
446
+ init_args = init_args[option_name] # Extract the inner value
447
+ elsif when_block.present?
443
448
  result = instance.instance_exec(init_args, &when_block)
444
449
  if result.is_a?(Hash) && result[:option]
445
450
  option_name = result[:option]
@@ -448,24 +453,6 @@ module GlueGun
448
453
  end
449
454
  end
450
455
 
451
- # Detect option from user input
452
- if option_name.nil? && (init_args.is_a?(Hash) && init_args.keys.size == 1)
453
- if option_configs.key?(init_args.keys.first)
454
- option_name = init_args.keys.first
455
- init_args = init_args[option_name] # Extract the inner value
456
- else
457
- default_option = get_option(default_option_name)
458
- unless default_option.only?
459
- raise ArgumentError,
460
- "Unknown #{component_type} option: #{init_args.keys.first}."
461
- end
462
- unless default_option.attributes.keys.include?(init_args.keys.first)
463
- raise ArgumentError, "#{default_option.class_name} does not respond to #{init_args.keys.first}"
464
- end
465
- end
466
- end
467
-
468
- # Use default option if none determined
469
456
  option_name ||= default_option_name
470
457
 
471
458
  [option_name, init_args]
@@ -1,8 +1,11 @@
1
+ require_relative "shared"
1
2
  module GlueGun
2
3
  module Model
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  included do
7
+ include GlueGun::Shared
8
+
6
9
  before_save :serialize_service_object
7
10
  after_find :deserialize_service_object
8
11
 
@@ -24,30 +27,74 @@ module GlueGun
24
27
  raise ArgumentError, "You must provide a service class, factory, or a block to resolve the service class."
25
28
  end
26
29
  end
30
+
31
+ def find_or_create_by!(attributes)
32
+ attributes = attributes.deep_symbolize_keys
33
+ db_attributes = extract_db_attributes(attributes)
34
+ attributes.except(*db_attributes.keys)
35
+
36
+ record = where(db_attributes).first_or_initialize(attributes)
37
+
38
+ if record.new_record?
39
+ record.save!
40
+ else
41
+ record.send(:build_service_object, attributes)
42
+ end
43
+ yield record if block_given?
44
+
45
+ record
46
+ end
47
+
48
+ def find_or_create_by(attributes)
49
+ attributes = attributes.deep_symbolize_keys
50
+ db_attributes = extract_db_attributes(attributes)
51
+ attributes.except(*db_attributes.keys)
52
+
53
+ record = where(db_attributes).first_or_initialize(attributes)
54
+
55
+ if record.new_record?
56
+ record.save
57
+ else
58
+ record.send(:build_service_object, attributes)
59
+ end
60
+ yield record if block_given?
61
+
62
+ record
63
+ end
64
+
65
+ def extract_db_attributes(attributes)
66
+ # Extract attributes that correspond to database columns or associations
67
+ column_names = self.column_names.map(&:to_sym)
68
+ association_names = reflect_on_all_associations.map(&:name)
69
+
70
+ attributes.slice(*(column_names + association_names))
71
+ end
27
72
  end
28
73
 
29
74
  def initialize(attributes = {})
75
+ attributes[:root_dir] = detect_root_dir
30
76
  attributes = attributes.deep_symbolize_keys
31
- db_attributes = extract_db_attributes(attributes)
77
+ db_attributes = self.class.extract_db_attributes(attributes)
32
78
  super(db_attributes)
33
- self.class.send(:attr_reader, service_attribute_name)
34
79
  build_service_object(attributes)
35
80
  end
36
81
 
37
82
  private
38
83
 
39
- def extract_db_attributes(attributes)
40
- # Extract attributes that correspond to database columns or associations
41
- column_names = self.class.column_names.map(&:to_sym)
42
- association_names = self.class.reflect_on_all_associations.map(&:name)
43
-
44
- attributes.slice(*(column_names + association_names))
45
- end
46
-
47
84
  def build_service_object(attributes)
85
+ self.class.send(:attr_reader, service_attribute_name)
48
86
  service_class = resolve_service_class(attributes)
87
+ raise "Unable to find service class for #{self.class} given #{attributes}" unless service_class.present?
88
+
49
89
  service_attributes = extract_service_attributes(attributes, service_class)
50
- service_instance = service_class.new(service_attributes)
90
+ begin
91
+ service_instance = service_class.new(service_attributes)
92
+ rescue StandardError => e
93
+ ap %(Error building service object #{service_class}:)
94
+ ap e.message
95
+ ap e.backtrace
96
+ raise e
97
+ end
51
98
  instance_variable_set("@#{service_attribute_name}", service_instance)
52
99
  end
53
100
 
@@ -116,16 +163,36 @@ module GlueGun
116
163
  }
117
164
  end
118
165
  end
119
- json = attrs.merge(deps.deep_compact).deep_symbolize_keys
166
+ json = serializable!(attrs.merge(deps.deep_compact).deep_symbolize_keys)
120
167
  write_attribute(:configuration, json.to_json)
121
168
  end
122
169
 
170
+ def serializable!(json)
171
+ regular_args = json.slice(*allowed_names(json.keys))
172
+ assoc_names = self.class.reflect_on_all_associations.map(&:name)
173
+ found_associations = assoc_names & json.keys
174
+ found_associations.each do |association|
175
+ regular_args[association] = true
176
+ end
177
+ regular_args
178
+ end
179
+
180
+ def deserialize_associations(json)
181
+ assoc_names = self.class.reflect_on_all_associations.map(&:name)
182
+ found_associations = assoc_names & json.keys
183
+ found_associations.each do |association|
184
+ json[association] = send(association)
185
+ end
186
+ json
187
+ end
188
+
123
189
  def deserialize_service_object
124
190
  serialized_data = JSON.parse(read_attribute(:configuration) || "{}")
125
191
  serialized_data.deep_symbolize_keys!
126
192
  service_class = resolve_service_class(serialized_data)
193
+ serialized_data = deserialize_associations(serialized_data)
127
194
  serialized_data = service_class.deserialize(serialized_data) if service_class.respond_to?(:deserialize)
128
- service_instance = service_class.new(serialized_data)
195
+ service_instance = build_service_object(serialized_data)
129
196
  instance_variable_set("@#{service_attribute_name}", service_instance)
130
197
  end
131
198
 
@@ -134,23 +201,11 @@ module GlueGun
134
201
  [names.map(&:to_sym) - assoc_names.map(&:to_sym)].flatten
135
202
  end
136
203
 
137
- def serialize
138
- dataset_service.attributes
139
- write_attribute(:configuration, json.to_json)
140
- end
141
-
142
- def deserialize
143
- options = JSON.parse(read_attribute(:configuration))
144
- options.deep_symbolize_keys!
145
-
146
- build_dataset_service(options)
147
- end
148
-
149
- def method_missing(method_name, *args, &block)
204
+ def method_missing(method_name, *args, **kwargs, &block)
150
205
  service_object = instance_variable_get("@#{service_attribute_name}")
151
206
 
152
207
  if service_object && service_object.respond_to?(method_name)
153
- service_object.send(method_name, *args, &block)
208
+ service_object.send(method_name, *args, **kwargs, &block)
154
209
  else
155
210
  super
156
211
  end
@@ -0,0 +1,8 @@
1
+ module GlueGun
2
+ module Shared
3
+ def detect_root_dir
4
+ base_path = Module.const_source_location(self.class.name)&.first || ""
5
+ File.dirname(base_path)
6
+ end
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GlueGun
4
- VERSION = "0.1.21"
4
+ VERSION = "0.1.23"
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.21
4
+ version: 0.1.23
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-22 00:00:00.000000000 Z
11
+ date: 2024-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -70,6 +70,20 @@ dependencies:
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
72
  version: '8'
73
+ - !ruby/object:Gem::Dependency
74
+ name: awesome_print
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
73
87
  - !ruby/object:Gem::Dependency
74
88
  name: appraisal
75
89
  requirement: !ruby/object:Gem::Requirement
@@ -194,7 +208,7 @@ files:
194
208
  - lib/glue_gun/core_ext/hash_extensions.rb
195
209
  - lib/glue_gun/dsl.rb
196
210
  - lib/glue_gun/model.rb
197
- - lib/glue_gun/my_model.rb
211
+ - lib/glue_gun/shared.rb
198
212
  - lib/glue_gun/types.rb
199
213
  - lib/glue_gun/types/array_type.rb
200
214
  - lib/glue_gun/types/date_time_type.rb
@@ -1,73 +0,0 @@
1
- module EasyML
2
- class Dataset < ActiveRecord::Base
3
- before_save :serialize
4
- after_find :deserialize
5
-
6
- validates :name, presence: true
7
- belongs_to :datasource,
8
- foreign_key: :datasource_id,
9
- class_name: "EasyML::Datasource"
10
-
11
- def initialize(options = {})
12
- super(EasyML::DbOptions.parse(options, self))
13
- build_dataset_service(options)
14
- end
15
-
16
- attr_accessor :dataset_service
17
-
18
- private
19
-
20
- def build_dataset_service(options)
21
- options.deep_symbolize_keys!
22
- service_klass = EasyML::Data::Dataset
23
-
24
- allowed_attr_names = service_klass.dependency_definitions.keys.concat(
25
- service_klass.attribute_definitions.keys
26
- )
27
-
28
- allowed_attrs = options.slice(*allowed_attr_names)
29
- @dataset_service = service_klass.new(allowed_attrs)
30
- define_dataset_service_delegators(allowed_attr_names)
31
- end
32
-
33
- def define_dataset_service_delegators(attr_names)
34
- allowed_names(attr_names).each do |attr_name|
35
- define_singleton_method(attr_name) do
36
- dataset_service.send(attr_name)
37
- end
38
- end
39
- end
40
-
41
- def allowed_names(names)
42
- assoc_names = self.class.reflect_on_all_associations.map(&:name)
43
- [names.map(&:to_sym) - assoc_names.map(&:to_sym)].flatten
44
- end
45
-
46
- def serialize
47
- attrs = dataset_service.attributes
48
- deps = allowed_names(dataset_service.dependency_definitions.keys).inject({}) do |hash, dep|
49
- hash.tap do
50
- this_dep = dataset_service.send(dep)
51
- next unless this_dep.present?
52
-
53
- opts = dataset_service.dependency_definitions[dep].option_configs
54
- selected_option = opts.detect do |_k, v|
55
- this_dep.class == v.class_name
56
- end.first
57
- hash[dep] = {
58
- selected_option => dataset_service.send(dep).attributes
59
- }
60
- end
61
- end
62
- json = attrs.merge(deps).deep_symbolize_keys.deep_compact
63
- write_attribute(:configuration, json.to_json)
64
- end
65
-
66
- def deserialize
67
- options = JSON.parse(read_attribute(:configuration))
68
- options.deep_symbolize_keys!
69
-
70
- build_dataset_service(options)
71
- end
72
- end
73
- end