mongo_mapper 0.10.1 → 0.11.0

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