djsun-mongomapper 0.3.1.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History +20 -1
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/base.rb +3 -5
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +5 -3
- data/lib/mongomapper/associations/belongs_to_proxy.rb +4 -4
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +38 -15
- data/lib/mongomapper/document.rb +165 -95
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +116 -88
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +12 -16
- data/lib/mongomapper/serializers/json_serializer.rb +15 -12
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +7 -33
- data/mongomapper.gemspec +10 -7
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +14 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +10 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +46 -52
- data/test/functional/associations/test_many_proxy.rb +71 -12
- data/test/functional/test_associations.rb +9 -2
- data/test/functional/test_document.rb +281 -20
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +39 -8
- data/test/unit/serializers/test_json_serializer.rb +46 -12
- data/test/unit/test_association_base.rb +10 -2
- data/test/unit/test_document.rb +7 -9
- data/test/unit/test_embedded_document.rb +180 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +54 -24
- metadata +5 -5
- data/test/unit/test_mongo_id.rb +0 -35
@@ -15,6 +15,38 @@ class DocumentTest < Test::Unit::TestCase
|
|
15
15
|
@document.collection.clear
|
16
16
|
end
|
17
17
|
|
18
|
+
context "Saving a document with a custom id" do
|
19
|
+
should "clear custom id flag when saved" do
|
20
|
+
doc = @document.new(:id => '1234')
|
21
|
+
doc.using_custom_id?.should be_true
|
22
|
+
doc.save.should be_true
|
23
|
+
doc.using_custom_id?.should be_false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "Loading a document from the database with keys that are not defined" do
|
28
|
+
setup do
|
29
|
+
@id = XGen::Mongo::Driver::ObjectID.new.to_s
|
30
|
+
@document.collection.insert({
|
31
|
+
:_id => @id,
|
32
|
+
:first_name => 'John',
|
33
|
+
:last_name => 'Nunemaker',
|
34
|
+
:age => 27,
|
35
|
+
:favorite_color => 'red',
|
36
|
+
:skills => ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
should "assign all keys from database" do
|
41
|
+
doc = @document.find(@id)
|
42
|
+
doc.first_name.should == 'John'
|
43
|
+
doc.last_name.should == 'Nunemaker'
|
44
|
+
doc.age.should == 27
|
45
|
+
doc.favorite_color.should == 'red'
|
46
|
+
doc.skills.should == ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
18
50
|
context "Document Class Methods" do
|
19
51
|
context "Using key with type Array" do
|
20
52
|
setup do
|
@@ -53,7 +85,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
53
85
|
doc.tags.should == ["foo"]
|
54
86
|
end
|
55
87
|
|
56
|
-
|
88
|
+
should "work with << then save" do
|
57
89
|
doc = @document.new
|
58
90
|
doc.tags << "foo"
|
59
91
|
doc.tags << "bar"
|
@@ -61,7 +93,6 @@ class DocumentTest < Test::Unit::TestCase
|
|
61
93
|
doc.tags.should == %w(foo bar)
|
62
94
|
@document.find(doc.id).tags.should == %w(foo bar)
|
63
95
|
end
|
64
|
-
|
65
96
|
end
|
66
97
|
|
67
98
|
context "Using key with type Hash" do
|
@@ -73,14 +104,14 @@ class DocumentTest < Test::Unit::TestCase
|
|
73
104
|
doc = @document.new
|
74
105
|
doc.foo.should == {}
|
75
106
|
end
|
76
|
-
|
107
|
+
|
77
108
|
should "work with []=" do
|
78
109
|
doc = @document.new
|
79
110
|
doc.foo["quux"] = "bar"
|
80
111
|
doc.foo["quux"].should == "bar"
|
81
112
|
doc.foo.should == { "quux" => "bar" }
|
82
113
|
end
|
83
|
-
|
114
|
+
|
84
115
|
should "work with indifferent access" do
|
85
116
|
doc = @document.new
|
86
117
|
doc.foo = {:baz => 'bar'}
|
@@ -92,6 +123,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
92
123
|
doc = @document.new
|
93
124
|
doc.foo = {:baz => 'bar'}
|
94
125
|
doc.save
|
126
|
+
|
95
127
|
doc = @document.find(doc.id)
|
96
128
|
doc.foo[:baz].should == 'bar'
|
97
129
|
doc.foo['baz'].should == 'bar'
|
@@ -132,6 +164,10 @@ class DocumentTest < Test::Unit::TestCase
|
|
132
164
|
@doc_instance.id.size.should == 24
|
133
165
|
end
|
134
166
|
|
167
|
+
should "no longer be new?" do
|
168
|
+
@doc_instance.new?.should be_false
|
169
|
+
end
|
170
|
+
|
135
171
|
should "return instance of document" do
|
136
172
|
@doc_instance.should be_instance_of(@document)
|
137
173
|
@doc_instance.first_name.should == 'John'
|
@@ -249,11 +285,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
249
285
|
end
|
250
286
|
|
251
287
|
should "raise error if document not found" do
|
252
|
-
lambda { @document.find(
|
253
|
-
end
|
254
|
-
|
255
|
-
should_eventually "raise error if id is illegal" do
|
256
|
-
lambda { @document.find(1) }.should raise_error(MongoMapper::IllegalID)
|
288
|
+
lambda { @document.find(123) }.should raise_error(MongoMapper::DocumentNotFound)
|
257
289
|
end
|
258
290
|
end
|
259
291
|
|
@@ -280,7 +312,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
280
312
|
context "with #all" do
|
281
313
|
should "find all documents based on criteria" do
|
282
314
|
@document.all(:order => 'first_name').should == [@doc1, @doc3, @doc2]
|
283
|
-
@document.all(:conditions => {:last_name => 'Nunemaker'}).should == [@doc1, @doc3]
|
315
|
+
@document.all(:conditions => {:last_name => 'Nunemaker'}, :order => 'age desc').should == [@doc1, @doc3]
|
284
316
|
end
|
285
317
|
end
|
286
318
|
|
@@ -299,17 +331,75 @@ class DocumentTest < Test::Unit::TestCase
|
|
299
331
|
|
300
332
|
context "with :last" do
|
301
333
|
should "find last document" do
|
302
|
-
@document.find(:last).should == @
|
334
|
+
@document.find(:last, :order => 'age').should == @doc2
|
303
335
|
end
|
304
336
|
end
|
305
337
|
|
306
338
|
context "with #last" do
|
307
339
|
should "find last document based on criteria" do
|
308
|
-
@document.last.should == @
|
340
|
+
@document.last(:order => 'age').should == @doc2
|
309
341
|
@document.last(:conditions => {:age => 28}).should == @doc2
|
310
342
|
end
|
311
343
|
end
|
312
344
|
|
345
|
+
context "with :find_by" do
|
346
|
+
should "find document based on argument" do
|
347
|
+
@document.find_by_first_name('John').should == @doc1
|
348
|
+
@document.find_by_last_name('Nunemaker', :order => 'age desc').should == @doc1
|
349
|
+
@document.find_by_age(27).should == @doc1
|
350
|
+
end
|
351
|
+
|
352
|
+
should "not raise error" do
|
353
|
+
@document.find_by_first_name('Mongo').should be_nil
|
354
|
+
end
|
355
|
+
|
356
|
+
should "define a method for each key" do
|
357
|
+
@document.methods(false).select { |e| e =~ /^find_by_/ }.size == @document.keys.size
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context "with dynamic finders" do
|
362
|
+
should "find document based on all arguments" do
|
363
|
+
@document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 27).should == @doc1
|
364
|
+
end
|
365
|
+
|
366
|
+
should "not find the document if an argument is wrong" do
|
367
|
+
@document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 28).should be_nil
|
368
|
+
end
|
369
|
+
|
370
|
+
should "find all documents based on arguments" do
|
371
|
+
docs = @document.find_all_by_last_name('Nunemaker')
|
372
|
+
docs.should be_kind_of(Array)
|
373
|
+
docs.should include(@doc1)
|
374
|
+
docs.should include(@doc3)
|
375
|
+
end
|
376
|
+
|
377
|
+
should "find last document based on arguments" do
|
378
|
+
doc = @document.find_last_by_last_name('Nunemaker', :order => 'age')
|
379
|
+
doc.should == @doc1
|
380
|
+
end
|
381
|
+
|
382
|
+
should "initialize document with given arguments" do
|
383
|
+
doc = @document.find_or_initialize_by_first_name_and_last_name('David', 'Cuadrado')
|
384
|
+
doc.should be_new
|
385
|
+
doc.first_name.should == 'David'
|
386
|
+
end
|
387
|
+
|
388
|
+
should "not initialize document if document is found" do
|
389
|
+
doc = @document.find_or_initialize_by_first_name('John')
|
390
|
+
doc.should_not be_new
|
391
|
+
end
|
392
|
+
|
393
|
+
should "create document with given arguments" do
|
394
|
+
doc = @document.find_or_create_by_first_name_and_last_name('David', 'Cuadrado')
|
395
|
+
doc.should_not be_new
|
396
|
+
doc.first_name.should == 'David'
|
397
|
+
end
|
398
|
+
|
399
|
+
should "raise error if document is not found" do
|
400
|
+
lambda {@document.find_by_first_name_and_last_name!(1,2)}.should raise_error(MongoMapper::DocumentNotFound)
|
401
|
+
end
|
402
|
+
end
|
313
403
|
end # finding documents
|
314
404
|
|
315
405
|
context "Finding document by id" do
|
@@ -324,7 +414,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
324
414
|
end
|
325
415
|
|
326
416
|
should "return nil if document not found" do
|
327
|
-
@document.find_by_id(
|
417
|
+
@document.find_by_id(1234).should be(nil)
|
328
418
|
end
|
329
419
|
end
|
330
420
|
|
@@ -448,6 +538,123 @@ class DocumentTest < Test::Unit::TestCase
|
|
448
538
|
end
|
449
539
|
end
|
450
540
|
|
541
|
+
context ":dependent" do
|
542
|
+
setup do
|
543
|
+
# FIXME: make use of already defined models
|
544
|
+
class ::Property
|
545
|
+
include MongoMapper::Document
|
546
|
+
end
|
547
|
+
Property.delete_all
|
548
|
+
|
549
|
+
class ::Thing
|
550
|
+
include MongoMapper::Document
|
551
|
+
key :name, String
|
552
|
+
end
|
553
|
+
Thing.delete_all
|
554
|
+
end
|
555
|
+
|
556
|
+
teardown do
|
557
|
+
Object.send :remove_const, 'Property' if defined?(::Property)
|
558
|
+
Object.send :remove_const, 'Thing' if defined?(::Thing)
|
559
|
+
end
|
560
|
+
|
561
|
+
context "many" do
|
562
|
+
context "=> destroy" do
|
563
|
+
setup do
|
564
|
+
Property.key :thing_id, String
|
565
|
+
Property.belongs_to :thing, :dependent => :destroy
|
566
|
+
Thing.many :properties, :dependent => :destroy
|
567
|
+
|
568
|
+
@thing = Thing.create(:name => "Tree")
|
569
|
+
@property1 = Property.create
|
570
|
+
@property2 = Property.create
|
571
|
+
@property3 = Property.create
|
572
|
+
@thing.properties << @property1
|
573
|
+
@thing.properties << @property2
|
574
|
+
@thing.properties << @property3
|
575
|
+
end
|
576
|
+
|
577
|
+
should "should destroy the associated documents" do
|
578
|
+
@thing.properties.count.should == 3
|
579
|
+
@thing.destroy
|
580
|
+
@thing.properties.count.should == 0
|
581
|
+
Property.count.should == 0
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
context "=> delete_all" do
|
586
|
+
setup do
|
587
|
+
Property.key :thing_id, String
|
588
|
+
Property.belongs_to :thing
|
589
|
+
Thing.has_many :properties, :dependent => :delete_all
|
590
|
+
|
591
|
+
@thing = Thing.create(:name => "Tree")
|
592
|
+
@property1 = Property.create
|
593
|
+
@property2 = Property.create
|
594
|
+
@property3 = Property.create
|
595
|
+
@thing.properties << @property1
|
596
|
+
@thing.properties << @property2
|
597
|
+
@thing.properties << @property3
|
598
|
+
end
|
599
|
+
|
600
|
+
should "should delete associated documents" do
|
601
|
+
@thing.properties.count.should == 3
|
602
|
+
@thing.destroy
|
603
|
+
@thing.properties.count.should == 0
|
604
|
+
Property.count.should == 0
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
context "=> nullify" do
|
609
|
+
setup do
|
610
|
+
Property.key :thing_id, String
|
611
|
+
Property.belongs_to :thing
|
612
|
+
Thing.has_many :properties, :dependent => :nullify
|
613
|
+
|
614
|
+
@thing = Thing.create(:name => "Tree")
|
615
|
+
@property1 = Property.create
|
616
|
+
@property2 = Property.create
|
617
|
+
@property3 = Property.create
|
618
|
+
@thing.properties << @property1
|
619
|
+
@thing.properties << @property2
|
620
|
+
@thing.properties << @property3
|
621
|
+
end
|
622
|
+
|
623
|
+
should "should nullify relationship but not destroy associated documents" do
|
624
|
+
@thing.properties.count.should == 3
|
625
|
+
@thing.destroy
|
626
|
+
@thing.properties.count.should == 0
|
627
|
+
Property.count.should == 3
|
628
|
+
end
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
632
|
+
context "belongs_to" do
|
633
|
+
context "=> destroy" do
|
634
|
+
setup do
|
635
|
+
Property.key :thing_id, String
|
636
|
+
Property.belongs_to :thing, :dependent => :destroy
|
637
|
+
Thing.has_many :properties
|
638
|
+
|
639
|
+
@thing = Thing.create(:name => "Tree")
|
640
|
+
@property1 = Property.create
|
641
|
+
@property2 = Property.create
|
642
|
+
@property3 = Property.create
|
643
|
+
@thing.properties << @property1
|
644
|
+
@thing.properties << @property2
|
645
|
+
@thing.properties << @property3
|
646
|
+
end
|
647
|
+
|
648
|
+
should "destroy the thing" do
|
649
|
+
Thing.count.should == 1
|
650
|
+
@property1.destroy
|
651
|
+
Thing.count.should == 0
|
652
|
+
@property1.thing.should be_frozen
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
451
658
|
context "Counting documents in collection" do
|
452
659
|
setup do
|
453
660
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
@@ -504,13 +711,13 @@ class DocumentTest < Test::Unit::TestCase
|
|
504
711
|
@document.ensure_index :first_name, :unique => true
|
505
712
|
end
|
506
713
|
|
507
|
-
|
714
|
+
should "allow creating index on multiple keys" do
|
508
715
|
index_name = nil
|
509
716
|
lambda {
|
510
717
|
index_name = @document.ensure_index [[:first_name, 1], [:last_name, -1]]
|
511
718
|
}.should change { @document.collection.index_information.size }.by(1)
|
512
719
|
|
513
|
-
|
720
|
+
[ 'first_name_1_last_name_-1', 'last_name_-1_first_name_1' ].should include(index_name)
|
514
721
|
|
515
722
|
index = @document.collection.index_information[index_name]
|
516
723
|
index.should_not be_nil
|
@@ -551,6 +758,21 @@ class DocumentTest < Test::Unit::TestCase
|
|
551
758
|
from_db.first_name.should == 'John'
|
552
759
|
from_db.age.should == 27
|
553
760
|
end
|
761
|
+
|
762
|
+
should "allow to add custom attributes to the document" do
|
763
|
+
@doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male', :tags => [1, "2"])
|
764
|
+
@doc.save
|
765
|
+
from_db = @document.find(@doc.id)
|
766
|
+
from_db.gender.should == 'male'
|
767
|
+
from_db.tags.should == [1, "2"]
|
768
|
+
end
|
769
|
+
|
770
|
+
should "allow to use custom methods to assign properties" do
|
771
|
+
person = RealPerson.new(:realname => "David")
|
772
|
+
person.save
|
773
|
+
from_db = RealPerson.find(person.id)
|
774
|
+
from_db.name.should == "David"
|
775
|
+
end
|
554
776
|
end
|
555
777
|
|
556
778
|
context "Saving an existing document" do
|
@@ -575,6 +797,14 @@ class DocumentTest < Test::Unit::TestCase
|
|
575
797
|
from_db.first_name.should == 'Johnny'
|
576
798
|
from_db.age.should == 30
|
577
799
|
end
|
800
|
+
|
801
|
+
should "allow to update custom attributes" do
|
802
|
+
@doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male')
|
803
|
+
@doc.gender = 'Male'
|
804
|
+
@doc.save
|
805
|
+
from_db = @document.find(@doc.id)
|
806
|
+
from_db.gender.should == 'Male'
|
807
|
+
end
|
578
808
|
end
|
579
809
|
|
580
810
|
context "Calling update attributes on a new document" do
|
@@ -603,6 +833,12 @@ class DocumentTest < Test::Unit::TestCase
|
|
603
833
|
from_db.first_name.should == 'Johnny'
|
604
834
|
from_db.age.should == 30
|
605
835
|
end
|
836
|
+
|
837
|
+
should "allow to update custom attributes" do
|
838
|
+
@doc.update_attributes(:gender => 'mALe')
|
839
|
+
from_db = @document.find(@doc.id)
|
840
|
+
from_db.gender.should == 'mALe'
|
841
|
+
end
|
606
842
|
end
|
607
843
|
|
608
844
|
context "Updating an existing document using update attributes" do
|
@@ -626,6 +862,20 @@ class DocumentTest < Test::Unit::TestCase
|
|
626
862
|
from_db.age.should == 30
|
627
863
|
end
|
628
864
|
end
|
865
|
+
|
866
|
+
context "update_attributes" do
|
867
|
+
setup do
|
868
|
+
@document.key :foo, String, :required => true
|
869
|
+
end
|
870
|
+
|
871
|
+
should "return true if document valid" do
|
872
|
+
@document.new.update_attributes(:foo => 'bar').should be_true
|
873
|
+
end
|
874
|
+
|
875
|
+
should "return false if document not valid" do
|
876
|
+
@document.new.update_attributes({}).should be_false
|
877
|
+
end
|
878
|
+
end
|
629
879
|
|
630
880
|
context "Destroying a document that exists" do
|
631
881
|
setup do
|
@@ -640,6 +890,10 @@ class DocumentTest < Test::Unit::TestCase
|
|
640
890
|
should "raise error if assignment is attempted" do
|
641
891
|
lambda { @doc.first_name = 'Foo' }.should raise_error(TypeError)
|
642
892
|
end
|
893
|
+
|
894
|
+
should "do nothing if destroy is called again" do
|
895
|
+
@doc.destroy.should be_false
|
896
|
+
end
|
643
897
|
end
|
644
898
|
|
645
899
|
context "Destroying a document that is a new" do
|
@@ -660,6 +914,10 @@ class DocumentTest < Test::Unit::TestCase
|
|
660
914
|
end
|
661
915
|
|
662
916
|
context "timestamping" do
|
917
|
+
setup do
|
918
|
+
@document.timestamps!
|
919
|
+
end
|
920
|
+
|
663
921
|
should "set created_at and updated_at on create" do
|
664
922
|
doc = @document.new(:first_name => 'John', :age => 27)
|
665
923
|
doc.created_at.should be(nil)
|
@@ -679,13 +937,16 @@ class DocumentTest < Test::Unit::TestCase
|
|
679
937
|
doc.updated_at.should_not == old_updated_at
|
680
938
|
end
|
681
939
|
|
682
|
-
|
940
|
+
should "set updated_at on document update but leave created_at alone" do
|
683
941
|
doc = @document.create(:first_name => 'John', :age => 27)
|
684
942
|
old_created_at = doc.created_at
|
685
943
|
old_updated_at = doc.updated_at
|
686
|
-
|
687
|
-
doc.
|
688
|
-
|
944
|
+
sleep 1 # this annoys me
|
945
|
+
@document.update(doc._id, { :first_name => 'Johnny' })
|
946
|
+
|
947
|
+
from_db = @document.find(doc.id)
|
948
|
+
from_db.created_at.to_i.should == old_created_at.to_i
|
949
|
+
from_db.updated_at.to_i.should_not == old_updated_at.to_i
|
689
950
|
end
|
690
951
|
end
|
691
|
-
end
|
952
|
+
end
|
@@ -18,9 +18,8 @@ class TestRailsCompatibility < Test::Unit::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
should "have to_param that returns id" do
|
21
|
-
|
22
|
-
instance
|
23
|
-
instance.to_param.should == id.to_s
|
21
|
+
instance = Order.create('_id' => 1234)
|
22
|
+
instance.to_param.should == '1234'
|
24
23
|
end
|
25
24
|
|
26
25
|
should "alias new to new_record?" do
|
data/test/models.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class Address
|
2
2
|
include MongoMapper::EmbeddedDocument
|
3
|
+
|
3
4
|
key :address, String
|
4
5
|
key :city, String
|
5
6
|
key :state, String
|
@@ -8,7 +9,12 @@ end
|
|
8
9
|
|
9
10
|
class Message
|
10
11
|
include MongoMapper::Document
|
12
|
+
|
11
13
|
key :body, String
|
14
|
+
key :position, Integer
|
15
|
+
key :_type, String
|
16
|
+
key :room_id, String
|
17
|
+
|
12
18
|
belongs_to :room
|
13
19
|
end
|
14
20
|
|
@@ -18,12 +24,14 @@ class Chat < Message; end
|
|
18
24
|
|
19
25
|
class Room
|
20
26
|
include MongoMapper::Document
|
27
|
+
|
21
28
|
key :name, String
|
22
29
|
many :messages, :polymorphic => true
|
23
30
|
end
|
24
31
|
|
25
32
|
class Project
|
26
33
|
include MongoMapper::Document
|
34
|
+
|
27
35
|
key :name, String
|
28
36
|
many :statuses
|
29
37
|
many :addresses
|
@@ -31,32 +39,48 @@ end
|
|
31
39
|
|
32
40
|
class Status
|
33
41
|
include MongoMapper::Document
|
42
|
+
|
43
|
+
key :project_id, String
|
44
|
+
key :target_id, String
|
45
|
+
key :target_type, String
|
46
|
+
key :name, String
|
47
|
+
key :position, Integer
|
48
|
+
|
34
49
|
belongs_to :project
|
35
50
|
belongs_to :target, :polymorphic => true
|
36
|
-
key :name, String
|
37
51
|
end
|
38
52
|
|
39
53
|
class RealPerson
|
40
54
|
include MongoMapper::Document
|
41
|
-
|
55
|
+
|
56
|
+
many :pets
|
42
57
|
key :name, String
|
58
|
+
|
59
|
+
def realname=(n)
|
60
|
+
self.name = n
|
61
|
+
end
|
43
62
|
end
|
44
63
|
|
45
64
|
class Person
|
46
65
|
include MongoMapper::EmbeddedDocument
|
66
|
+
|
47
67
|
key :name, String
|
48
68
|
key :child, Person
|
69
|
+
|
49
70
|
many :pets
|
50
71
|
end
|
51
72
|
|
52
73
|
class Pet
|
53
74
|
include MongoMapper::EmbeddedDocument
|
75
|
+
|
54
76
|
key :name, String
|
55
77
|
key :species, String
|
56
78
|
end
|
57
79
|
|
58
80
|
class Media
|
59
81
|
include MongoMapper::EmbeddedDocument
|
82
|
+
|
83
|
+
key :_type, String
|
60
84
|
key :file, String
|
61
85
|
end
|
62
86
|
|
@@ -75,34 +99,41 @@ end
|
|
75
99
|
|
76
100
|
class Catalog
|
77
101
|
include MongoMapper::Document
|
102
|
+
|
78
103
|
many :medias, :polymorphic => true
|
79
104
|
end
|
80
105
|
|
81
106
|
module TrModels
|
82
107
|
class Transport
|
83
108
|
include MongoMapper::EmbeddedDocument
|
109
|
+
|
110
|
+
key :_type, String
|
84
111
|
key :license_plate, String
|
85
112
|
end
|
86
|
-
|
113
|
+
|
87
114
|
class Car < TrModels::Transport
|
88
115
|
include MongoMapper::EmbeddedDocument
|
116
|
+
|
89
117
|
key :model, String
|
90
118
|
key :year, Integer
|
91
119
|
end
|
92
|
-
|
120
|
+
|
93
121
|
class Bus < TrModels::Transport
|
94
122
|
include MongoMapper::EmbeddedDocument
|
123
|
+
|
95
124
|
key :max_passengers, Integer
|
96
125
|
end
|
97
|
-
|
126
|
+
|
98
127
|
class Ambulance < TrModels::Transport
|
99
128
|
include MongoMapper::EmbeddedDocument
|
129
|
+
|
100
130
|
key :icu, Boolean
|
101
131
|
end
|
102
|
-
|
132
|
+
|
103
133
|
class Fleet
|
104
134
|
include MongoMapper::Document
|
135
|
+
|
105
136
|
many :transports, :polymorphic => true, :class_name => "TrModels::Transport"
|
106
|
-
key :name, String
|
137
|
+
key :name, String
|
107
138
|
end
|
108
|
-
end
|
139
|
+
end
|
@@ -51,7 +51,7 @@ class JsonSerializationTest < Test::Unit::TestCase
|
|
51
51
|
should "allow attribute filtering with except" do
|
52
52
|
json = @contact.to_json(:except => [:name, :age])
|
53
53
|
|
54
|
-
|
54
|
+
assert_no_match %r{"_id"}, json
|
55
55
|
assert_no_match %r{"name"}, json
|
56
56
|
assert_no_match %r{"age"}, json
|
57
57
|
assert_match %r{"awesome"}, json
|
@@ -59,26 +59,60 @@ class JsonSerializationTest < Test::Unit::TestCase
|
|
59
59
|
assert_match %r{"preferences"}, json
|
60
60
|
end
|
61
61
|
|
62
|
-
context "
|
62
|
+
context "_id key" do
|
63
|
+
should "not be included by default" do
|
64
|
+
json = @contact.to_json
|
65
|
+
assert_no_match %r{"_id":}, json
|
66
|
+
end
|
67
|
+
|
68
|
+
should "not be included even if :except is used" do
|
69
|
+
json = @contact.to_json(:except => :name)
|
70
|
+
assert_no_match %r{"_id":}, json
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "id method" do
|
63
75
|
setup do
|
64
76
|
def @contact.label; "Has cheezburger"; end
|
65
77
|
def @contact.favorite_quote; "Constraints are liberating"; end
|
66
78
|
end
|
67
79
|
|
68
|
-
should "
|
80
|
+
should "be included by default" do
|
81
|
+
json = @contact.to_json
|
82
|
+
assert_match %r{"id"}, json
|
83
|
+
end
|
84
|
+
|
85
|
+
should "be included when single method included" do
|
69
86
|
json = @contact.to_json(:methods => :label)
|
87
|
+
assert_match %r{"id"}, json
|
70
88
|
assert_match %r{"label":"Has cheezburger"}, json
|
89
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
90
|
+
assert_no_match %r{"favorite_quote":"Constraints are liberating"}, json
|
71
91
|
end
|
72
92
|
|
73
|
-
should "
|
74
|
-
json = @contact.to_json(:
|
75
|
-
|
93
|
+
should "be included when multiple methods included" do
|
94
|
+
json = @contact.to_json(:methods => [:label, :favorite_quote])
|
95
|
+
assert_match %r{"id"}, json
|
76
96
|
assert_match %r{"label":"Has cheezburger"}, json
|
97
|
+
assert_match %r{"favorite_quote":"Constraints are liberating"}, json
|
77
98
|
assert_match %r{"name":"Konata Izumi"}, json
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
99
|
+
end
|
100
|
+
|
101
|
+
should "not be included if :only is present" do
|
102
|
+
json = @contact.to_json(:only => :name)
|
103
|
+
assert_no_match %r{"id":}, json
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "including methods" do
|
108
|
+
setup do
|
109
|
+
def @contact.label; "Has cheezburger"; end
|
110
|
+
def @contact.favorite_quote; "Constraints are liberating"; end
|
111
|
+
end
|
112
|
+
|
113
|
+
should "include single method" do
|
114
|
+
json = @contact.to_json(:methods => :label)
|
115
|
+
assert_match %r{"label":"Has cheezburger"}, json
|
82
116
|
end
|
83
117
|
|
84
118
|
should "include multiple methods" do
|
@@ -106,8 +140,8 @@ class JsonSerializationTest < Test::Unit::TestCase
|
|
106
140
|
end
|
107
141
|
|
108
142
|
should "allow attribute filtering with except" do
|
109
|
-
json = @contacts.to_json(:except => [:name, :preferences, :awesome, :created_at, :updated_at
|
110
|
-
assert_equal %([{"id":
|
143
|
+
json = @contacts.to_json(:except => [:name, :preferences, :awesome, :created_at, :updated_at])
|
144
|
+
assert_equal %([{"id":null,"age":39},{"id":null,"age":14}]), json
|
111
145
|
end
|
112
146
|
end
|
113
147
|
|
@@ -78,8 +78,16 @@ class AssociationBaseTest < Test::Unit::TestCase
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
|
-
|
81
|
+
context "foreign_key" do
|
82
|
+
should "default to assocation_name_id" do
|
83
|
+
base = Base.new(:belongs_to, :foo)
|
84
|
+
base.foreign_key.should == 'foo_id'
|
85
|
+
end
|
86
|
+
|
87
|
+
should "be overridable with :foreign_key option" do
|
88
|
+
base = Base.new(:belongs_to, :foo, :foreign_key => 'foobar_id')
|
89
|
+
base.foreign_key.should == 'foobar_id'
|
90
|
+
end
|
83
91
|
end
|
84
92
|
|
85
93
|
should "have ivar that is association name" do
|