mongo_mapper 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/UPGRADES +3 -0
  2. data/examples/plugins.rb +2 -5
  3. data/lib/mongo_mapper.rb +1 -0
  4. data/lib/mongo_mapper/connection.rb +4 -0
  5. data/lib/mongo_mapper/embedded_document.rb +1 -0
  6. data/lib/mongo_mapper/extensions/object.rb +5 -6
  7. data/lib/mongo_mapper/plugins/accessible.rb +14 -16
  8. data/lib/mongo_mapper/plugins/associations.rb +21 -23
  9. data/lib/mongo_mapper/plugins/associations/base.rb +1 -1
  10. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +4 -0
  11. data/lib/mongo_mapper/plugins/associations/many_association.rb +0 -4
  12. data/lib/mongo_mapper/plugins/associations/one_association.rb +1 -1
  13. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  14. data/lib/mongo_mapper/plugins/caching.rb +11 -13
  15. data/lib/mongo_mapper/plugins/callbacks.rb +12 -14
  16. data/lib/mongo_mapper/plugins/clone.rb +11 -13
  17. data/lib/mongo_mapper/plugins/dirty.rb +36 -38
  18. data/lib/mongo_mapper/plugins/document.rb +20 -22
  19. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +11 -13
  20. data/lib/mongo_mapper/plugins/embedded_document.rb +22 -24
  21. data/lib/mongo_mapper/plugins/equality.rb +6 -8
  22. data/lib/mongo_mapper/plugins/identity_map.rb +11 -13
  23. data/lib/mongo_mapper/plugins/inspect.rb +6 -8
  24. data/lib/mongo_mapper/plugins/keys.rb +109 -110
  25. data/lib/mongo_mapper/plugins/logger.rb +2 -4
  26. data/lib/mongo_mapper/plugins/modifiers.rb +32 -34
  27. data/lib/mongo_mapper/plugins/persistence.rb +5 -7
  28. data/lib/mongo_mapper/plugins/protected.rb +14 -16
  29. data/lib/mongo_mapper/plugins/querying.rb +29 -31
  30. data/lib/mongo_mapper/plugins/rails.rb +28 -22
  31. data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  32. data/lib/mongo_mapper/plugins/safe.rb +3 -5
  33. data/lib/mongo_mapper/plugins/sci.rb +3 -5
  34. data/lib/mongo_mapper/plugins/serialization.rb +49 -52
  35. data/lib/mongo_mapper/plugins/timestamps.rb +4 -6
  36. data/lib/mongo_mapper/plugins/validations.rb +8 -10
  37. data/lib/mongo_mapper/railtie/database.rake +1 -1
  38. data/lib/mongo_mapper/version.rb +1 -1
  39. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +1 -1
  40. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +2 -0
  41. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +63 -0
  42. data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
  43. data/test/functional/test_accessible.rb +5 -0
  44. data/test/functional/test_embedded_document.rb +12 -0
  45. data/test/functional/test_modifiers.rb +19 -19
  46. data/test/functional/test_protected.rb +10 -0
  47. data/test/functional/test_querying.rb +15 -1
  48. data/test/functional/test_validations.rb +33 -0
  49. data/test/models.rb +14 -0
  50. data/test/unit/associations/test_one_association.rb +11 -0
  51. data/test/unit/test_mongo_mapper.rb +9 -0
  52. data/test/unit/test_plugins.rb +2 -4
  53. data/test/unit/test_rails_reflect_on_association.rb +118 -0
  54. metadata +15 -11
@@ -55,7 +55,7 @@ namespace :db do
55
55
  end
56
56
  end
57
57
 
58
- desc 'Load the seed data from db/seeds.rb'
58
+ desc 'Load indexes from db/indexes.rb'
59
59
  task :index => :environment do
60
60
  indexes = File.join(Rails.root, 'db', 'indexes.rb')
61
61
  load(indexes) if File.exist?(indexes)
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
- Version = '0.10.1'
3
+ Version = '0.11.0'
4
4
  end
@@ -14,7 +14,7 @@ module MongoMapper
14
14
  end
15
15
 
16
16
  def create_model_file
17
- template 'model.rb', File.join('app/models', "#{file_name}.rb")
17
+ template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
18
18
  end
19
19
 
20
20
  hook_for :test_framework
@@ -1,3 +1,4 @@
1
+ <% module_namespacing do -%>
1
2
  class <%= class_name %>
2
3
  include MongoMapper::Document
3
4
 
@@ -9,3 +10,4 @@ class <%= class_name %>
9
10
  <% end -%>
10
11
 
11
12
  end
13
+ <% end -%>
@@ -30,6 +30,69 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
30
30
  catalog.medias[0].new?.should == false
31
31
  end
32
32
 
33
+ context "associating objects of non-SCI class" do
34
+ should "work on replacement" do
35
+ catalog = Catalog.new
36
+ catalog.medias = [Human.new(:name => 'Frank'), Robot.new(:serial_number => '1B')]
37
+
38
+ catalog.medias.size.should == 2
39
+ catalog.medias[0].name.should == 'Frank'
40
+ catalog.medias[0].class.should == Human
41
+ catalog.medias[1].serial_number.should == '1B'
42
+ catalog.medias[1].class.should == Robot
43
+
44
+ catalog.save.should be_true
45
+ catalog.reload
46
+
47
+ catalog.medias.size.should == 2
48
+ catalog.medias[0].name.should == 'Frank'
49
+ catalog.medias[0].class.should == Human
50
+ catalog.medias[1].serial_number.should == '1B'
51
+ catalog.medias[1].class.should == Robot
52
+ end
53
+
54
+ should "work on replacement with hashes" do
55
+ catalog = Catalog.new
56
+ catalog.medias = [{:name => 'Frank', '_type' => 'Human'}, {:serial_number => '1B', '_type' => 'Robot'}]
57
+
58
+ catalog.medias.size.should == 2
59
+ catalog.medias[0].name.should == 'Frank'
60
+ catalog.medias[0].class.should == Human
61
+ catalog.medias[1].serial_number.should == '1B'
62
+ catalog.medias[1].class.should == Robot
63
+
64
+ catalog.save.should be_true
65
+ catalog.reload
66
+
67
+ catalog.medias.size.should == 2
68
+ catalog.medias[0].name.should == 'Frank'
69
+ catalog.medias[0].class.should == Human
70
+ catalog.medias[1].serial_number.should == '1B'
71
+ catalog.medias[1].class.should == Robot
72
+ end
73
+
74
+ should "work with concatination" do
75
+ catalog = Catalog.new
76
+ catalog.medias << Human.new(:name => 'Frank')
77
+ catalog.medias << Robot.new(:serial_number => '1B')
78
+
79
+ catalog.medias.size.should == 2
80
+ catalog.medias[0].name.should == 'Frank'
81
+ catalog.medias[0].class.should == Human
82
+ catalog.medias[1].serial_number.should == '1B'
83
+ catalog.medias[1].class.should == Robot
84
+
85
+ catalog.save.should be_true
86
+ catalog.reload
87
+
88
+ catalog.medias.size.should == 2
89
+ catalog.medias[0].name.should == 'Frank'
90
+ catalog.medias[0].class.should == Human
91
+ catalog.medias[1].serial_number.should == '1B'
92
+ catalog.medias[1].class.should == Robot
93
+ end
94
+ end
95
+
33
96
  context "count" do
34
97
  should "default to 0" do
35
98
  Catalog.new.medias.count.should == 0
@@ -0,0 +1,208 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class OneEmbeddedPolymorhpicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ @post_class = Doc('Post') do
7
+ key :title, String
8
+ end
9
+ end
10
+
11
+ should "default to nil" do
12
+ @post_class.one :author, :polymorphic => true, :class => Robot
13
+ @post_class.new.author.should be_nil
14
+ end
15
+
16
+ should "return nil instead of a proxy" do
17
+ @post_class.one :author, :polymorphic => true, :class => Robot
18
+ nil.should === @post_class.new.author
19
+ end
20
+
21
+ should "be able to build" do
22
+ @post_class.one :author, :polymorphic => true, :class => Robot
23
+ post = @post_class.create
24
+ author = post.build_author(:serial_number => "1B")
25
+ post.author.should be_instance_of(Robot)
26
+ post.author.should be_new
27
+ post.author.serial_number.should == '1B'
28
+ post.author.should == author
29
+ post.author.post.should == post
30
+ end
31
+
32
+ should "allow assignment of associated document using a hash" do
33
+ @post_class.one :author, :polymorphic => :true, :class => Robot
34
+
35
+ post = @post_class.new('author' => { 'name' => 'Frank', '_type' => 'Human' })
36
+ post.author.name.should == 'Frank'
37
+ post.author.class.should == Human
38
+
39
+ post.save.should be_true
40
+ post.reload
41
+
42
+ post.author.name.should == 'Frank'
43
+ post.author.class.should == Human
44
+ end
45
+
46
+ context "replacing the association" do
47
+ context "with an object" do
48
+ setup do
49
+ @post_class.one :author, :polymorphic => true, :class => Robot
50
+ @post = @post_class.create
51
+ @human = Human.new(:name => 'Frank')
52
+ end
53
+
54
+ should "work" do
55
+ @post.author = @human
56
+ @post.save
57
+ @post.reload
58
+
59
+ @post.author.should == @human
60
+ @post.author.nil?.should be_false
61
+ @post.author.class.should == Human
62
+
63
+ new_human = Human.new(:name => 'Emily')
64
+ @post.author = new_human
65
+ @post.author.should == new_human
66
+ end
67
+
68
+ should "generate a new proxy instead of modifying the existing one" do
69
+ @post.author = @human
70
+ @post.save
71
+ @post.reload
72
+
73
+ @post.author.should == @human
74
+ @post.author.nil?.should be_false
75
+
76
+ original_author = @post.author
77
+ original_author.name.should == 'Frank'
78
+ new_human = Human.new(:name => 'Emily')
79
+ @post.author = new_human
80
+ @post.author.should == new_human
81
+
82
+ original_author.name.should == 'Frank'
83
+ end
84
+
85
+ should "assign _type" do
86
+ @post.author = @human
87
+ @post.author._type.should == "Human"
88
+ end
89
+ end
90
+
91
+ context "with a Hash" do
92
+ setup do
93
+ @post_class.one :author, :polymorphic => true, :class => Robot
94
+ @post = @post_class.create
95
+ end
96
+
97
+ should "convert to an object of the class and work" do
98
+ @post.author = {'serial_number' => '1B'}
99
+ @post.save
100
+ @post.reload
101
+
102
+ @post.author.serial_number.should == '1B'
103
+ @post.author.nil?.should be_false
104
+
105
+ @post.author = {'serial_number' => '2C'}
106
+ @post.author.serial_number.should == '2C'
107
+ end
108
+
109
+ should "convert to an object of _type if given" do
110
+ @post.author = {'name' => 'Frank', '_type' => 'Human'}
111
+ @post.author.name.should == 'Frank'
112
+ @post.author.class.should == Human
113
+ @post.save
114
+ @post.reload
115
+
116
+ @post.author.name.should == 'Frank'
117
+ @post.author.class.should == Human
118
+ end
119
+
120
+ should "assign _type" do
121
+ @post.author = {'name' => 'Frank', '_type' => 'Human'}
122
+ @post.save
123
+ @post.reload
124
+ @post.author._type.should == "Human"
125
+ end
126
+ end
127
+ end
128
+
129
+ should "unset the association" do
130
+ @post_class.one :author, :polymorphic => true, :class => Robot
131
+ post = @post_class.create
132
+ human = Human.new
133
+ post.update_attributes!(:author => human)
134
+ post.reload
135
+ post.author = nil
136
+ post.author.should == nil
137
+ end
138
+
139
+ should "set modularized associated models correctly" do
140
+ @post_class.one :author, :polymorphic => true, :class => Robot
141
+
142
+ post = @post_class.new('author' => {'_type' => 'TrModels::Ambulance', 'license_plate' => 'GGG123', 'icu' => true})
143
+
144
+ post.author.class.should == TrModels::Ambulance
145
+ post.author.license_plate.should == 'GGG123'
146
+ post.author.icu.should be_true
147
+ post.save.should be_true
148
+
149
+ post = post.reload
150
+ post.author.class.should == TrModels::Ambulance
151
+ post.author.license_plate.should == 'GGG123'
152
+ post.author.icu.should be_true
153
+ end
154
+
155
+ should "not have problem loading root document if embedded one is nil" do
156
+ @post_class.one :author, :polymorphic => true, :class => Robot
157
+ post = @post_class.create
158
+
159
+ lambda {
160
+ @post_class.find(post.id)
161
+ }.should_not raise_error
162
+ end
163
+
164
+ should "load the parent and root documents for nested embedded documents" do
165
+ @address_class = EDoc('Address') do
166
+ key :city, String
167
+ key :state, String
168
+ end
169
+ @author_class = EDoc('EmbeddedAuthor')
170
+ @author_class.one :address, :polymorphic => true, :class => @address_class
171
+ @post_class.one :author, :polymorphic => true, :class => @author_class
172
+
173
+ post = @post_class.create(:title => 'Post Title', :author => { :name => 'Frank', :address => { :city => 'Boston', :state => 'MA' } })
174
+
175
+ post.author.address._parent_document.should == post.author
176
+ post.author.address._root_document.should == post
177
+ end
178
+
179
+ should "have boolean method for testing presence" do
180
+ @post_class.one :author, :polymorphic => true, :class => Robot
181
+
182
+ post = @post_class.new
183
+ post.author?.should be_false
184
+
185
+ post.author = Human.new(:name => 'Frank')
186
+ post.author?.should be_true
187
+ end
188
+
189
+ should "initialize id for nested embedded document created from hash" do
190
+ @address_class = EDoc('Address') do
191
+ key :city, String
192
+ key :state, String
193
+ end
194
+ @author_class = EDoc('EmbeddedAuthor')
195
+ @author_class.one :address, :polymorphic => true, :class => @address_class
196
+ @post_class.one :author, :polymorphic => true, :class => @author_class
197
+
198
+ post = @post_class.create(:title => 'Post Title', :author => {
199
+ :name => 'Frank',
200
+ :address => {
201
+ :city => 'Boston',
202
+ :state => 'MA'
203
+ }
204
+ })
205
+
206
+ post.author.address.id.should_not be_nil
207
+ end
208
+ end
@@ -68,6 +68,11 @@ class AccessibleTest < Test::Unit::TestCase
68
68
  doc.name.should == 'John'
69
69
  end
70
70
 
71
+ should "not ignore inaccessible attribute on #update_attribute" do
72
+ @doc.update_attribute('admin', true)
73
+ @doc.admin.should be_true
74
+ end
75
+
71
76
  should "ignore inaccessible attribute on #update_attributes" do
72
77
  @doc.update_attributes(:name => 'Ren Hoek', :admin => true)
73
78
  @doc.name.should == 'Ren Hoek'
@@ -241,6 +241,18 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
241
241
  person.pets.first.crazy_key.should == 'crazy'
242
242
  end
243
243
 
244
+ should "be able to update_attribute" do
245
+ pet = @pet_klass.new(:name => 'sparky')
246
+ person = @klass.create(:pets => [pet])
247
+ person.reload
248
+ pet = person.pets.first
249
+
250
+ pet.update_attribute('name', 'koda').should be_true
251
+ person.reload
252
+ person.pets.first._id.should == pet._id
253
+ person.pets.first.name.should == 'koda'
254
+ end
255
+
244
256
  should "be able to update_attributes" do
245
257
  pet = @pet_klass.new(:name => 'sparky')
246
258
  person = @klass.create(:pets => [pet])
@@ -156,7 +156,7 @@ class ModifierTest < Test::Unit::TestCase
156
156
  @page.tags.should == %w(foo)
157
157
 
158
158
  @page2.reload
159
- @page.tags.should == %w(foo)
159
+ @page2.tags.should == %w(foo)
160
160
  end
161
161
 
162
162
  should "work with ids and modifier hash" do
@@ -166,7 +166,7 @@ class ModifierTest < Test::Unit::TestCase
166
166
  @page.tags.should == %w(foo)
167
167
 
168
168
  @page2.reload
169
- @page.tags.should == %w(foo)
169
+ @page2.tags.should == %w(foo)
170
170
  end
171
171
  end
172
172
 
@@ -184,7 +184,7 @@ class ModifierTest < Test::Unit::TestCase
184
184
  @page.tags.should == @tags
185
185
 
186
186
  @page2.reload
187
- @page.tags.should == @tags
187
+ @page2.tags.should == @tags
188
188
  end
189
189
 
190
190
  should "work with ids and modifier hash" do
@@ -194,7 +194,7 @@ class ModifierTest < Test::Unit::TestCase
194
194
  @page.tags.should == @tags
195
195
 
196
196
  @page2.reload
197
- @page.tags.should == @tags
197
+ @page2.tags.should == @tags
198
198
  end
199
199
  end
200
200
 
@@ -211,7 +211,7 @@ class ModifierTest < Test::Unit::TestCase
211
211
  @page.tags.should == %w(bar)
212
212
 
213
213
  @page2.reload
214
- @page.tags.should == %w(bar)
214
+ @page2.tags.should == %w(bar)
215
215
  end
216
216
 
217
217
  should "be able to pull with ids and modifier hash" do
@@ -221,7 +221,7 @@ class ModifierTest < Test::Unit::TestCase
221
221
  @page.tags.should == %w(bar)
222
222
 
223
223
  @page2.reload
224
- @page.tags.should == %w(bar)
224
+ @page2.tags.should == %w(bar)
225
225
  end
226
226
  end
227
227
 
@@ -238,7 +238,7 @@ class ModifierTest < Test::Unit::TestCase
238
238
  @page.tags.should == %w(baz)
239
239
 
240
240
  @page2.reload
241
- @page.tags.should == %w(baz)
241
+ @page2.tags.should == %w(baz)
242
242
  end
243
243
 
244
244
  should "work with ids and modifier hash" do
@@ -248,7 +248,7 @@ class ModifierTest < Test::Unit::TestCase
248
248
  @page.tags.should == %w(baz)
249
249
 
250
250
  @page2.reload
251
- @page.tags.should == %w(baz)
251
+ @page2.tags.should == %w(baz)
252
252
  end
253
253
  end
254
254
 
@@ -265,7 +265,7 @@ class ModifierTest < Test::Unit::TestCase
265
265
  @page.tags.should == %w(foo)
266
266
 
267
267
  @page2.reload
268
- @page.tags.should == %w(foo)
268
+ @page2.tags.should == %w(foo)
269
269
  end
270
270
 
271
271
  should "be able to add to set with ids and modifier hash" do
@@ -275,7 +275,7 @@ class ModifierTest < Test::Unit::TestCase
275
275
  @page.tags.should == %w(foo)
276
276
 
277
277
  @page2.reload
278
- @page.tags.should == %w(foo)
278
+ @page2.tags.should == %w(foo)
279
279
  end
280
280
  end
281
281
 
@@ -292,7 +292,7 @@ class ModifierTest < Test::Unit::TestCase
292
292
  @page.tags.should == %w(foo)
293
293
 
294
294
  @page2.reload
295
- @page.tags.should == %w(foo)
295
+ @page2.tags.should == %w(foo)
296
296
  end
297
297
 
298
298
  should "be able to push uniq with ids and modifier hash" do
@@ -302,7 +302,7 @@ class ModifierTest < Test::Unit::TestCase
302
302
  @page.tags.should == %w(foo)
303
303
 
304
304
  @page2.reload
305
- @page.tags.should == %w(foo)
305
+ @page2.tags.should == %w(foo)
306
306
  end
307
307
  end
308
308
 
@@ -325,7 +325,7 @@ class ModifierTest < Test::Unit::TestCase
325
325
  end
326
326
  end
327
327
 
328
- context "InstanceMethods" do
328
+ context "instance methods" do
329
329
  should "be able to unset with keys" do
330
330
  page = @page_class.create(:title => 'Foo', :tags => %w(foo))
331
331
  page.unset(:title, :tags)
@@ -368,7 +368,7 @@ class ModifierTest < Test::Unit::TestCase
368
368
  page.reload
369
369
  page.tags.should == %w(foo)
370
370
  end
371
-
371
+
372
372
  should "be able to push_all with modifier hashes" do
373
373
  page = @page_class.create
374
374
  page.push_all(:tags => %w(foo bar))
@@ -384,7 +384,7 @@ class ModifierTest < Test::Unit::TestCase
384
384
  page.reload
385
385
  page.tags.should == %w(bar)
386
386
  end
387
-
387
+
388
388
  should "be able to pull_all with criteria and modifier hashes" do
389
389
  page = @page_class.create(:tags => %w(foo bar baz))
390
390
  page.pull_all(:tags => %w(foo bar))
@@ -398,13 +398,13 @@ class ModifierTest < Test::Unit::TestCase
398
398
  page2 = @page_class.create
399
399
 
400
400
  page.add_to_set(:tags => 'foo')
401
- page.add_to_set(:tags => 'foo')
401
+ page2.add_to_set(:tags => 'foo')
402
402
 
403
403
  page.reload
404
404
  page.tags.should == %w(foo)
405
405
 
406
406
  page2.reload
407
- page.tags.should == %w(foo)
407
+ page2.tags.should == %w(foo)
408
408
  end
409
409
 
410
410
  should "be able to push uniq with criteria and modifier hash" do
@@ -412,13 +412,13 @@ class ModifierTest < Test::Unit::TestCase
412
412
  page2 = @page_class.create
413
413
 
414
414
  page.push_uniq(:tags => 'foo')
415
- page.push_uniq(:tags => 'foo')
415
+ page2.push_uniq(:tags => 'foo')
416
416
 
417
417
  page.reload
418
418
  page.tags.should == %w(foo)
419
419
 
420
420
  page2.reload
421
- page.tags.should == %w(foo)
421
+ page2.tags.should == %w(foo)
422
422
  end
423
423
 
424
424
  should "be able to pop with modifier hashes" do