data_active 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -110,6 +110,12 @@ When /^the book price will be identical to those in "([^"]*)"$/ do |xml_document
110
110
  if book_price.nil?
111
111
  fail "BookPrice with id #{book_price_id} is missing"
112
112
  else
113
+ if book_price.book_id.nil?
114
+ fail "BookPrice.book_id in database isn't being set (expecting book_id = #{book_id})"
115
+ elsif book_price.book_id != book_id.to_i
116
+ fail "BookPrice.book_id in database is set incorrectly (expecting book_id = #{book_id} and got #{book_price.book_id})"
117
+ end
118
+
113
119
  book_price_sell = book_price_element.xpath("sell").text
114
120
  book_price_educational = book_price_element.xpath("educational").text
115
121
  book_price_cost = book_price_element.xpath("cost").text
@@ -141,6 +147,40 @@ When /^the book price will be identical to those in "([^"]*)"$/ do |xml_document
141
147
  end
142
148
  end
143
149
 
150
+ When /^the book price will be identical to those in "([^"]*)" with new ids$/ do |xml_document_file|
151
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
152
+
153
+ # Ensure that all chapters in the xml document have been recorded
154
+ xml_document.xpath('//book').each do |book_element|
155
+ book = Book.find_by_name book_element.xpath('name')[0].text
156
+ book_id = book.id
157
+ book_price_element = book_element.xpath('book_price')
158
+ book_price = BookPrice.find_by_book_id book_id
159
+
160
+ fail 'Too many book prices' if book_price_element.count > 1
161
+
162
+ if book_price.nil?
163
+ fail "BookPrice for book '#{book.name}' is missing"
164
+ else
165
+ book_price_sell = book_price_element.xpath('sell').text
166
+ book_price_educational = book_price_element.xpath('educational').text
167
+ book_price_cost = book_price_element.xpath('cost').text
168
+
169
+ if Float(book_price_sell) != book_price.sell
170
+ fail "BookPrice 'sell' in database doesn't match book price sell in xml for book '#{book.name}', XML: #{book_price_sell}, Database: #{book_price.sell}"
171
+ end
172
+
173
+ if Float(book_price_cost) != book_price.cost
174
+ fail "BookPrice 'cost' in database doesn't match book price cost in xml for book '#{book.name}', XML: #{book_price_cost}, Database: #{book_price.cost}"
175
+ end
176
+
177
+ if Float(book_price_educational) != book_price.educational
178
+ fail "BookPrice 'educational' in database doesn't match book price educational in xml for book '#{book.name}', XML: #{book_price_educational}, Database: #{book_price.educational}"
179
+ end
180
+ end
181
+ end
182
+ end
183
+
144
184
  When /^the chapters will be identical to those in "([^"]*)"$/ do |xml_document_file|
145
185
  chapters_in_database = Chapter.all
146
186
  if chapters_in_database.count > 0
@@ -190,18 +230,23 @@ When /^the chapters will be identical to those in "([^"]*)" with new ids$/ do |x
190
230
  xml_document.xpath("//book").each do |book_element|
191
231
  book = Book.where(:name => book_element.xpath("name")[0].text).first
192
232
  book_id = book.id
193
- xml_document.xpath("//book[name[text()='#{book_id}']]/chapters/chapter").each do |chapter_element|
233
+ xml_document.xpath("//book[name[text()='#{book.name}']]/chapters/chapter").each do |chapter_element|
194
234
  chapter_title = chapter_element.xpath("title")[0].text
195
235
  chapter_introduction = chapter_element.xpath("introduction")[0].text
196
- chapter = book.chapters.where(:title => chapter_title)
236
+ chapter = book.chapters.where(:title => chapter_title).first
197
237
 
198
238
  if chapter == nil
199
239
  fail "Chapters #{chapter_title} is missing"
200
240
  else
241
+ if chapter.book_id.nil?
242
+ fail "Chapter.book_id in database isn't being set (expecting book_id = #{book_id}"
243
+ elsif chapter.book_id != book_id
244
+ fail "Chapter.book_id in database is set incorrectly (expecting book_id = #{book_id} and got #{chapter.book_id})"
245
+ end
201
246
  if chapter_introduction != chapter.introduction
202
247
  fail "Chapter introduction in database doesn't match chapter introduction in xml for chapter #{chapter_title}, XML: #{chapter_introduction}, Database: #{chapter.introduction}"
203
248
  end
204
- if book_id != chapter.book_id.to_s
249
+ if book_id != chapter.book_id
205
250
  fail "Chapter book_id in database doesn't match chapter book_id in xml for chapter #{chapter_title}, XML: #{book_id}, Database: #{chapter.book_id}"
206
251
  end
207
252
  end
@@ -74,6 +74,11 @@
74
74
  </book>
75
75
  <book>
76
76
  <name>Book 1</name>
77
+ <book_price>
78
+ <sell>50.00</sell>
79
+ <educational>35.00</educational>
80
+ <cost>20.00</cost>
81
+ </book_price>
77
82
  <chapters type="array">
78
83
  <chapter>
79
84
  <title>Chapter 1</title>
@@ -110,6 +110,11 @@
110
110
  </book>
111
111
  <book>
112
112
  <name>Book 2</name>
113
+ <book_price>
114
+ <sell>50.00</sell>
115
+ <educational>35.00</educational>
116
+ <cost>20.00</cost>
117
+ </book_price>
113
118
  <chapter>
114
119
  <title>B2 Chapter 1</title>
115
120
  <introduction>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus purus nulla, condimentum vitae
@@ -45,6 +45,7 @@ Feature: Synchronise one to many relationships
45
45
  When I synchronise with "<xml_file>"
46
46
  Then the books in the database will be identical to those in "<xml_file>" with new ids
47
47
  And the chapters will be identical to those in "<xml_file>" with new ids
48
+ And the book price will be identical to those in "<xml_file>" with new ids
48
49
 
49
50
  Examples:
50
51
  | xml_file |
data/lib/data_active.rb CHANGED
@@ -28,7 +28,7 @@ module DataActive
28
28
  # Load or create a new record
29
29
  pk_node = current_node.xpath self.primary_key.to_s
30
30
 
31
- active_record = find_record_based_on(pk_node)
31
+ active_record = find_or_create_based_on(pk_node)
32
32
 
33
33
  unless active_record.nil?
34
34
  # Process the attributes
@@ -41,7 +41,6 @@ module DataActive
41
41
  end
42
42
 
43
43
  # Check through associations and apply sync appropriately
44
- associations = self.reflect_on_all_associations
45
44
  self.reflect_on_all_associations.each do |association|
46
45
  foreign_key = foreign_key_from(association)
47
46
  klass = association.klass
@@ -101,7 +100,11 @@ module DataActive
101
100
  new_record = klass.one_from_xml(single_objects[0], options)
102
101
  if new_record != nil
103
102
  new_record[foreign_key.to_sym] = active_record[self.primary_key.to_s]
104
- new_record.save!
103
+ if active_record.new_record?
104
+ active_record.send("#{klass.name.underscore.to_sym}=", new_record)
105
+ else
106
+ new_record.save!
107
+ end
105
108
  end
106
109
  end
107
110
  elsif single_objects.count > 1
@@ -142,6 +145,44 @@ module DataActive
142
145
  end
143
146
 
144
147
  private
148
+ def many_from(current_node)
149
+ case
150
+ when (is_ms_access_xml?(current_node) or is_rails_like_xml?(current_node))
151
+ process_children_for current_node
152
+
153
+ when self.name.underscore.eql?(current_node.name.underscore)
154
+ raise "The supplied XML (#{current_node.name}) is a single instance of '#{self.name}'. Please use one_from_xml"
155
+
156
+ else
157
+ raise "The supplied XML (#{current_node.name}) cannot be mapped to this class (#{self.name})"
158
+
159
+ end
160
+ end
161
+
162
+ def process_children_for(current_node)
163
+ records = []
164
+ recorded_ids = []
165
+
166
+ current_node.xpath(".//#{self.name.underscore}").each do |node|
167
+ record = self.one_from_xml(node, @data_active_options)
168
+ if record
169
+ recorded_ids << record[primary_key.to_sym]
170
+ records << record
171
+ end
172
+ end
173
+
174
+ remove_records_not_in recorded_ids
175
+ records
176
+ end
177
+
178
+ def is_ms_access_xml?(node)
179
+ node.name.eql?('dataroot') and node.namespace_definitions.map { |ns| ns.href }.include?('urn:schemas-microsoft-com:officedata')
180
+ end
181
+
182
+ def is_rails_like_xml?(current_node)
183
+ self.name.pluralize.underscore.eql?(current_node.name.underscore)
184
+ end
185
+
145
186
  def xml_node_matches_class(xml_node)
146
187
  if xml_node.attributes['type'].blank?
147
188
  xml_node.name.underscore == self.name.underscore
@@ -150,7 +191,7 @@ module DataActive
150
191
  end
151
192
  end
152
193
 
153
- def find_record_based_on(pk_node)
194
+ def find_or_create_based_on(pk_node)
154
195
  ar = nil
155
196
  if pk_node
156
197
  begin
@@ -232,7 +273,7 @@ module DataActive
232
273
  # Support for Rails earlier than 3.1
233
274
  foreign_key = association.primary_key_name
234
275
  else
235
- raise "Unsupported version of ActiveRecord. Unable to identify the foreign key."
276
+ raise 'Unsupported version of ActiveRecord. Unable to identify the foreign key.'
236
277
  end
237
278
  foreign_key
238
279
  end
@@ -259,61 +300,6 @@ module DataActive
259
300
  end
260
301
  end
261
302
  end
262
-
263
- def many_from_rails_xml(current_node)
264
- records = []
265
- recorded_ids = []
266
-
267
- current_node.element_children.each do |node|
268
- record = self.one_from_xml(node, @data_active_options)
269
- if record
270
- recorded_ids << record[primary_key.to_sym]
271
- records << record
272
- end
273
- end
274
-
275
- remove_records_not_in recorded_ids
276
-
277
- records
278
- end
279
-
280
- def many_from_ms_xml(current_node)
281
- records = []
282
- recorded_ids = []
283
-
284
- current_node.element_children.each do |node|
285
- if self.name.underscore.eql?(node.name.underscore)
286
- record = self.one_from_xml(node, @data_active_options)
287
- if record
288
- recorded_ids << record[primary_key.to_sym]
289
- records << record
290
- end
291
- end
292
- end
293
-
294
- remove_records_not_in recorded_ids
295
-
296
- records
297
- end
298
-
299
- def many_from(current_node)
300
- case
301
- when self.name.pluralize.underscore.eql?(current_node.name.underscore)
302
- many_from_rails_xml current_node
303
-
304
- when (current_node.name.eql?('dataroot') \
305
- and current_node.namespace_definitions.map { |ns| ns.href }.include?('urn:schemas-microsoft-com:officedata'))
306
- # Identified as data generated from Microsoft Access
307
- many_from_ms_xml current_node
308
-
309
- when self.name.underscore.eql?(current_node.name.underscore)
310
- raise "The supplied XML (#{current_node.name}) is a single instance of '#{self.name}'. Please use one_from_xml"
311
-
312
- else
313
- raise "The supplied XML (#{current_node.name}) cannot be mapped to this class (#{self.name})"
314
-
315
- end
316
- end
317
303
  end
318
304
  end
319
305
 
@@ -1,3 +1,3 @@
1
1
  module DataActive
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_active
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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-04-03 00:00:00.000000000 Z
12
+ date: 2013-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -280,7 +280,7 @@ rubyforge_project: data_active
280
280
  rubygems_version: 1.8.22
281
281
  signing_key:
282
282
  specification_version: 3
283
- summary: data_active 0.0.5
283
+ summary: data_active 0.0.6
284
284
  test_files:
285
285
  - features/remove_records_missing_in_xml.feature
286
286
  - features/step_definitions/remove_records_missing_in_xml.rb