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.
- data/.gitignore +8 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +87 -0
- data/VERSION +1 -0
- data/bin/mmconsole +55 -0
- data/lib/mongo_mapper/associations/base.rb +83 -0
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +22 -0
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +27 -0
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +116 -0
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +67 -0
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
- data/lib/mongo_mapper/associations/many_proxy.rb +6 -0
- data/lib/mongo_mapper/associations/proxy.rb +74 -0
- data/lib/mongo_mapper/associations.rb +86 -0
- data/lib/mongo_mapper/callbacks.rb +106 -0
- data/lib/mongo_mapper/document.rb +308 -0
- data/lib/mongo_mapper/dynamic_finder.rb +35 -0
- data/lib/mongo_mapper/embedded_document.rb +354 -0
- data/lib/mongo_mapper/finder_options.rb +94 -0
- data/lib/mongo_mapper/key.rb +32 -0
- data/lib/mongo_mapper/observing.rb +50 -0
- data/lib/mongo_mapper/pagination.rb +51 -0
- data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
- data/lib/mongo_mapper/save_with_validation.rb +19 -0
- data/lib/mongo_mapper/serialization.rb +55 -0
- data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
- data/lib/mongo_mapper/support.rb +171 -0
- data/lib/mongo_mapper/validations.rb +69 -0
- data/lib/mongo_mapper.rb +95 -0
- data/mongo_mapper.gemspec +156 -0
- data/specs.watchr +32 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/custom_matchers.rb +48 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +49 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +244 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +132 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +174 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +297 -0
- data/test/functional/associations/test_many_proxy.rb +331 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +18 -0
- data/test/functional/test_callbacks.rb +85 -0
- data/test/functional/test_document.rb +964 -0
- data/test/functional/test_embedded_document.rb +97 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_pagination.rb +87 -0
- data/test/functional/test_rails_compatibility.rb +30 -0
- data/test/functional/test_validations.rb +279 -0
- data/test/models.rb +169 -0
- data/test/test_helper.rb +30 -0
- data/test/unit/serializers/test_json_serializer.rb +193 -0
- data/test/unit/test_association_base.rb +144 -0
- data/test/unit/test_document.rb +165 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +643 -0
- data/test/unit/test_finder_options.rb +193 -0
- data/test/unit/test_key.rb +175 -0
- data/test/unit/test_mongomapper.rb +28 -0
- data/test/unit/test_observing.rb +101 -0
- data/test/unit/test_pagination.rb +109 -0
- data/test/unit/test_rails_compatibility.rb +39 -0
- data/test/unit/test_serializations.rb +52 -0
- data/test/unit/test_support.rb +272 -0
- data/test/unit/test_time_zones.rb +40 -0
- data/test/unit/test_validations.rb +503 -0
- 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
|