drive_time 0.0.7 → 0.0.8

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.
@@ -104,10 +104,13 @@ module DriveTime
104
104
  def worksheet_for_association(name, worksheets)
105
105
  # And find the worksheet that satisfies it
106
106
  worksheets.each do |worksheet|
107
+ puts "#{name} --->"
107
108
  class_name = DriveTime.class_name_from_title(worksheet.title)
108
- resolved = @class_name_map.resolve_mapped_from_original class_name
109
+ puts " -- #{DriveTime.underscore_from_text(worksheet.title)}"
110
+ #resolved = @class_name_map.resolve_mapped_from_original class_name
111
+ #puts "Resolved -- #{resolved}"
109
112
  # If the name matches we have a dependent relationship
110
- if resolved.underscore == name
113
+ if name == DriveTime.underscore_from_text(worksheet.title)
111
114
  return worksheet
112
115
  end
113
116
  end
@@ -6,7 +6,7 @@ module DriveTime
6
6
 
7
7
  class NoClassWithTitleError < StandardError; end
8
8
  class NoFieldNameError < StandardError; end
9
-
9
+ class NoMethodError < StandardError; end
10
10
  class NoKeyError < StandardError; end
11
11
  class PolymorphicAssociationError < StandardError; end
12
12
 
@@ -57,7 +57,8 @@ module DriveTime
57
57
  model_key = build_id_for_model mapping
58
58
  Logger.log_as_sub_header "Model Key: #{model_key}"
59
59
  # Build hash ready to pass into model
60
- model_fields = row_fields_to_model_fields mapping, model_key
60
+ model_fields = row_fields_to_model_fields(mapping, model_key)
61
+ method_calls = row_fields_to_method_calls(mapping, model_key)
61
62
 
62
63
  # Set the model key as an attribute on the model
63
64
  if mapping[:key_to]
@@ -65,8 +66,23 @@ module DriveTime
65
66
  end
66
67
 
67
68
  Logger.debug "Creating Model of class '#{clazz.name.to_s}' with Model Fields #{model_fields.to_s}"
69
+
68
70
  # Create new model
69
71
  model = clazz.new(model_fields, without_protection: true)
72
+
73
+ # Invoke any method calls
74
+ method_calls.each do |method_call|
75
+ call_step = model
76
+ methods = method_call["methods"]
77
+ methods.each_with_index do |method, index|
78
+ if index == method_call.length - 1
79
+ call_step.send(method, method_call["value"])
80
+ else
81
+ call_step = call_step.send(method)
82
+ end
83
+ end
84
+ end
85
+
70
86
  # Add its associations
71
87
  add_associations(model, mapping)
72
88
  # Store the model using its ID
@@ -85,39 +101,46 @@ module DriveTime
85
101
  end
86
102
  end
87
103
 
104
+ def row_fields_to_method_calls(mapping, model_key)
105
+ method_calls = []
106
+ # Run through the mapping, pulling values from row_map as required
107
+ if mapping[:calls]
108
+ mapping[:calls].each do |call_mapping|
109
+ field_name = call_mapping[:name]
110
+ methods = call_mapping[:methods]
111
+
112
+ unless methods
113
+ raise NoMethodError "Missing Method: Name for call field: #{field_name} in mapping: #{mapping}"
114
+ end
115
+
116
+ field_value = parse_field_value(@row_map[field_name])
117
+
118
+ # handle multi-values
119
+ if call_mapping[:builder] == "multi"
120
+ field_value = MultiBuilder.new.build(field_value)
121
+ end
122
+ method_calls << {"methods" => methods, "value" => field_value}
123
+ end
124
+ end
125
+ return method_calls
126
+ end
127
+
88
128
  # Run through the mapping's fields and convert them
89
129
  def row_fields_to_model_fields(mapping, model_key)
90
130
  model_fields = HashWithIndifferentAccess.new
131
+
91
132
  # Run through the mapping, pulling values from row_map as required
92
133
  if mapping[:fields]
93
134
  mapping[:fields].each do |field_mapping|
94
135
  field_name = field_mapping[:name]
95
136
  mapped_to_field_name = field_mapping[:map_to]
137
+
96
138
  unless field_name
97
139
  raise NoFieldNameError "Missing Field: Name for field: #{value} in mapping: #{mapping}"
98
140
  end
99
141
 
100
- field_value = @row_map[field_name]
101
- # Check for token pattern: {{some_value}}
102
- match = /\{\{(.*?)\}\}/.match(field_value)
103
- if match
104
- field_value = @field_expander.expand(match[1], model_key)
105
- end
106
-
107
- # Check for Boolean values
108
- if field_value
109
- downcased = field_value.downcase
110
- if downcased == 'y' || downcased == 'yes' || downcased == 'true'
111
- field_value = true
112
- elsif downcased == 'n' || downcased == 'no' || downcased == 'false'
113
- field_value = false
114
- end
115
- end
116
-
117
- # Make sure any empty cells give us nil (rather than an empty string)
118
- field_value = nil if field_value.blank?
142
+ field_value = parse_field_value(@row_map[field_name])
119
143
  model_fields[mapped_to_field_name || field_name] = field_value
120
-
121
144
  end
122
145
  end
123
146
  return model_fields
@@ -133,7 +156,7 @@ module DriveTime
133
156
  associations_mapping.each do |association_mapping|
134
157
  # Use the spreadsheet name unless 'map_to_class' is set
135
158
  if !association_mapping[:polymorphic]
136
- association_class_name = @class_name_map.resolve_mapped_from_original association_mapping[:name].classify
159
+ association_class_name = @class_name_map.resolve_mapped_from_original(association_mapping[:name].classify)
137
160
  else
138
161
  possible_class_names = association_mapping[:name]
139
162
  # The classname will be taken from the type collumn
@@ -180,7 +203,7 @@ module DriveTime
180
203
  associated_models.each do |associated_model|
181
204
  Logger.debug " - Associated Model: #{associated_model}"
182
205
  unless association_mapping[:inverse] == true
183
- association_name = association_class_name.underscore
206
+ association_name = association_class_name.split('::').last.underscore
184
207
  if association_mapping[:singular] == true
185
208
  Logger.debug " - Adding association #{associated_model} to #{model}::#{association_name}"
186
209
  # Set the association
@@ -210,9 +233,11 @@ module DriveTime
210
233
  def associated_models_from_builder(association_mapping, class_name)
211
234
  associated_models = []
212
235
  if association_mapping[:builder] == 'multi' # It's a multi value, find a matching cell and split its value by comma
213
- cell_value = @row_map[class_name.underscore.pluralize]
214
- raise MissingAssociationError "No field #{class_name.underscore.pluralize} to satisfy multi association" if !cell_value && association_mapping[:optional] != true
215
- components = cell_value.split ','
236
+ # Use only the classname for the fieldname, discarding namespace
237
+ field_name = class_name.split("::").last.underscore.pluralize
238
+ cell_value = @row_map[field_name]
239
+ raise MissingAssociationError "No field #{class_name.underscore.pluralize} to satisfy multi association" if cell_value.blank? && association_mapping[:optional] != true
240
+ components = MultiBuilder.new.build(cell_value)
216
241
  components.each do |component|
217
242
  associated_models << model_for_id(component, namespaced_class_name(class_name))
218
243
  end
@@ -252,9 +277,40 @@ module DriveTime
252
277
  end
253
278
  end
254
279
 
255
- def namespaced_class_name class_name
280
+ def namespaced_class_name(class_name)
256
281
  class_name = "#{@namespace}::#{class_name}" unless @namespace.blank?
257
282
  class_name.constantize
258
283
  end
284
+
285
+ def parse_field_value(field_value)
286
+ if field_value
287
+ field_value = check_for_token(field_value)
288
+ field_value = check_for_boolean(field_value)
289
+ end
290
+ # Make sure any empty cells give us nil (rather than an empty string)
291
+ field_value = nil if field_value.blank?
292
+ field_value
293
+ end
294
+
295
+ def check_for_token(field_value)
296
+ # Check for token pattern: {{some_value}}
297
+ match = /\{\{(.*?)\}\}/.match(field_value)
298
+ if match
299
+ @field_expander.expand(match[1], model_key)
300
+ else
301
+ field_value
302
+ end
303
+ end
304
+
305
+ def check_for_boolean(field_value)
306
+ downcased = field_value.downcase
307
+ if downcased == 'y' || downcased == 'yes' || downcased == 'true'
308
+ true
309
+ elsif downcased == 'n' || downcased == 'no' || downcased == 'false'
310
+ false
311
+ else
312
+ field_value
313
+ end
314
+ end
259
315
  end
260
316
  end
@@ -32,6 +32,7 @@ module DriveTime
32
32
  class_string = clazz.to_s
33
33
  # Sanitise key
34
34
  key = DriveTime.underscore_from_text(key)
35
+
35
36
  @logger.debug "Adding model with key #{key} of class #{clazz}"
36
37
  if !@store[class_string]
37
38
  @store[class_string] = {}
@@ -43,7 +44,6 @@ module DriveTime
43
44
 
44
45
  def get_model(clazz, key)
45
46
  @logger.debug "Request for model with key #{key} of class #{clazz}"
46
-
47
47
  models_for_class = @store[clazz.to_s]
48
48
  # Are there any classes of this type in the store?
49
49
  if models_for_class.nil?
@@ -52,8 +52,7 @@ module DriveTime
52
52
 
53
53
  # Is there an instance
54
54
  model = models_for_class[key]
55
-
56
- if !model
55
+ unless model.preset?
57
56
  raise NoModelOfClassWithKeyInStoreError, "No model of class #{clazz} with a key of #{key} in model store"
58
57
  end
59
58
 
@@ -61,13 +60,21 @@ module DriveTime
61
60
  end
62
61
 
63
62
  def save_all
63
+ @logger.log_as_header "Saving Models"
64
64
  @store.each do |key, models|
65
65
  models.each do |key, model|
66
- model.save!
66
+ @logger.debug "Saving Model: #{key} #{model.inspect}"
67
+ begin
68
+ model.save!
69
+ rescue Exception => error
70
+ @logger.warn "Failed To Save Model: #{key}"
71
+ @logger.warn "Error: #{error}"
72
+ @logger.warn "#{model.inspect}"
73
+ raise error
74
+ end
67
75
  end
68
76
  end
69
77
  end
70
78
 
71
79
  end
72
-
73
80
  end
@@ -1,3 +1,3 @@
1
1
  module DriveTime
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/drive_time.rb CHANGED
@@ -15,6 +15,7 @@ require 'drive_time/loader'
15
15
  require 'drive_time/class_name_map'
16
16
  require 'drive_time/builders/join_builder'
17
17
  require 'drive_time/builders/name_builder'
18
+ require 'drive_time/builders/multi_builder'
18
19
  require 'drive_time/converters/spreadsheets_converter'
19
20
  require 'drive_time/converters/worksheet_converter'
20
21
  require 'drive_time/logging'
@@ -21,7 +21,7 @@ spreadsheets:
21
21
  builder: use_fields
22
22
  field_names: [label_1, label_2, label_3]
23
23
  singular: true
24
- - name: act
24
+ - name: group
25
25
  singular: true
26
26
 
27
27
  - title: Label
data/spec/full_tests.rb CHANGED
@@ -45,4 +45,4 @@ module DriveTime
45
45
  end
46
46
 
47
47
  end
48
- end
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drive_time
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-09 00:00:00.000000000 Z
12
+ date: 2013-09-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: log4r