data_active 0.0.5 → 0.0.6

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.
@@ -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