mongo_odm 0.1.8
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/Gemfile +11 -0
- data/LICENSE +20 -0
- data/README.rdoc +251 -0
- data/Rakefile +70 -0
- data/lib/mongo_odm.rb +48 -0
- data/lib/mongo_odm/collection.rb +42 -0
- data/lib/mongo_odm/core_ext/conversions.rb +262 -0
- data/lib/mongo_odm/cursor.rb +11 -0
- data/lib/mongo_odm/document.rb +34 -0
- data/lib/mongo_odm/document/associations.rb +39 -0
- data/lib/mongo_odm/document/associations/has_many.rb +19 -0
- data/lib/mongo_odm/document/associations/has_one.rb +19 -0
- data/lib/mongo_odm/document/attribute_methods.rb +103 -0
- data/lib/mongo_odm/document/attribute_methods/dirty.rb +51 -0
- data/lib/mongo_odm/document/attribute_methods/localization.rb +67 -0
- data/lib/mongo_odm/document/attribute_methods/query.rb +35 -0
- data/lib/mongo_odm/document/attribute_methods/read.rb +39 -0
- data/lib/mongo_odm/document/attribute_methods/write.rb +37 -0
- data/lib/mongo_odm/document/callbacks.rb +29 -0
- data/lib/mongo_odm/document/fields.rb +66 -0
- data/lib/mongo_odm/document/inspect.rb +28 -0
- data/lib/mongo_odm/document/persistence.rb +96 -0
- data/lib/mongo_odm/document/validations.rb +46 -0
- data/lib/mongo_odm/errors.rb +18 -0
- data/lib/mongo_odm/version.rb +7 -0
- data/spec/models/00-blank_slate.rb +4 -0
- data/spec/models/01-shape.rb +8 -0
- data/spec/models/02-circle.rb +7 -0
- data/spec/models/03-big_red_circle.rb +8 -0
- data/spec/mongo_odm/core_ext/conversions_spec.rb +423 -0
- data/spec/mongo_odm/document/fields_spec.rb +187 -0
- data/spec/mongo_odm/document/inspect_spec.rb +19 -0
- data/spec/mongo_odm/document_spec.rb +12 -0
- data/spec/mongo_odm/mongo_odm_spec.rb +84 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +12 -0
- metadata +185 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'active_support/core_ext/module/aliasing'
|
3
|
+
|
4
|
+
module MongoODM
|
5
|
+
module Document
|
6
|
+
module Validations
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include ActiveModel::Validations
|
12
|
+
|
13
|
+
alias_method_chain :save, :validation
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
# The validation process on save can be skipped by passing false. The regular Base#save method is
|
18
|
+
# replaced with this when the validations module is mixed in, which it is by default.
|
19
|
+
def save_with_validation(options=nil)
|
20
|
+
perform_validation = case options
|
21
|
+
when NilClass
|
22
|
+
true
|
23
|
+
when Hash
|
24
|
+
options[:validate] != false
|
25
|
+
end
|
26
|
+
|
27
|
+
if perform_validation && valid? || !perform_validation
|
28
|
+
save_without_validation
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Runs all the specified validations and returns true if no errors were added otherwise false.
|
35
|
+
def valid?
|
36
|
+
errors.clear
|
37
|
+
|
38
|
+
_run_validate_callbacks
|
39
|
+
|
40
|
+
errors.empty?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module MongoODM
|
3
|
+
|
4
|
+
module Errors
|
5
|
+
class TypeCastMissing < StandardError
|
6
|
+
def initialize(value, klass)
|
7
|
+
super "can't convert #{value.inspect} to #{klass}: Define a `type_cast' method for #{value.class}:#{value.class.class}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class InvalidLocalizedField < StandardError
|
12
|
+
def initialize(field_name, klass)
|
13
|
+
super "can't localize field #{field_name}; it has to be declared as a Hash, was #{klass}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,423 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe "Conversions" do
|
5
|
+
|
6
|
+
describe Array do
|
7
|
+
|
8
|
+
describe ".type_cast" do
|
9
|
+
|
10
|
+
it "returns nil when called with nil" do
|
11
|
+
Array.type_cast(nil).should == nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "tries to convert any other value to an array" do
|
15
|
+
Array.type_cast({:a => 1, :b => 2}).should == [[:a, 1], [:b, 2]]
|
16
|
+
Array.type_cast([1, 2]).should == [1, 2]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#to_mongo" do
|
22
|
+
|
23
|
+
it "tries to instanciate each of its elements sending MongoODM.instanciate to its classes" do
|
24
|
+
num = 1
|
25
|
+
float = 2.3
|
26
|
+
string = "test"
|
27
|
+
time = Time.now
|
28
|
+
klass = Shape.new
|
29
|
+
[num, float, string, time, klass].each{|i| i.should_receive(:to_mongo).once }
|
30
|
+
[num, float, string, time, klass].to_mongo
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Class do
|
38
|
+
|
39
|
+
describe ".type_cast" do
|
40
|
+
|
41
|
+
it "returns nil when called with nil" do
|
42
|
+
Class.type_cast(nil).should == nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "tries to constantize to a class when called with any other value" do
|
46
|
+
Class.type_cast("Shape").should == Shape
|
47
|
+
Class.type_cast("Class").should == Class
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#to_mongo" do
|
53
|
+
|
54
|
+
it "returns the string representation of the class name" do
|
55
|
+
Class.to_mongo.should == "Class"
|
56
|
+
Shape.to_mongo.should == "Shape"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Symbol do
|
64
|
+
|
65
|
+
describe ".type_cast" do
|
66
|
+
|
67
|
+
it "returns nil when called with nil" do
|
68
|
+
Symbol.type_cast(nil).should == nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "tries to convert any other value to a symbol" do
|
72
|
+
Symbol.type_cast("test").should == :test
|
73
|
+
Symbol.type_cast([1, 2]).should == :"[1, 2]"
|
74
|
+
Symbol.type_cast({:a => 1, :b => 2}).should == :"{:a=>1, :b=>2}"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#to_mongo" do
|
80
|
+
|
81
|
+
it "returns itself" do
|
82
|
+
@test = :test
|
83
|
+
@test.to_mongo.should == @test
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe String do
|
91
|
+
|
92
|
+
describe ".type_cast" do
|
93
|
+
|
94
|
+
it "returns nil when called with nil" do
|
95
|
+
String.type_cast(nil).should == nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "tries to convert any other value to a string" do
|
99
|
+
String.type_cast(:test).should == "test"
|
100
|
+
String.type_cast([1, 2]).should == "[1, 2]"
|
101
|
+
String.type_cast({:a => 1, :b => 2}).should == "{:a=>1, :b=>2}"
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#to_mongo" do
|
107
|
+
|
108
|
+
it "returns itself" do
|
109
|
+
@test = "test"
|
110
|
+
@test.to_mongo.should == @test
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe Integer do
|
118
|
+
|
119
|
+
describe ".type_cast" do
|
120
|
+
|
121
|
+
it "returns nil when called with nil" do
|
122
|
+
Integer.type_cast(nil).should == nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it "tries to convert any other value to an integer" do
|
126
|
+
Integer.type_cast(2.2).should == 2
|
127
|
+
Integer.type_cast("23.2").should == 23
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#to_mongo" do
|
133
|
+
|
134
|
+
it "returns itself" do
|
135
|
+
@test = 2
|
136
|
+
@test.to_mongo.should == @test
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
describe Float do
|
144
|
+
|
145
|
+
describe ".type_cast" do
|
146
|
+
|
147
|
+
it "returns nil when called with nil" do
|
148
|
+
Float.type_cast(nil).should == nil
|
149
|
+
end
|
150
|
+
|
151
|
+
it "tries to convert any other value to a float" do
|
152
|
+
Float.type_cast(2).should == 2.0
|
153
|
+
Float.type_cast("23.2").should == 23.2
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "#to_mongo" do
|
159
|
+
|
160
|
+
it "returns itself" do
|
161
|
+
@test = 2.23
|
162
|
+
@test.to_mongo.should == @test
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
describe BigDecimal do
|
170
|
+
|
171
|
+
describe ".type_cast" do
|
172
|
+
|
173
|
+
it "returns nil when called with nil" do
|
174
|
+
BigDecimal.type_cast(nil).should == nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it "tries to convert any other value to a big decimal" do
|
178
|
+
BigDecimal.type_cast(2).should == BigDecimal.new("2")
|
179
|
+
BigDecimal.type_cast("23.2").should == BigDecimal.new("23.2")
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "#to_mongo" do
|
185
|
+
|
186
|
+
it "returns the string representation of the value" do
|
187
|
+
@test = BigDecimal.new("3.14159265358979323846")
|
188
|
+
@test.to_mongo.should == "3.14159265358979323846"
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
describe Date do
|
196
|
+
|
197
|
+
describe ".type_cast" do
|
198
|
+
|
199
|
+
it "returns nil when called with nil" do
|
200
|
+
Date.type_cast(nil).should == nil
|
201
|
+
end
|
202
|
+
|
203
|
+
it "tries to convert any other value to a date" do
|
204
|
+
Date.type_cast("1/2/1980").should == Date.new(1980, 2, 1)
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "#to_mongo" do
|
210
|
+
|
211
|
+
it "returns a UTC Time object for the date" do
|
212
|
+
@test = Date.new(1980, 2, 1)
|
213
|
+
@test.to_mongo.should == Time.utc(1980, 2, 1)
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
describe DateTime do
|
221
|
+
|
222
|
+
describe ".type_cast" do
|
223
|
+
|
224
|
+
it "returns nil when called with nil" do
|
225
|
+
DateTime.type_cast(nil).should == nil
|
226
|
+
end
|
227
|
+
|
228
|
+
it "tries to convert any other value to a date" do
|
229
|
+
DateTime.type_cast("1/2/1980 11:30").should == DateTime.new(1980, 2, 1, 11, 30)
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
describe "#to_mongo" do
|
235
|
+
|
236
|
+
it "returns a UTC Time object for the datetime" do
|
237
|
+
@test = DateTime.new(1980, 2, 1, 11, 30)
|
238
|
+
@test.to_mongo.should == Time.utc(1980, 2, 1, 11, 30)
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
describe TrueClass do
|
246
|
+
|
247
|
+
describe ".type_cast" do
|
248
|
+
|
249
|
+
it "returns nil when called with nil" do
|
250
|
+
TrueClass.type_cast(nil).should == nil
|
251
|
+
end
|
252
|
+
|
253
|
+
it "returns true when called with any other value" do
|
254
|
+
TrueClass.type_cast(true).should == true
|
255
|
+
TrueClass.type_cast(false).should == true
|
256
|
+
TrueClass.type_cast(3).should == true
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
describe "#to_mongo" do
|
262
|
+
|
263
|
+
it "returns true" do
|
264
|
+
true.to_mongo.should == true
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
end
|
270
|
+
|
271
|
+
describe FalseClass do
|
272
|
+
|
273
|
+
describe ".type_cast" do
|
274
|
+
|
275
|
+
it "returns nil when called with nil" do
|
276
|
+
FalseClass.type_cast(nil).should == nil
|
277
|
+
end
|
278
|
+
|
279
|
+
it "returns false when called with any other value" do
|
280
|
+
FalseClass.type_cast(false).should == false
|
281
|
+
FalseClass.type_cast(true).should == false
|
282
|
+
FalseClass.type_cast(3).should == false
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
describe "#to_mongo" do
|
288
|
+
|
289
|
+
it "returns false" do
|
290
|
+
false.to_mongo.should == false
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
describe Time do
|
298
|
+
|
299
|
+
describe ".type_cast" do
|
300
|
+
|
301
|
+
it "returns nil when called with nil" do
|
302
|
+
Time.type_cast(nil).should == nil
|
303
|
+
end
|
304
|
+
|
305
|
+
it "tries to convert any other value to a date" do
|
306
|
+
Time.type_cast("1/2/1980 11:30").should == Time.utc(1980, 2, 1, 11, 30)
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
describe "#to_mongo" do
|
312
|
+
|
313
|
+
it "returns the time in UTC" do
|
314
|
+
@test = Time.local(4, 56, 8, 9, 4, 2003, 3, 99, true, "CDT")
|
315
|
+
@test.to_mongo.should == Time.utc(2003, 4, 9, 6, 56, 4)
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
describe Boolean do
|
323
|
+
|
324
|
+
describe ".type_cast" do
|
325
|
+
|
326
|
+
it "returns nil when called with nil" do
|
327
|
+
Boolean.type_cast(nil).should == nil
|
328
|
+
end
|
329
|
+
|
330
|
+
it "tries to convert any other value to true or false" do
|
331
|
+
Boolean.type_cast("true").should == true
|
332
|
+
Boolean.type_cast("false").should == false
|
333
|
+
Boolean.type_cast(15).should == true
|
334
|
+
Boolean.type_cast(0).should == false
|
335
|
+
Boolean.type_cast([]).should == false
|
336
|
+
Boolean.type_cast([1]).should == true
|
337
|
+
end
|
338
|
+
|
339
|
+
end
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
describe Numeric do
|
344
|
+
|
345
|
+
describe ".type_cast" do
|
346
|
+
|
347
|
+
it "returns nil when called with nil" do
|
348
|
+
Numeric.type_cast(nil).should == nil
|
349
|
+
end
|
350
|
+
|
351
|
+
it "tries to convert any other value to a number" do
|
352
|
+
Numeric.type_cast("23.2").should == 23.2
|
353
|
+
Numeric.type_cast("5").should == 5
|
354
|
+
Numeric.type_cast("any").should == 0
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|
360
|
+
|
361
|
+
describe Hash do
|
362
|
+
|
363
|
+
describe ".type_cast" do
|
364
|
+
|
365
|
+
it "returns nil when called with nil" do
|
366
|
+
Hash.type_cast(nil).should == nil
|
367
|
+
end
|
368
|
+
|
369
|
+
it "tries to convert any other value to a hash" do
|
370
|
+
Hash.type_cast({:a => 1}).should == {:a => 1}
|
371
|
+
end
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
describe "#to_mongo" do
|
376
|
+
|
377
|
+
it "returns itself" do
|
378
|
+
@test = {:a => 1}
|
379
|
+
@test.to_mongo.should == @test
|
380
|
+
end
|
381
|
+
|
382
|
+
end
|
383
|
+
|
384
|
+
end
|
385
|
+
|
386
|
+
describe Regexp do
|
387
|
+
|
388
|
+
describe ".type_cast" do
|
389
|
+
|
390
|
+
it "returns nil when called with nil" do
|
391
|
+
Regexp.type_cast(nil).should == nil
|
392
|
+
end
|
393
|
+
|
394
|
+
it "tries to convert any other value to a regular expression" do
|
395
|
+
Regexp.type_cast("^test$").should == /^test$/
|
396
|
+
end
|
397
|
+
|
398
|
+
end
|
399
|
+
|
400
|
+
describe "#to_mongo" do
|
401
|
+
|
402
|
+
it "returns itself" do
|
403
|
+
@test = /^test$/
|
404
|
+
@test.to_mongo.should == @test
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
describe NilClass do
|
412
|
+
|
413
|
+
describe "#to_mongo" do
|
414
|
+
|
415
|
+
it "returns nil" do
|
416
|
+
nil.to_mongo.should == nil
|
417
|
+
end
|
418
|
+
|
419
|
+
end
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
end
|