drogus-mongo_mapper 0.6.10
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 +10 -0
- data/LICENSE +20 -0
- data/README.rdoc +29 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/mmconsole +60 -0
- data/lib/mongo_mapper.rb +131 -0
- data/lib/mongo_mapper/document.rb +417 -0
- data/lib/mongo_mapper/embedded_document.rb +55 -0
- data/lib/mongo_mapper/finder_options.rb +127 -0
- data/lib/mongo_mapper/plugins.rb +30 -0
- data/lib/mongo_mapper/plugins/associations.rb +104 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +134 -0
- data/lib/mongo_mapper/plugins/clone.rb +13 -0
- data/lib/mongo_mapper/plugins/descendants.rb +16 -0
- data/lib/mongo_mapper/plugins/dirty.rb +119 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +324 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +85 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +105 -0
- data/lib/mongo_mapper/plugins/validations.rb +57 -0
- data/lib/mongo_mapper/support.rb +217 -0
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
- data/lib/mongo_mapper/support/find.rb +77 -0
- data/mongo_mapper.gemspec +195 -0
- data/performance/read_write.rb +52 -0
- data/specs.watchr +51 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
- data/test/functional/associations/test_in_array_proxy.rb +309 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
- data/test/functional/associations/test_many_documents_proxy.rb +431 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
- data/test/functional/associations/test_one_proxy.rb +161 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_callbacks.rb +81 -0
- data/test/functional/test_dirty.rb +163 -0
- data/test/functional/test_document.rb +1264 -0
- data/test/functional/test_embedded_document.rb +125 -0
- data/test/functional/test_identity_map.rb +508 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +252 -0
- data/test/functional/test_pagination.rb +93 -0
- data/test/functional/test_protected.rb +155 -0
- data/test/functional/test_string_id_compatibility.rb +67 -0
- data/test/functional/test_validations.rb +329 -0
- data/test/models.rb +232 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/support/timing.rb +16 -0
- data/test/test_helper.rb +60 -0
- data/test/unit/associations/test_base.rb +207 -0
- data/test/unit/associations/test_proxy.rb +105 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +231 -0
- data/test/unit/test_dynamic_finder.rb +123 -0
- data/test/unit/test_embedded_document.rb +663 -0
- data/test/unit/test_finder_options.rb +329 -0
- data/test/unit/test_keys.rb +169 -0
- data/test/unit/test_mongo_mapper.rb +65 -0
- data/test/unit/test_pagination.rb +127 -0
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/test_rails_compatibility.rb +52 -0
- data/test/unit/test_serialization.rb +51 -0
- data/test/unit/test_support.rb +354 -0
- data/test/unit/test_time_zones.rb +39 -0
- data/test/unit/test_validations.rb +544 -0
- metadata +290 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class StringIdCompatibilityTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@note_class = EDoc do
|
6
|
+
key :_id, String
|
7
|
+
end
|
8
|
+
|
9
|
+
@task_class = Doc do
|
10
|
+
key :_id, String
|
11
|
+
key :project_id, String
|
12
|
+
belongs_to :project
|
13
|
+
end
|
14
|
+
|
15
|
+
@project_class = Doc do
|
16
|
+
include MongoMapper::Document
|
17
|
+
key :_id, String
|
18
|
+
end
|
19
|
+
|
20
|
+
@task_class.belongs_to :project, :class => @project_class
|
21
|
+
@project_class.many :notes, :class => @note_class
|
22
|
+
@project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id', :order => :position.asc
|
23
|
+
end
|
24
|
+
|
25
|
+
should "assign correct _id for documents" do
|
26
|
+
project = @project_class.create
|
27
|
+
project._id.should == project.id
|
28
|
+
project._id.should be_instance_of(String)
|
29
|
+
project.id.size.should == 24
|
30
|
+
lambda {
|
31
|
+
Mongo::ObjectID.from_string(project.id)
|
32
|
+
}.should_not raise_error
|
33
|
+
end
|
34
|
+
|
35
|
+
should "assign correct _id for embedded documents" do
|
36
|
+
note = @note_class.new
|
37
|
+
note.id.should == note._id
|
38
|
+
note.id.size.should == 24
|
39
|
+
end
|
40
|
+
|
41
|
+
should "find records" do
|
42
|
+
project = @project_class.create
|
43
|
+
@project_class.find(project.id).should == project
|
44
|
+
end
|
45
|
+
|
46
|
+
should "save embedded docs" do
|
47
|
+
n1 = @note_class.new
|
48
|
+
n2 = @note_class.new
|
49
|
+
n3 = @note_class.new
|
50
|
+
project = @project_class.create(:notes => [n1, n2, n3])
|
51
|
+
|
52
|
+
project = project.reload
|
53
|
+
project.notes.size.should == 3
|
54
|
+
project.notes.should == [n1, n2, n3]
|
55
|
+
end
|
56
|
+
|
57
|
+
should "be able to associate records" do
|
58
|
+
t1 = @task_class.new(:body => 'First task', :position => 1)
|
59
|
+
t2 = @task_class.new(:body => 'Second task', :position => 2)
|
60
|
+
t3 = @task_class.new(:body => 'Third task', :position => 3)
|
61
|
+
project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
|
62
|
+
|
63
|
+
project = project.reload
|
64
|
+
project.tasks.count.should == 3
|
65
|
+
project.tasks.should == [t1, t2, t3]
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,329 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ValidationsTest < Test::Unit::TestCase
|
4
|
+
context "Saving a new document that is invalid" do
|
5
|
+
setup do
|
6
|
+
@document = Doc do
|
7
|
+
key :name, String, :required => true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not insert document" do
|
12
|
+
doc = @document.new
|
13
|
+
doc.save
|
14
|
+
@document.count.should == 0
|
15
|
+
end
|
16
|
+
|
17
|
+
should "populate document's errors" do
|
18
|
+
doc = @document.new
|
19
|
+
doc.errors.size.should == 0
|
20
|
+
doc.save
|
21
|
+
doc.errors.full_messages.should == ["Name can't be empty"]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "Saving a document that is invalid (destructive)" do
|
26
|
+
setup do
|
27
|
+
@document = Doc do
|
28
|
+
key :name, String, :required => true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
should "raise error" do
|
33
|
+
doc = @document.new
|
34
|
+
lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "Creating a document that is invalid (destructive)" do
|
39
|
+
setup do
|
40
|
+
@document = Doc do
|
41
|
+
key :name, String, :required => true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
should "raise error" do
|
46
|
+
lambda { @document.create! }.should raise_error(MongoMapper::DocumentNotValid)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "create a new document" do
|
50
|
+
instance = @document.create!(:name => "James")
|
51
|
+
instance.new_record?.should be_false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "Saving an existing document that is invalid" do
|
56
|
+
setup do
|
57
|
+
@document = Doc do
|
58
|
+
key :name, String, :required => true
|
59
|
+
end
|
60
|
+
|
61
|
+
@doc = @document.create(:name => 'John Nunemaker')
|
62
|
+
end
|
63
|
+
|
64
|
+
should "not update document" do
|
65
|
+
@doc.name = nil
|
66
|
+
@doc.save
|
67
|
+
@doc.reload.name.should == 'John Nunemaker'
|
68
|
+
end
|
69
|
+
|
70
|
+
should "populate document's errors" do
|
71
|
+
@doc.name = nil
|
72
|
+
@doc.save
|
73
|
+
@doc.errors.full_messages.should == ["Name can't be empty"]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "Adding validation errors" do
|
78
|
+
setup do
|
79
|
+
@document = Doc do
|
80
|
+
key :action, String
|
81
|
+
def action_present
|
82
|
+
errors.add(:action, 'is invalid') if action.blank?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
should "work with validate_on_create callback" do
|
88
|
+
@document.validate_on_create :action_present
|
89
|
+
|
90
|
+
doc = @document.new
|
91
|
+
doc.action = nil
|
92
|
+
doc.should have_error_on(:action)
|
93
|
+
|
94
|
+
doc.action = 'kick'
|
95
|
+
doc.should_not have_error_on(:action)
|
96
|
+
doc.save
|
97
|
+
|
98
|
+
doc.action = nil
|
99
|
+
doc.should_not have_error_on(:action)
|
100
|
+
end
|
101
|
+
|
102
|
+
should "work with validate_on_update callback" do
|
103
|
+
@document.validate_on_update :action_present
|
104
|
+
|
105
|
+
doc = @document.new
|
106
|
+
doc.action = nil
|
107
|
+
doc.should_not have_error_on(:action)
|
108
|
+
doc.save
|
109
|
+
|
110
|
+
doc.action = nil
|
111
|
+
doc.should have_error_on(:action)
|
112
|
+
|
113
|
+
doc.action = 'kick'
|
114
|
+
doc.should_not have_error_on(:action)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "validating uniqueness of" do
|
119
|
+
setup do
|
120
|
+
@document = Doc do
|
121
|
+
key :name, String
|
122
|
+
validates_uniqueness_of :name
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
should "not fail if object is new" do
|
127
|
+
doc = @document.new
|
128
|
+
doc.should_not have_error_on(:name)
|
129
|
+
end
|
130
|
+
|
131
|
+
should "not fail when new object is out of scope" do
|
132
|
+
document = Doc do
|
133
|
+
key :name
|
134
|
+
key :adult
|
135
|
+
validates_uniqueness_of :name, :scope => :adult
|
136
|
+
end
|
137
|
+
doc = document.new("name" => "joe", :adult => true)
|
138
|
+
doc.save.should be_true
|
139
|
+
|
140
|
+
doc2 = document.new("name" => "joe", :adult => false)
|
141
|
+
doc2.should be_valid
|
142
|
+
end
|
143
|
+
|
144
|
+
should "allow to update an object" do
|
145
|
+
doc = @document.new("name" => "joe")
|
146
|
+
doc.save.should be_true
|
147
|
+
|
148
|
+
@document \
|
149
|
+
.stubs(:first) \
|
150
|
+
.with(:name => 'joe') \
|
151
|
+
.returns(doc)
|
152
|
+
|
153
|
+
doc.name = "joe"
|
154
|
+
doc.valid?.should be_true
|
155
|
+
doc.should_not have_error_on(:name)
|
156
|
+
end
|
157
|
+
|
158
|
+
should "fail if object name is not unique" do
|
159
|
+
doc = @document.new("name" => "joe")
|
160
|
+
doc.save.should be_true
|
161
|
+
|
162
|
+
@document \
|
163
|
+
.stubs(:first) \
|
164
|
+
.with(:name => 'joe') \
|
165
|
+
.returns(doc)
|
166
|
+
|
167
|
+
doc2 = @document.new("name" => "joe")
|
168
|
+
doc2.should have_error_on(:name)
|
169
|
+
end
|
170
|
+
|
171
|
+
should "allow multiple blank entries if :allow_blank => true" do
|
172
|
+
document = Doc do
|
173
|
+
key :name
|
174
|
+
validates_uniqueness_of :name, :allow_blank => :true
|
175
|
+
end
|
176
|
+
|
177
|
+
doc = document.new("name" => "")
|
178
|
+
doc.save.should be_true
|
179
|
+
|
180
|
+
document \
|
181
|
+
.stubs(:first) \
|
182
|
+
.with(:name => '') \
|
183
|
+
.returns(doc)
|
184
|
+
|
185
|
+
doc2 = document.new("name" => "")
|
186
|
+
doc2.should_not have_error_on(:name)
|
187
|
+
end
|
188
|
+
|
189
|
+
should "allow multiple nil entries if :allow_nil => true" do
|
190
|
+
document = Doc do
|
191
|
+
key :name
|
192
|
+
validates_uniqueness_of :name, :allow_nil => :true
|
193
|
+
end
|
194
|
+
|
195
|
+
doc = document.new('name' => nil)
|
196
|
+
doc.save.should be_true
|
197
|
+
|
198
|
+
doc2 = document.new('name' => nil)
|
199
|
+
doc2.should_not have_error_on(:name)
|
200
|
+
end
|
201
|
+
|
202
|
+
should "allow entries that differ only in case by default" do
|
203
|
+
document = Doc do
|
204
|
+
key :name
|
205
|
+
validates_uniqueness_of :name
|
206
|
+
end
|
207
|
+
|
208
|
+
doc = document.new("name" => "BLAMMO")
|
209
|
+
doc.save.should be_true
|
210
|
+
|
211
|
+
doc2 = document.new("name" => "blammo")
|
212
|
+
doc2.should_not have_error_on(:name)
|
213
|
+
end
|
214
|
+
|
215
|
+
context "with :case_sensitive => false" do
|
216
|
+
setup do
|
217
|
+
@document = Doc do
|
218
|
+
key :name
|
219
|
+
validates_uniqueness_of :name, :case_sensitive => false
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
should "fail on entries that differ only in case" do
|
224
|
+
doc = @document.new("name" => "BLAMMO")
|
225
|
+
doc.save.should be_true
|
226
|
+
|
227
|
+
doc2 = @document.new("name" => "blammo")
|
228
|
+
doc2.should have_error_on(:name)
|
229
|
+
end
|
230
|
+
|
231
|
+
should "not raise an error if value is nil" do
|
232
|
+
doc = @document.new("name" => nil)
|
233
|
+
lambda { doc.valid? }.should_not raise_error
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "scoped by a single attribute" do
|
238
|
+
setup do
|
239
|
+
@document = Doc do
|
240
|
+
key :name, String
|
241
|
+
key :scope, String
|
242
|
+
validates_uniqueness_of :name, :scope => :scope
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
should "fail if the same name exists in the scope" do
|
247
|
+
doc = @document.new("name" => "joe", "scope" => "one")
|
248
|
+
doc.save.should be_true
|
249
|
+
|
250
|
+
@document \
|
251
|
+
.stubs(:first) \
|
252
|
+
.with(:name => 'joe', :scope => "one") \
|
253
|
+
.returns(doc)
|
254
|
+
|
255
|
+
doc2 = @document.new("name" => "joe", "scope" => "one")
|
256
|
+
doc2.should have_error_on(:name)
|
257
|
+
end
|
258
|
+
|
259
|
+
should "pass if the same name exists in a different scope" do
|
260
|
+
doc = @document.new("name" => "joe", "scope" => "one")
|
261
|
+
doc.save.should be_true
|
262
|
+
|
263
|
+
@document \
|
264
|
+
.stubs(:first) \
|
265
|
+
.with(:name => 'joe', :scope => 'two') \
|
266
|
+
.returns(nil)
|
267
|
+
|
268
|
+
doc2 = @document.new("name" => "joe", "scope" => "two")
|
269
|
+
doc2.should_not have_error_on(:name)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "scoped by a multiple attributes" do
|
274
|
+
setup do
|
275
|
+
@document = Doc do
|
276
|
+
key :name, String
|
277
|
+
key :first_scope, String
|
278
|
+
key :second_scope, String
|
279
|
+
validates_uniqueness_of :name, :scope => [:first_scope, :second_scope]
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
should "fail if the same name exists in the scope" do
|
284
|
+
doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
285
|
+
doc.save.should be_true
|
286
|
+
|
287
|
+
@document \
|
288
|
+
.stubs(:first) \
|
289
|
+
.with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
|
290
|
+
.returns(doc)
|
291
|
+
|
292
|
+
doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
293
|
+
doc2.should have_error_on(:name)
|
294
|
+
end
|
295
|
+
|
296
|
+
should "pass if the same name exists in a different scope" do
|
297
|
+
doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
298
|
+
doc.save.should be_true
|
299
|
+
|
300
|
+
@document \
|
301
|
+
.stubs(:first) \
|
302
|
+
.with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
|
303
|
+
.returns(nil)
|
304
|
+
|
305
|
+
doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
|
306
|
+
doc2.should_not have_error_on(:name)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context "validates uniqueness of with :unique shortcut" do
|
312
|
+
should "work" do
|
313
|
+
@document = Doc do
|
314
|
+
key :name, String, :unique => true
|
315
|
+
end
|
316
|
+
|
317
|
+
doc = @document.create(:name => 'John')
|
318
|
+
doc.should_not have_error_on(:name)
|
319
|
+
|
320
|
+
@document \
|
321
|
+
.stubs(:first) \
|
322
|
+
.with(:name => 'John') \
|
323
|
+
.returns(doc)
|
324
|
+
|
325
|
+
second_john = @document.create(:name => 'John')
|
326
|
+
second_john.should have_error_on(:name, 'has already been taken')
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
data/test/models.rb
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
# custom type
|
2
|
+
class WindowSize
|
3
|
+
attr_reader :width, :height
|
4
|
+
|
5
|
+
def self.to_mongo(value)
|
6
|
+
value.to_a
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.from_mongo(value)
|
10
|
+
value.is_a?(self) ? value : WindowSize.new(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
@width, @height = args.flatten
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_a
|
18
|
+
[width, height]
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
other.is_a?(self.class) && other.width == width && other.height == height
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module AccountsExtensions
|
27
|
+
def inactive
|
28
|
+
all(:last_logged_in => nil)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Post
|
33
|
+
include MongoMapper::Document
|
34
|
+
|
35
|
+
key :title, String
|
36
|
+
key :body, String
|
37
|
+
|
38
|
+
many :comments, :as => :commentable, :class_name => 'PostComment'
|
39
|
+
|
40
|
+
timestamps!
|
41
|
+
end
|
42
|
+
|
43
|
+
class PostComment
|
44
|
+
include MongoMapper::Document
|
45
|
+
|
46
|
+
key :username, String, :default => 'Anonymous'
|
47
|
+
key :body, String
|
48
|
+
|
49
|
+
key :commentable_id, ObjectId
|
50
|
+
key :commentable_type, String
|
51
|
+
belongs_to :commentable, :polymorphic => true
|
52
|
+
|
53
|
+
timestamps!
|
54
|
+
end
|
55
|
+
|
56
|
+
class Address
|
57
|
+
include MongoMapper::EmbeddedDocument
|
58
|
+
|
59
|
+
key :address, String
|
60
|
+
key :city, String
|
61
|
+
key :state, String
|
62
|
+
key :zip, Integer
|
63
|
+
end
|
64
|
+
|
65
|
+
class Message
|
66
|
+
include MongoMapper::Document
|
67
|
+
|
68
|
+
key :body, String
|
69
|
+
key :position, Integer
|
70
|
+
key :_type, String
|
71
|
+
key :room_id, ObjectId
|
72
|
+
|
73
|
+
belongs_to :room
|
74
|
+
end
|
75
|
+
|
76
|
+
class Enter < Message; end
|
77
|
+
class Exit < Message; end
|
78
|
+
class Chat < Message; end
|
79
|
+
|
80
|
+
class Room
|
81
|
+
include MongoMapper::Document
|
82
|
+
|
83
|
+
key :name, String
|
84
|
+
many :messages, :polymorphic => true, :order => 'position' do
|
85
|
+
def older
|
86
|
+
all(:position => {'$gt' => 5})
|
87
|
+
end
|
88
|
+
end
|
89
|
+
many :latest_messages, :class_name => 'Message', :order => 'position desc', :limit => 2
|
90
|
+
|
91
|
+
many :accounts, :polymorphic => true, :extend => AccountsExtensions
|
92
|
+
end
|
93
|
+
|
94
|
+
class Account
|
95
|
+
include MongoMapper::Document
|
96
|
+
|
97
|
+
key :_type, String
|
98
|
+
key :room_id, ObjectId
|
99
|
+
key :last_logged_in, Time
|
100
|
+
|
101
|
+
belongs_to :room
|
102
|
+
end
|
103
|
+
class AccountUser < Account; end
|
104
|
+
class Bot < Account; end
|
105
|
+
|
106
|
+
class Answer
|
107
|
+
include MongoMapper::Document
|
108
|
+
|
109
|
+
key :body, String
|
110
|
+
end
|
111
|
+
|
112
|
+
module CollaboratorsExtensions
|
113
|
+
def top
|
114
|
+
first
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Project
|
119
|
+
include MongoMapper::Document
|
120
|
+
|
121
|
+
key :name, String
|
122
|
+
|
123
|
+
many :collaborators, :extend => CollaboratorsExtensions
|
124
|
+
many :statuses, :order => 'position' do
|
125
|
+
def open
|
126
|
+
all(:name => %w(New Assigned))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
many :addresses do
|
131
|
+
def find_all_by_state(state)
|
132
|
+
# can't use select here for some reason
|
133
|
+
find_all { |a| a.state == state }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Collaborator
|
139
|
+
include MongoMapper::Document
|
140
|
+
key :project_id, ObjectId
|
141
|
+
key :name, String
|
142
|
+
belongs_to :project
|
143
|
+
end
|
144
|
+
|
145
|
+
class Status
|
146
|
+
include MongoMapper::Document
|
147
|
+
|
148
|
+
key :project_id, ObjectId
|
149
|
+
key :target_id, ObjectId
|
150
|
+
key :target_type, String
|
151
|
+
key :name, String, :required => true
|
152
|
+
key :position, Integer
|
153
|
+
|
154
|
+
belongs_to :project
|
155
|
+
belongs_to :target, :polymorphic => true
|
156
|
+
end
|
157
|
+
|
158
|
+
class Media
|
159
|
+
include MongoMapper::EmbeddedDocument
|
160
|
+
|
161
|
+
key :_type, String
|
162
|
+
key :file, String
|
163
|
+
|
164
|
+
key :visible, Boolean
|
165
|
+
end
|
166
|
+
|
167
|
+
class Video < Media
|
168
|
+
key :length, Integer
|
169
|
+
end
|
170
|
+
|
171
|
+
class Image < Media
|
172
|
+
key :width, Integer
|
173
|
+
key :height, Integer
|
174
|
+
end
|
175
|
+
|
176
|
+
class Music < Media
|
177
|
+
key :bitrate, String
|
178
|
+
end
|
179
|
+
|
180
|
+
class Catalog
|
181
|
+
include MongoMapper::Document
|
182
|
+
|
183
|
+
many :medias, :polymorphic => true do
|
184
|
+
def visible
|
185
|
+
# for some reason we can't use select here
|
186
|
+
find_all { |m| m.visible? }
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
module TrModels
|
192
|
+
class Transport
|
193
|
+
include MongoMapper::EmbeddedDocument
|
194
|
+
|
195
|
+
key :_type, String
|
196
|
+
key :license_plate, String
|
197
|
+
key :purchased_on, Date
|
198
|
+
end
|
199
|
+
|
200
|
+
class Car < TrModels::Transport
|
201
|
+
include MongoMapper::EmbeddedDocument
|
202
|
+
|
203
|
+
key :model, String
|
204
|
+
key :year, Integer
|
205
|
+
end
|
206
|
+
|
207
|
+
class Bus < TrModels::Transport
|
208
|
+
include MongoMapper::EmbeddedDocument
|
209
|
+
|
210
|
+
key :max_passengers, Integer
|
211
|
+
end
|
212
|
+
|
213
|
+
class Ambulance < TrModels::Transport
|
214
|
+
include MongoMapper::EmbeddedDocument
|
215
|
+
|
216
|
+
key :icu, Boolean
|
217
|
+
end
|
218
|
+
|
219
|
+
class Fleet
|
220
|
+
include MongoMapper::Document
|
221
|
+
|
222
|
+
module TransportsExtension
|
223
|
+
def to_be_replaced
|
224
|
+
# for some reason we can't use select
|
225
|
+
find_all { |t| t.purchased_on < 2.years.ago.to_date }
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
many :transports, :polymorphic => true, :class_name => "TrModels::Transport", :extend => TransportsExtension
|
230
|
+
key :name, String
|
231
|
+
end
|
232
|
+
end
|