drive_time 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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