djsun-mongo_mapper 0.5.0.1

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 (71) hide show
  1. data/.gitignore +8 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +39 -0
  4. data/Rakefile +87 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +55 -0
  7. data/lib/mongo_mapper/associations/base.rb +83 -0
  8. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
  9. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +22 -0
  10. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +27 -0
  11. data/lib/mongo_mapper/associations/many_documents_proxy.rb +116 -0
  12. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
  13. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +67 -0
  14. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
  15. data/lib/mongo_mapper/associations/many_proxy.rb +6 -0
  16. data/lib/mongo_mapper/associations/proxy.rb +74 -0
  17. data/lib/mongo_mapper/associations.rb +86 -0
  18. data/lib/mongo_mapper/callbacks.rb +106 -0
  19. data/lib/mongo_mapper/document.rb +308 -0
  20. data/lib/mongo_mapper/dynamic_finder.rb +35 -0
  21. data/lib/mongo_mapper/embedded_document.rb +354 -0
  22. data/lib/mongo_mapper/finder_options.rb +94 -0
  23. data/lib/mongo_mapper/key.rb +32 -0
  24. data/lib/mongo_mapper/observing.rb +50 -0
  25. data/lib/mongo_mapper/pagination.rb +51 -0
  26. data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
  27. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
  28. data/lib/mongo_mapper/save_with_validation.rb +19 -0
  29. data/lib/mongo_mapper/serialization.rb +55 -0
  30. data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
  31. data/lib/mongo_mapper/support.rb +171 -0
  32. data/lib/mongo_mapper/validations.rb +69 -0
  33. data/lib/mongo_mapper.rb +95 -0
  34. data/mongo_mapper.gemspec +156 -0
  35. data/specs.watchr +32 -0
  36. data/test/NOTE_ON_TESTING +1 -0
  37. data/test/custom_matchers.rb +48 -0
  38. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
  39. data/test/functional/associations/test_belongs_to_proxy.rb +49 -0
  40. data/test/functional/associations/test_many_documents_as_proxy.rb +244 -0
  41. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +132 -0
  42. data/test/functional/associations/test_many_embedded_proxy.rb +174 -0
  43. data/test/functional/associations/test_many_polymorphic_proxy.rb +297 -0
  44. data/test/functional/associations/test_many_proxy.rb +331 -0
  45. data/test/functional/test_associations.rb +44 -0
  46. data/test/functional/test_binary.rb +18 -0
  47. data/test/functional/test_callbacks.rb +85 -0
  48. data/test/functional/test_document.rb +964 -0
  49. data/test/functional/test_embedded_document.rb +97 -0
  50. data/test/functional/test_logger.rb +20 -0
  51. data/test/functional/test_pagination.rb +87 -0
  52. data/test/functional/test_rails_compatibility.rb +30 -0
  53. data/test/functional/test_validations.rb +279 -0
  54. data/test/models.rb +169 -0
  55. data/test/test_helper.rb +30 -0
  56. data/test/unit/serializers/test_json_serializer.rb +193 -0
  57. data/test/unit/test_association_base.rb +144 -0
  58. data/test/unit/test_document.rb +165 -0
  59. data/test/unit/test_dynamic_finder.rb +125 -0
  60. data/test/unit/test_embedded_document.rb +643 -0
  61. data/test/unit/test_finder_options.rb +193 -0
  62. data/test/unit/test_key.rb +175 -0
  63. data/test/unit/test_mongomapper.rb +28 -0
  64. data/test/unit/test_observing.rb +101 -0
  65. data/test/unit/test_pagination.rb +109 -0
  66. data/test/unit/test_rails_compatibility.rb +39 -0
  67. data/test/unit/test_serializations.rb +52 -0
  68. data/test/unit/test_support.rb +272 -0
  69. data/test/unit/test_time_zones.rb +40 -0
  70. data/test/unit/test_validations.rb +503 -0
  71. metadata +207 -0
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Status.collection.clear
7
+ Project.collection.clear
8
+ end
9
+
10
+ should "default to nil" do
11
+ status = Status.new
12
+ status.target.nil?.should == true
13
+ status.target.inspect.should == "nil"
14
+ end
15
+
16
+ should "be able to replace the association" do
17
+ status = Status.new
18
+ project = Project.new(:name => "mongomapper")
19
+ status.target = project
20
+ status.save.should be_true
21
+
22
+ from_db = Status.find(status.id)
23
+ from_db.target.nil?.should == false
24
+ from_db.target_id.should == project.id
25
+ from_db.target_type.should == "Project"
26
+ from_db.target.name.should == "mongomapper"
27
+ end
28
+
29
+ should "unset the association" do
30
+ status = Status.new
31
+ project = Project.new(:name => "mongomapper")
32
+ status.target = project
33
+ status.save.should be_true
34
+
35
+ from_db = Status.find(status.id)
36
+ from_db.target = nil
37
+ from_db.target_type.nil?.should == true
38
+ from_db.target_id.nil?.should == true
39
+ from_db.target.nil?.should == true
40
+ end
41
+
42
+ context "association id set but document not found" do
43
+ setup do
44
+ @status = Status.new
45
+ project = Project.new(:name => "mongomapper")
46
+ @status.target = project
47
+ @status.save.should be_true
48
+ project.destroy
49
+ end
50
+
51
+ should "return nil instead of raising error" do
52
+ @status.target.nil?.should == true
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Status.collection.clear
7
+ Project.collection.clear
8
+ end
9
+
10
+ should "default to nil" do
11
+ status = Status.new
12
+ status.project.nil?.should == true
13
+ status.project.inspect.should == "nil"
14
+ end
15
+
16
+ should "be able to replace the association" do
17
+ status = Status.new
18
+ project = Project.new(:name => "mongomapper")
19
+ status.project = project
20
+ status.save.should be_true
21
+
22
+ from_db = Status.find(status.id)
23
+ from_db.project.should_not be_nil
24
+ from_db.project.name.should == "mongomapper"
25
+ end
26
+
27
+ should "unset the association" do
28
+ status = Status.new
29
+ project = Project.new(:name => "mongomapper")
30
+ status.project = project
31
+ status.save.should be_true
32
+
33
+ from_db = Status.find(status.id)
34
+ from_db.project = nil
35
+ from_db.project.nil?.should == true
36
+ from_db.project.inspect.should == "nil"
37
+ end
38
+
39
+ context "association id set but document not found" do
40
+ setup do
41
+ @status = Status.new(:name => 'Foo', :project_id => '1234')
42
+ end
43
+
44
+ should "return nil instead of raising error" do
45
+ @status.project.nil?.should == true
46
+ @status.project.inspect.should == "nil"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,244 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Post.collection.clear
7
+ PostComment.collection.clear
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ Post.new.comments.should == []
12
+ end
13
+
14
+ should "add type and id key to polymorphic class base" do
15
+ PostComment.keys.keys.should include('commentable_type')
16
+ PostComment.keys.keys.should include('commentable_id')
17
+ end
18
+
19
+ should "allow adding to association like it was an array" do
20
+ post = Post.new
21
+ post.comments << PostComment.new(:body => 'foo bar')
22
+ post.comments << PostComment.new(:body => 'baz')
23
+ post.comments.concat PostComment.new(:body => 'baz')
24
+
25
+ post.comments.size.should == 3
26
+ end
27
+
28
+ should "be able to replace the association" do
29
+ post = Post.new
30
+
31
+ lambda {
32
+ post.comments = [
33
+ PostComment.new(:body => 'foo'),
34
+ PostComment.new(:body => 'bar'),
35
+ PostComment.new(:body => 'baz')
36
+ ]
37
+ }.should change { PostComment.count }.by(3)
38
+
39
+ from_db = Post.find(post.id)
40
+ from_db.comments.size.should == 3
41
+ from_db.comments[0].body.should == 'foo'
42
+ from_db.comments[1].body.should == 'bar'
43
+ from_db.comments[2].body.should == 'baz'
44
+ end
45
+
46
+ context "build" do
47
+ should "assign foreign key" do
48
+ post = Post.new
49
+ comment = post.comments.build
50
+ comment.commentable_id.should == post.id
51
+ end
52
+
53
+ should "assign _type" do
54
+ post = Post.new
55
+ comment = post.comments.build
56
+ comment.commentable_type.should == "Post"
57
+ end
58
+
59
+ should "allow assigning attributes" do
60
+ post = Post.new
61
+ comment = post.comments.build(:body => 'foo bar')
62
+ comment.body.should == 'foo bar'
63
+ end
64
+ end
65
+
66
+ context "create" do
67
+ should "assign foreign key" do
68
+ post = Post.new
69
+ comment = post.comments.create
70
+ comment.commentable_id.should == post.id
71
+ end
72
+
73
+ should "assign _type" do
74
+ post = Post.new
75
+ comment = post.comments.create
76
+ comment.commentable_type.should == "Post"
77
+ end
78
+
79
+ should "save record" do
80
+ post = Post.new
81
+ lambda {
82
+ post.comments.create(:body => 'baz')
83
+ }.should change { PostComment.count }
84
+ end
85
+
86
+ should "allow passing attributes" do
87
+ post = Post.create
88
+ comment = post.comments.create(:body => 'foo bar')
89
+ comment.body.should == 'foo bar'
90
+ end
91
+ end
92
+
93
+ context "count" do
94
+ should "work scoped to association" do
95
+ post = Post.create
96
+ 3.times { post.comments.create(:body => 'foo bar') }
97
+
98
+ other_post = Post.create
99
+ 2.times { other_post.comments.create(:body => 'baz') }
100
+
101
+ post.comments.count.should == 3
102
+ other_post.comments.count.should == 2
103
+ end
104
+
105
+ should "work with conditions" do
106
+ post = Post.create
107
+ post.comments.create(:body => 'foo bar')
108
+ post.comments.create(:body => 'baz')
109
+ post.comments.create(:body => 'foo bar')
110
+
111
+ post.comments.count(:body => 'foo bar').should == 2
112
+ end
113
+ end
114
+
115
+ context "Finding scoped to association" do
116
+ setup do
117
+ @post = Post.new
118
+
119
+ @comment1 = PostComment.create(:body => 'comment1', :name => 'John')
120
+ @comment2 = PostComment.create(:body => 'comment2', :name => 'Steve')
121
+ @comment3 = PostComment.create(:body => 'comment3', :name => 'John')
122
+ @post.comments = [@comment1, @comment2]
123
+ @post.save
124
+
125
+ @post2 = Post.create(:body => "post #2")
126
+ @comment4 = PostComment.create(:body => 'comment1', :name => 'Chas')
127
+ @comment5 = PostComment.create(:body => 'comment2', :name => 'Dan')
128
+ @comment6 = PostComment.create(:body => 'comment3', :name => 'Ed')
129
+ @post2.comments = [@comment4, @comment5, @comment6]
130
+ @post2.save
131
+ end
132
+
133
+ context "with :all" do
134
+ should "work" do
135
+ @post.comments.find(:all).should include(@comment1)
136
+ @post.comments.find(:all).should include(@comment2)
137
+ end
138
+
139
+ should "work with conditions" do
140
+ comments = @post.comments.find(:all, :conditions => {:body => 'comment1'})
141
+ comments.should == [@comment1]
142
+ end
143
+
144
+ should "work with order" do
145
+ comments = @post.comments.find(:all, :order => 'body desc')
146
+ comments.should == [@comment2, @comment1]
147
+ end
148
+ end
149
+
150
+ context "with #all" do
151
+ should "work" do
152
+ @post.comments.all.should == [@comment1, @comment2]
153
+ end
154
+
155
+ should "work with conditions" do
156
+ comments = @post.comments.all(:conditions => {:body => 'comment1'})
157
+ comments.should == [@comment1]
158
+ end
159
+
160
+ should "work with order" do
161
+ comments = @post.comments.all(:order => 'body desc')
162
+ comments.should == [@comment2, @comment1]
163
+ end
164
+ end
165
+
166
+ context "with one id" do
167
+ should "work for id in association" do
168
+ @post.comments.find(@comment2.id).should == @comment2
169
+ end
170
+
171
+ should "not work for id not in association" do
172
+ lambda {
173
+ @post.comments.find(@comment5.id)
174
+ }.should raise_error(MongoMapper::DocumentNotFound)
175
+ end
176
+ end
177
+
178
+ context "with multiple ids" do
179
+ should "work for ids in association" do
180
+ posts = @post.comments.find(@comment1.id, @comment2.id)
181
+ posts.should == [@comment1, @comment2]
182
+ end
183
+
184
+ should "not work for ids not in association" do
185
+ lambda {
186
+ @post.comments.find(@comment1.id, @comment2.id, @comment4.id)
187
+ }.should raise_error(MongoMapper::DocumentNotFound)
188
+ end
189
+ end
190
+
191
+ context "dynamic finders" do
192
+ should "work with single key" do
193
+ @post.comments.find_by_body('comment1').should == @comment1
194
+ @post2.comments.find_by_body('comment1').should == @comment4
195
+ end
196
+
197
+ should "work with multiple keys" do
198
+ @post.comments.find_by_body_and_name('comment1', 'John').should == @comment1
199
+ @post.comments.find_by_body_and_name('comment1', 'Frank').should be_nil
200
+ end
201
+
202
+ should "raise error when using !" do
203
+ lambda {
204
+ @post.comments.find_by_body!('asdf')
205
+ }.should raise_error(MongoMapper::DocumentNotFound)
206
+ end
207
+
208
+ context "find_or_create_by" do
209
+ should "not create document if found" do
210
+ lambda {
211
+ comment = @post.comments.find_or_create_by_name('Steve')
212
+ comment.commentable.should == @post
213
+ comment.should == @comment2
214
+ }.should_not change { PostComment.count }
215
+ end
216
+
217
+ should "create document if not found" do
218
+ lambda {
219
+ @post.comments.find_or_create_by_name('Chas')
220
+ }.should change { PostComment.count }.by(1)
221
+ end
222
+ end
223
+ end
224
+
225
+ context "with #paginate" do
226
+ setup do
227
+ @comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'name')
228
+ end
229
+
230
+ should "return total pages" do
231
+ @comments.total_pages.should == 2
232
+ end
233
+
234
+ should "return total entries" do
235
+ @comments.total_entries.should == 3
236
+ end
237
+
238
+ should "return the subject" do
239
+ @comments.should include(@comment4)
240
+ @comments.should include(@comment5)
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,132 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Catalog.collection.clear
7
+ TrModels::Fleet.collection.clear
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ catalog = Catalog.new
12
+ catalog.medias.should == []
13
+ end
14
+
15
+ should "allow adding to association like it was an array" do
16
+ catalog = Catalog.new
17
+ catalog.medias << Video.new
18
+ catalog.medias.push Video.new
19
+ catalog.medias.size.should == 2
20
+ end
21
+
22
+ should "be able to replace the association" do
23
+ catalog = Catalog.new
24
+ catalog.medias = [Video.new("file" => "video.mpg", "length" => 3600)]
25
+ catalog.save.should be_true
26
+
27
+ from_db = Catalog.find(catalog.id)
28
+ from_db.medias.size.should == 1
29
+ from_db.medias[0].file.should == "video.mpg"
30
+ end
31
+
32
+ should "store different associations" do
33
+ catalog = Catalog.new
34
+ catalog.medias = [
35
+ Video.new("file" => "video.mpg", "length" => 3600),
36
+ Music.new("file" => "music.mp3", "bitrate" => "128kbps"),
37
+ Image.new("file" => "image.png", "width" => 800, "height" => 600)
38
+ ]
39
+ catalog.save.should be_true
40
+
41
+ from_db = Catalog.find(catalog.id)
42
+ from_db.medias.size.should == 3
43
+ from_db.medias[0].file.should == "video.mpg"
44
+ from_db.medias[0].length.should == 3600
45
+ from_db.medias[1].file.should == "music.mp3"
46
+ from_db.medias[1].bitrate.should == "128kbps"
47
+ from_db.medias[2].file.should == "image.png"
48
+ from_db.medias[2].width.should == 800
49
+ from_db.medias[2].height.should == 600
50
+ end
51
+
52
+ context "With modularized models" do
53
+ should "set associations correctly" do
54
+ fleet_attributes = {
55
+ "name" => "My Fleet",
56
+ "transports" => [
57
+ {"_type" => "TrModels::Ambulance", "license_plate" => "GGG123", "icu" => true},
58
+ {"_type" => "TrModels::Car", "license_plate" => "ABC123", "model" => "VW Golf", "year" => 2001},
59
+ {"_type" => "TrModels::Car", "license_plate" => "DEF123", "model" => "Honda Accord", "year" => 2008},
60
+ ]
61
+ }
62
+
63
+ fleet = TrModels::Fleet.new(fleet_attributes)
64
+ fleet.transports.size.should == 3
65
+ fleet.transports[0].class.should == TrModels::Ambulance
66
+ fleet.transports[0].license_plate.should == "GGG123"
67
+ fleet.transports[0].icu.should be_true
68
+ fleet.transports[1].class.should == TrModels::Car
69
+ fleet.transports[1].license_plate.should == "ABC123"
70
+ fleet.transports[1].model.should == "VW Golf"
71
+ fleet.transports[1].year.should == 2001
72
+ fleet.transports[2].class.should == TrModels::Car
73
+ fleet.transports[2].license_plate.should == "DEF123"
74
+ fleet.transports[2].model.should == "Honda Accord"
75
+ fleet.transports[2].year.should == 2008
76
+ fleet.save.should be_true
77
+
78
+ from_db = TrModels::Fleet.find(fleet.id)
79
+ from_db.transports.size.should == 3
80
+ from_db.transports[0].license_plate.should == "GGG123"
81
+ from_db.transports[0].icu.should be_true
82
+ from_db.transports[1].license_plate.should == "ABC123"
83
+ from_db.transports[1].model.should == "VW Golf"
84
+ from_db.transports[1].year.should == 2001
85
+ from_db.transports[2].license_plate.should == "DEF123"
86
+ from_db.transports[2].model.should == "Honda Accord"
87
+ from_db.transports[2].year.should == 2008
88
+ end
89
+
90
+ should "default reader to empty array" do
91
+ fleet = TrModels::Fleet.new
92
+ fleet.transports.should == []
93
+ end
94
+
95
+ should "allow adding to association like it was an array" do
96
+ fleet = TrModels::Fleet.new
97
+ fleet.transports << TrModels::Car.new
98
+ fleet.transports.push TrModels::Bus.new
99
+ fleet.transports.size.should == 2
100
+ end
101
+
102
+ should "be able to replace the association" do
103
+ fleet = TrModels::Fleet.new
104
+ fleet.transports = [TrModels::Car.new("license_plate" => "DCU2013", "model" => "Honda Civic")]
105
+ fleet.save.should be_true
106
+
107
+ from_db = TrModels::Fleet.find(fleet.id)
108
+ from_db.transports.size.should == 1
109
+ from_db.transports[0].license_plate.should == "DCU2013"
110
+ end
111
+
112
+ should "store different associations" do
113
+ fleet = TrModels::Fleet.new
114
+ fleet.transports = [
115
+ TrModels::Car.new("license_plate" => "ABC1223", "model" => "Honda Civic", "year" => 2003),
116
+ TrModels::Bus.new("license_plate" => "XYZ9090", "max_passengers" => 51),
117
+ TrModels::Ambulance.new("license_plate" => "HDD3030", "icu" => true)
118
+ ]
119
+ fleet.save.should be_true
120
+
121
+ from_db = TrModels::Fleet.find(fleet.id)
122
+ from_db.transports.size.should == 3
123
+ from_db.transports[0].license_plate.should == "ABC1223"
124
+ from_db.transports[0].model.should == "Honda Civic"
125
+ from_db.transports[0].year.should == 2003
126
+ from_db.transports[1].license_plate.should == "XYZ9090"
127
+ from_db.transports[1].max_passengers.should == 51
128
+ from_db.transports[2].license_plate.should == "HDD3030"
129
+ from_db.transports[2].icu.should == true
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,174 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyEmbeddedProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Project.collection.clear
7
+ RealPerson.collection.clear
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ Project.new.addresses.should == []
12
+ end
13
+
14
+ should "allow adding to association like it was an array" do
15
+ project = Project.new
16
+ project.addresses << Address.new
17
+ project.addresses.push Address.new
18
+ project.addresses.size.should == 2
19
+ end
20
+
21
+ should "allow finding :all embedded documents" do
22
+ project = Project.new
23
+ project.addresses << Address.new
24
+ project.addresses << Address.new
25
+ project.save
26
+ end
27
+
28
+ should "be embedded in document on save" do
29
+ sb = Address.new(:city => 'South Bend', :state => 'IN')
30
+ chi = Address.new(:city => 'Chicago', :state => 'IL')
31
+ project = Project.new
32
+ project.addresses << sb
33
+ project.addresses << chi
34
+ project.save
35
+
36
+ from_db = Project.find(project.id)
37
+ from_db.addresses.size.should == 2
38
+ from_db.addresses[0].should == sb
39
+ from_db.addresses[1].should == chi
40
+ end
41
+
42
+ should "allow embedding arbitrarily deep" do
43
+ @document = Class.new do
44
+ include MongoMapper::Document
45
+ set_collection_name 'test'
46
+ key :person, Person
47
+ end
48
+ @document.collection.clear
49
+
50
+ meg = Person.new(:name => "Meg")
51
+ meg.child = Person.new(:name => "Steve")
52
+ meg.child.child = Person.new(:name => "Linda")
53
+
54
+ doc = @document.new(:person => meg)
55
+ doc.save
56
+
57
+ from_db = @document.find(doc.id)
58
+ from_db.person.name.should == 'Meg'
59
+ from_db.person.child.name.should == 'Steve'
60
+ from_db.person.child.child.name.should == 'Linda'
61
+ end
62
+
63
+ should "allow assignment of 'many' embedded documents using a hash" do
64
+ person_attributes = {
65
+ "name" => "Mr. Pet Lover",
66
+ "pets" => [
67
+ {"name" => "Jimmy", "species" => "Cocker Spainel"},
68
+ {"name" => "Sasha", "species" => "Siberian Husky"},
69
+ ]
70
+ }
71
+
72
+ pet_lover = RealPerson.new(person_attributes)
73
+ pet_lover.name.should == "Mr. Pet Lover"
74
+ pet_lover.pets[0].name.should == "Jimmy"
75
+ pet_lover.pets[0].species.should == "Cocker Spainel"
76
+ pet_lover.pets[1].name.should == "Sasha"
77
+ pet_lover.pets[1].species.should == "Siberian Husky"
78
+ pet_lover.save.should be_true
79
+
80
+ from_db = RealPerson.find(pet_lover.id)
81
+ from_db.name.should == "Mr. Pet Lover"
82
+ from_db.pets[0].name.should == "Jimmy"
83
+ from_db.pets[0].species.should == "Cocker Spainel"
84
+ from_db.pets[1].name.should == "Sasha"
85
+ from_db.pets[1].species.should == "Siberian Husky"
86
+ end
87
+
88
+ context "embedding many embedded documents" do
89
+ setup do
90
+ @document = Class.new do
91
+ include MongoMapper::Document
92
+ set_collection_name 'test'
93
+ many :people
94
+ end
95
+ @document.collection.clear
96
+ end
97
+
98
+ should "persist all embedded documents" do
99
+ meg = Person.new(:name => "Meg")
100
+ sparky = Pet.new(:name => "Sparky", :species => "Dog")
101
+ koda = Pet.new(:name => "Koda", :species => "Dog")
102
+
103
+ doc = @document.new
104
+
105
+ meg.pets << sparky
106
+ meg.pets << koda
107
+
108
+ doc.people << meg
109
+ doc.save
110
+
111
+ from_db = @document.find(doc.id)
112
+ from_db.people.first.name.should == "Meg"
113
+ from_db.people.first.pets.should_not == []
114
+ from_db.people.first.pets.first.name.should == "Sparky"
115
+ from_db.people.first.pets.first.species.should == "Dog"
116
+ from_db.people.first.pets[1].name.should == "Koda"
117
+ from_db.people.first.pets[1].species.should == "Dog"
118
+ end
119
+
120
+ should "create a reference to the root document for all embedded documents before save" do
121
+ meg = Person.new(:name => "Meg")
122
+ sparky = Pet.new(:name => "Sparky", :species => "Dog")
123
+
124
+ doc = @document.new
125
+
126
+ doc.people << meg
127
+ meg.pets << sparky
128
+
129
+ doc.people.first._root_document.should == doc
130
+ doc.people.first.pets.first._root_document.should == doc
131
+ end
132
+
133
+ should "create properly-named reference to parent document when building off association proxy" do
134
+ person = RealPerson.new
135
+ pet = person.pets.build
136
+ person.should == pet.real_person
137
+ end
138
+
139
+
140
+ should "create a reference to the root document for all embedded documents" do
141
+ meg = Person.new(:name => "Meg")
142
+ sparky = Pet.new(:name => "Sparky", :species => "Dog")
143
+
144
+ doc = @document.new
145
+
146
+ meg.pets << sparky
147
+
148
+ doc.people << meg
149
+ doc.save
150
+
151
+ from_db = @document.find(doc.id)
152
+ from_db.people.first._root_document.should == doc
153
+ from_db.people.first.pets.first._root_document.should == doc
154
+ end
155
+ end
156
+
157
+ should "allow retrieval via find(:all)" do
158
+ meg = Person.new(:name => "Meg")
159
+ sparky = Pet.new(:name => "Sparky", :species => "Dog")
160
+
161
+ meg.pets << sparky
162
+
163
+ meg.pets.find(:all).should include(sparky)
164
+ end
165
+
166
+ should "allow retrieval via find(id)" do
167
+ meg = Person.new(:name => "Meg")
168
+ sparky = Pet.new(:name => "Sparky", :species => "Dog")
169
+
170
+ meg.pets << sparky
171
+
172
+ meg.pets.find(sparky.id).should == sparky
173
+ end
174
+ end