djsun-mongomapper 0.3.1.1 → 0.3.3
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/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
|