replicate 1.4 → 1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -101,7 +101,7 @@ ActiveRecord
101
101
  ------------
102
102
 
103
103
  Basic support for dumping and loading ActiveRecord objects is included. The
104
- tests pass under ActiveRecord versions 2.2.3, 2.3.14, 3.0.10, and 3.1.0 under
104
+ tests pass under ActiveRecord versions 2.2.3, 2.3.5, 2.3.14, 3.0.10, and 3.1.0 under
105
105
  MRI 1.8.7 as well as under MRI 1.9.2.
106
106
 
107
107
  To use customization macros in your models, require the replicate library after
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  # supported activerecord gem versions
28
28
  AR_VERSIONS = []
29
- AR_VERSIONS << '2.2.3' if RUBY_VERSION < '1.9'
29
+ AR_VERSIONS.concat %w[2.2.3 2.3.5] if RUBY_VERSION < '1.9'
30
30
  AR_VERSIONS.concat %w[2.3.14 3.0.10 3.1.0]
31
31
 
32
32
  desc "Run unit tests under all supported AR versions"
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #/ Usage: replicate --dump dumpscript.rb > objects.dump
3
- #/ replicate [-r <lib>] --dump "<ruby>" > objects.dump
3
+ #/ replicate [-r <lib>] --dump "<ruby>" [-- <argv>...] > objects.dump
4
4
  #/ replicate [-r <lib>] --load < objects.dump
5
5
  #/ Dump and load objects between environments.
6
6
  #
@@ -9,6 +9,9 @@
9
9
  #/ must call dump(object) on one or more objects. When a Ruby expression is
10
10
  #/ given, all resulting objects are dumped automatically.
11
11
  #/
12
+ #/ Dump scripts have access to any additional <argv> provided via the normal
13
+ #/ system ARGV array. This can be used to pass arguments to dump scripts.
14
+ #/
12
15
  #/ The --load form reads dump data from stdin and creates objects under the
13
16
  #/ current environment.
14
17
  #/
@@ -62,20 +65,19 @@ end
62
65
  # dump mode means we're reading records from the database here and writing to
63
66
  # stdout. the database should not be modified at all by this operation.
64
67
  if mode == :dump
65
- usage.call if ARGV.empty? || ARGV[0].empty?
68
+ script = ARGV.shift
69
+ usage.call if script.empty?
66
70
  Replicate::Dumper.new do |dumper|
67
71
  dumper.marshal_to out
68
72
  dumper.log_to $stderr, verbose, quiet
69
- ARGV.each do |code|
70
- if File.exist?(code)
71
- dumper.load_script code
72
- elsif code == '-'
73
- code = $stdin.read
74
- objects = dumper.instance_eval(code, '<stdin>', 0)
75
- else
76
- objects = dumper.instance_eval(code, '<argv>', 0)
77
- dumper.dump objects
78
- end
73
+ if script == '-'
74
+ code = $stdin.read
75
+ objects = dumper.instance_eval(code, '<stdin>', 0)
76
+ elsif File.exist?(script)
77
+ dumper.load_script script
78
+ else
79
+ objects = dumper.instance_eval(script, '<argv>', 0)
80
+ dumper.dump objects
79
81
  end
80
82
  end
81
83
 
@@ -16,7 +16,7 @@ module Replicate
16
16
  elsif ENV['RAILS_ENV']
17
17
  ENV['RAILS_ENV'] == 'production'
18
18
  elsif ENV['RACK_ENV']
19
- ENV['RAILS_ENV'] == 'production'
19
+ ENV['RACK_ENV'] == 'production'
20
20
  end
21
21
  end
22
22
 
@@ -38,16 +38,27 @@ module Replicate
38
38
  self.class.replicate_omit_attributes.each do |omit|
39
39
  attributes.delete(omit.to_s)
40
40
  end
41
- self.class.reflect_on_all_associations(:belongs_to).select {|association|
42
- association.options[:polymorphic] != true
43
- }.each do |reflection|
44
- klass = reflection.klass
41
+ self.class.reflect_on_all_associations(:belongs_to).each do |reflection|
45
42
  options = reflection.options
46
- primary_key = (options[:primary_key] || klass.primary_key).to_s
47
- foreign_key = (options[:foreign_key] || "#{reflection.name}_id").to_s
43
+ if options[:polymorphic]
44
+ if ::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR > 0
45
+ reference_class = attributes[reflection.foreign_type]
46
+ else
47
+ reference_class = attributes[options[:foreign_type]]
48
+ end
49
+ next if reference_class.nil?
50
+
51
+ klass = Kernel.const_get(reference_class)
52
+ primary_key = klass.primary_key
53
+ foreign_key = "#{reflection.name}_id"
54
+ else
55
+ klass = reflection.klass
56
+ primary_key = (options[:primary_key] || klass.primary_key).to_s
57
+ foreign_key = (options[:foreign_key] || "#{reflection.name}_id").to_s
58
+ end
48
59
  if primary_key == klass.primary_key
49
60
  if id = attributes[foreign_key]
50
- attributes[foreign_key] = [:id, reflection.klass.to_s, id]
61
+ attributes[foreign_key] = [:id, klass.to_s, id]
51
62
  else
52
63
  # nil value in association reference
53
64
  end
@@ -154,6 +165,7 @@ module Replicate
154
165
 
155
166
  # Set flag for replicating original id.
156
167
  def replicate_id=(boolean)
168
+ self.replicate_natural_key = [:id] if boolean
157
169
  @replicate_id = boolean
158
170
  end
159
171
 
@@ -168,7 +180,7 @@ module Replicate
168
180
 
169
181
  # Set which, if any, attributes should not be dumped. Also works for
170
182
  # associations.
171
- #
183
+ #
172
184
  # attribute_names - Array of attribute name symbols
173
185
  def replicate_omit_attributes=(attribute_names)
174
186
  @replicate_omit_attributes = attribute_names
@@ -51,6 +51,7 @@ ActiveRecord::Schema.define do
51
51
 
52
52
  create_table "notes", :force => true do |t|
53
53
  t.integer "notable_id"
54
+ t.string "notable_type"
54
55
  end
55
56
  end
56
57
 
@@ -252,7 +253,7 @@ class ActiveRecordTest < Test::Unit::TestCase
252
253
  assert_equal 'Note', type
253
254
  assert_equal note.id, id
254
255
  assert_equal note.notable_type, attrs['notable_type']
255
- assert_equal attrs["notable_id"], rtomayko.id
256
+ assert_equal attrs["notable_id"], [:id, 'User', rtomayko.id]
256
257
  assert_equal note, obj
257
258
  end
258
259
 
@@ -292,6 +293,54 @@ class ActiveRecordTest < Test::Unit::TestCase
292
293
  assert_equal rtomayko.emails.last, obj
293
294
  end
294
295
 
296
+ def test_dumping_polymorphic_associations
297
+ objects = []
298
+ @dumper.listen { |type, id, attrs, obj| objects << [type, id, attrs, obj] }
299
+
300
+ User.replicate_associations :notes
301
+ rtomayko = User.find_by_login('rtomayko')
302
+ note = Note.create!(:notable => rtomayko)
303
+ @dumper.dump rtomayko
304
+
305
+ assert_equal 3, objects.size
306
+
307
+ type, id, attrs, obj = objects.shift
308
+ assert_equal 'User', type
309
+ assert_equal rtomayko.id, id
310
+ assert_equal 'rtomayko', attrs['login']
311
+ assert_equal rtomayko.created_at, attrs['created_at']
312
+ assert_equal rtomayko, obj
313
+
314
+ type, id, attrs, obj = objects.shift
315
+ assert_equal 'Profile', type
316
+ assert_equal rtomayko.profile.id, id
317
+ assert_equal 'Ryan Tomayko', attrs['name']
318
+ assert_equal rtomayko.profile, obj
319
+
320
+ type, id, attrs, obj = objects.shift
321
+ assert_equal 'Note', type
322
+ assert_equal note.notable_type, attrs['notable_type']
323
+ assert_equal [:id, 'User', rtomayko.id], attrs['notable_id']
324
+ assert_equal rtomayko.notes.first, obj
325
+
326
+ end
327
+
328
+ def test_dumping_empty_polymorphic_associations
329
+ objects = []
330
+ @dumper.listen { |type, id, attrs, obj| objects << [type, id, attrs, obj] }
331
+
332
+ note = Note.create!()
333
+ @dumper.dump note
334
+
335
+ assert_equal 1, objects.size
336
+
337
+ type, id, attrs, obj = objects.shift
338
+ assert_equal 'Note', type
339
+ assert_equal nil, attrs['notable_type']
340
+ assert_equal nil, attrs['notable_id']
341
+ end
342
+
343
+
295
344
  def test_loading_everything
296
345
  objects = []
297
346
  @dumper.listen { |type, id, attrs, obj| objects << [type, id, attrs, obj] }
metadata CHANGED
@@ -1,11 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: replicate
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 5
5
+ prerelease:
5
6
  segments:
6
7
  - 1
7
- - 4
8
- version: "1.4"
8
+ - 5
9
+ version: "1.5"
9
10
  platform: ruby
10
11
  authors:
11
12
  - Ryan Tomayko
@@ -20,9 +21,11 @@ dependencies:
20
21
  name: activerecord
21
22
  prerelease: false
22
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
23
25
  requirements:
24
26
  - - ~>
25
27
  - !ruby/object:Gem::Version
28
+ hash: 5
26
29
  segments:
27
30
  - 3
28
31
  - 1
@@ -33,9 +36,11 @@ dependencies:
33
36
  name: sqlite3
34
37
  prerelease: false
35
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
36
40
  requirements:
37
41
  - - ">="
38
42
  - !ruby/object:Gem::Version
43
+ hash: 3
39
44
  segments:
40
45
  - 0
41
46
  version: "0"
@@ -77,23 +82,27 @@ rdoc_options: []
77
82
  require_paths:
78
83
  - lib
79
84
  required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
80
86
  requirements:
81
87
  - - ">="
82
88
  - !ruby/object:Gem::Version
89
+ hash: 3
83
90
  segments:
84
91
  - 0
85
92
  version: "0"
86
93
  required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
87
95
  requirements:
88
96
  - - ">="
89
97
  - !ruby/object:Gem::Version
98
+ hash: 3
90
99
  segments:
91
100
  - 0
92
101
  version: "0"
93
102
  requirements: []
94
103
 
95
104
  rubyforge_project:
96
- rubygems_version: 1.3.6
105
+ rubygems_version: 1.6.2
97
106
  signing_key:
98
107
  specification_version: 2
99
108
  summary: Dump and load relational objects between Ruby environments.