mongodb-mongo_record 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +9 -0
- data/lib/mongo_record/base.rb +50 -33
- data/mongo-activerecord-ruby.gemspec +2 -2
- data/tests/test_mongo.rb +59 -41
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -72,6 +72,15 @@ See MongoRecord::LogDevice. When running outside of the cloud (for example,
|
|
72
72
|
during development), all log messages are echoed to $stderr which is normally
|
73
73
|
the console.
|
74
74
|
|
75
|
+
== Credits
|
76
|
+
Jim Mulholland, jim at squeejee dot com
|
77
|
+
* Ability to save custom attributes not declared in the model
|
78
|
+
* Save and retrieve custom "_id" fields
|
79
|
+
* Find_each functionality
|
80
|
+
* Find_last based on the created_at field
|
81
|
+
* Assigning created_at and updated_at fields even if they are not declared
|
82
|
+
* Alias methods for "first", "last" and "all"
|
83
|
+
|
75
84
|
== To Do
|
76
85
|
|
77
86
|
* DBRefs
|
data/lib/mongo_record/base.rb
CHANGED
@@ -119,7 +119,7 @@ module MongoRecord
|
|
119
119
|
# lower_case_with_underscores.
|
120
120
|
def collection_name(coll_name)
|
121
121
|
@coll_name = coll_name
|
122
|
-
field(:_id, :_ns
|
122
|
+
field(:_id, :_ns)
|
123
123
|
end
|
124
124
|
|
125
125
|
# Creates one or more collection fields. Each field will be saved to
|
@@ -287,10 +287,10 @@ module MongoRecord
|
|
287
287
|
# is the same as
|
288
288
|
# Person.find(:all).skip(10).limit(10).sort({:created_on => 1})
|
289
289
|
#
|
290
|
-
|
291
|
-
|
292
|
-
def find(*args)
|
293
|
-
options = extract_options_from_args!(args)
|
290
|
+
|
291
|
+
|
292
|
+
def find(*args)
|
293
|
+
options = extract_options_from_args!(args)
|
294
294
|
options.symbolize_keys!
|
295
295
|
case args.first
|
296
296
|
when :first
|
@@ -303,7 +303,7 @@ module MongoRecord
|
|
303
303
|
find_from_ids(args, options)
|
304
304
|
end
|
305
305
|
end
|
306
|
-
|
306
|
+
|
307
307
|
# Yields each record that was found by the find +options+. The find is
|
308
308
|
# performed by find.
|
309
309
|
#
|
@@ -313,20 +313,20 @@ module MongoRecord
|
|
313
313
|
# person.party_all_night!
|
314
314
|
# end
|
315
315
|
|
316
|
-
def find_each(*args)
|
317
|
-
options = extract_options_from_args!(args)
|
316
|
+
def find_each(*args)
|
317
|
+
options = extract_options_from_args!(args)
|
318
318
|
options.symbolize_keys!
|
319
319
|
find_every(options).each do |record|
|
320
|
-
yield record
|
320
|
+
yield record
|
321
321
|
end
|
322
322
|
self
|
323
323
|
end
|
324
|
-
|
324
|
+
|
325
325
|
def all(*args)
|
326
326
|
options = extract_options_from_args!(args)
|
327
327
|
find_every(options)
|
328
328
|
end
|
329
|
-
|
329
|
+
|
330
330
|
def first(*args)
|
331
331
|
# args = ([:first]<<args).flatten
|
332
332
|
options = extract_options_from_args!(args)
|
@@ -362,10 +362,10 @@ module MongoRecord
|
|
362
362
|
end
|
363
363
|
|
364
364
|
def sum(column)
|
365
|
-
x = self.find(:all, :select=>column)
|
365
|
+
x = self.find(:all, :select=>column)
|
366
366
|
x.map {|p1| p1.followers_count}.compact.sum
|
367
367
|
end
|
368
|
-
|
368
|
+
|
369
369
|
# Deletes the record with the given id from the collection.
|
370
370
|
def delete(id)
|
371
371
|
collection.remove({:_id => id})
|
@@ -465,7 +465,7 @@ module MongoRecord
|
|
465
465
|
# row = collection.find_first(criteria, :fields => fields)
|
466
466
|
# (row.nil? || row['_id'] == nil) ? nil : self.new(row)
|
467
467
|
# end
|
468
|
-
|
468
|
+
|
469
469
|
def find_initial(options)
|
470
470
|
options[:limit] = 1
|
471
471
|
options[:order] = 'created_at asc'
|
@@ -483,7 +483,7 @@ module MongoRecord
|
|
483
483
|
def find_every(options)
|
484
484
|
options.symbolize_keys!
|
485
485
|
criteria = criteria_from(options[:conditions], options[:criteria]).merge!(where_func(options[:where]))
|
486
|
-
|
486
|
+
|
487
487
|
find_options = {}
|
488
488
|
find_options[:fields] = fields_from(options[:select]) if options[:select]
|
489
489
|
find_options[:limit] = options[:limit].to_i if options[:limit]
|
@@ -528,10 +528,10 @@ module MongoRecord
|
|
528
528
|
|
529
529
|
def ids_clause(ids)
|
530
530
|
#ids.length == 1 ? ids[0].to_oid : {'$in' => ids.collect{|id| id.to_oid}}
|
531
|
-
|
532
|
-
if ids.length == 1
|
531
|
+
|
532
|
+
if ids.length == 1
|
533
533
|
ids[0].is_a?(String) ? ids[0].to_oid : ids[0]
|
534
|
-
else
|
534
|
+
else
|
535
535
|
{'$in' => ids.collect{|id| id.is_a?(String) ? id.to_oid : id}}
|
536
536
|
end
|
537
537
|
end
|
@@ -577,7 +577,7 @@ module MongoRecord
|
|
577
577
|
opts = criteria_from_hash(condition)
|
578
578
|
else
|
579
579
|
opts = {}
|
580
|
-
end
|
580
|
+
end
|
581
581
|
opts ||= {}
|
582
582
|
criteria ||= {}
|
583
583
|
opts.merge!(criteria)
|
@@ -771,7 +771,7 @@ module MongoRecord
|
|
771
771
|
|
772
772
|
# Save self and returns true if the save was successful, false if not.
|
773
773
|
def save
|
774
|
-
create_or_update
|
774
|
+
create_or_update
|
775
775
|
end
|
776
776
|
|
777
777
|
# Save self and returns true if the save was successful and raises
|
@@ -789,14 +789,22 @@ module MongoRecord
|
|
789
789
|
# database.
|
790
790
|
def to_mongo_value
|
791
791
|
h = {}
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
792
|
+
key_names = self.instance_values.keys
|
793
|
+
key_names.each {|key|
|
794
|
+
value = instance_variable_get("@#{key}").to_mongo_value
|
795
|
+
if value.instance_of? Hash and value["_ns"]
|
796
|
+
value = XGen::Mongo::Driver::DBRef.new(value["_ns"], value["_id"])
|
797
|
+
elsif value.instance_of? Array
|
798
|
+
value = value.map {|v|
|
799
|
+
if v.instance_of? Hash and v["_ns"]
|
800
|
+
XGen::Mongo::Driver::DBRef.new(v["_ns"], v["_id"])
|
801
|
+
else
|
802
|
+
v
|
803
|
+
end
|
804
|
+
}
|
805
|
+
end
|
806
|
+
h[key] = value
|
807
|
+
}
|
800
808
|
h
|
801
809
|
end
|
802
810
|
|
@@ -804,6 +812,7 @@ module MongoRecord
|
|
804
812
|
def create
|
805
813
|
create_date = self.instance_variable_defined?("@created_at") ? self.created_at : nil
|
806
814
|
set_create_times(create_date)
|
815
|
+
@_ns = self.class.collection.name
|
807
816
|
with_id = self.class.collection.insert(to_mongo_value)
|
808
817
|
@_id = with_id['_id'] || with_id[:_id]
|
809
818
|
with_id
|
@@ -817,7 +826,7 @@ module MongoRecord
|
|
817
826
|
if self.class.collection.db.error?
|
818
827
|
return false
|
819
828
|
end
|
820
|
-
self
|
829
|
+
self
|
821
830
|
end
|
822
831
|
|
823
832
|
# Remove self from the database and set @_id to nil. If self has no
|
@@ -839,12 +848,12 @@ module MongoRecord
|
|
839
848
|
def [](attr_name)
|
840
849
|
self.send(attr_name)
|
841
850
|
end
|
842
|
-
|
851
|
+
|
843
852
|
def []=(attr_name, value)
|
844
853
|
self.class.field(attr_name)
|
845
854
|
self.send(attr_name.to_s + '=', value)
|
846
855
|
end
|
847
|
-
|
856
|
+
|
848
857
|
def method_missing(sym, *args)
|
849
858
|
if self.instance_variables.include?("@#{sym}")
|
850
859
|
self.class.field(sym)
|
@@ -853,7 +862,7 @@ module MongoRecord
|
|
853
862
|
super
|
854
863
|
end
|
855
864
|
end
|
856
|
-
|
865
|
+
|
857
866
|
#--
|
858
867
|
# ================================================================
|
859
868
|
# These methods exist so we can plug in ActiveRecord validation, etc.
|
@@ -913,11 +922,19 @@ module MongoRecord
|
|
913
922
|
def init_ivar(ivar_name, val)
|
914
923
|
sym = ivar_name[1..-1].to_sym
|
915
924
|
if self.class.subobjects.keys.include?(sym)
|
925
|
+
if val.instance_of? XGen::Mongo::Driver::DBRef
|
926
|
+
val = self.class.collection.db.dereference(val)
|
927
|
+
end
|
916
928
|
instance_variable_set(ivar_name, self.class.subobjects[sym].new(val))
|
917
929
|
elsif self.class.arrays.keys.include?(sym)
|
918
930
|
klazz = self.class.arrays[sym]
|
919
931
|
val = [val] unless val.kind_of?(Array)
|
920
|
-
instance_variable_set(ivar_name, val.collect {|v|
|
932
|
+
instance_variable_set(ivar_name, val.collect {|v|
|
933
|
+
if v.instance_of? XGen::Mongo::Driver::DBRef
|
934
|
+
v = self.class.collection.db.dereference(v)
|
935
|
+
end
|
936
|
+
v.kind_of?(MongoRecord::Base) ? v : klazz.new(v)
|
937
|
+
})
|
921
938
|
else
|
922
939
|
instance_variable_set(ivar_name, val)
|
923
940
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'mongo_record'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.3'
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.summary = 'ActiveRecord-like models for the 10gen Mongo DB'
|
6
6
|
s.description = 'MongoRecord is an ActiveRecord-like framework for the 10gen Mongo database. For more information about Mongo, see http://www.mongodb.org.'
|
7
7
|
|
8
|
-
s.add_dependency('mongodb-mongo', ['>= 0.6.
|
8
|
+
s.add_dependency('mongodb-mongo', ['>= 0.6.7'])
|
9
9
|
|
10
10
|
s.require_paths = ['lib']
|
11
11
|
|
data/tests/test_mongo.rb
CHANGED
@@ -164,7 +164,7 @@ class MongoTest < Test::Unit::TestCase
|
|
164
164
|
def test_find_all
|
165
165
|
assert_all_songs Track.find(:all).inject('') { |str, t| str + t.to_s }
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
def test_find_using_hash
|
169
169
|
str = Track.find(:all, :conditions => {:album => 'Aliens Ate My Buick'}).inject('') { |str, t| str + t.to_s }
|
170
170
|
assert_match(/song: The Ability to Swing/, str)
|
@@ -271,11 +271,9 @@ class MongoTest < Test::Unit::TestCase
|
|
271
271
|
assert_equal "Budapest by Blimp:Europa and the Pirate Twins:Garden Of Earthly Delights:King For A Day:The Ability to Swing:The Mayor Of Simpleton",
|
272
272
|
tracks.collect {|t| t.song }.join(':')
|
273
273
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
# assert_equal "Garden Of Earthly Delights:King For A Day:The Mayor Of Simpleton:Budapest by Blimp:Europa and the Pirate Twins:The Ability to Swing",
|
278
|
-
# tracks.collect {|t| t.song }.join(':')
|
274
|
+
tracks = Track.find(:all, :order => "artist desc, song")
|
275
|
+
assert_not_nil tracks
|
276
|
+
assert_equal "Garden Of Earthly Delights:King For A Day:The Mayor Of Simpleton:Budapest by Blimp:Europa and the Pirate Twins:The Ability to Swing", tracks.collect {|t| t.song }.join(':')
|
279
277
|
end
|
280
278
|
|
281
279
|
def test_delete
|
@@ -560,34 +558,54 @@ class MongoTest < Test::Unit::TestCase
|
|
560
558
|
assert_equal s.created_on, s.updated_on
|
561
559
|
end
|
562
560
|
|
563
|
-
#
|
564
|
-
#
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
561
|
+
# This reproduces a bug where DBRefs weren't being created properly because
|
562
|
+
# the MongoRecord::Base objects weren't storing _ns
|
563
|
+
def test_db_ref
|
564
|
+
s = Student.new(:name => 'Spongebob Squarepants', :address => @spongebob_addr)
|
565
|
+
s.save
|
566
|
+
|
567
|
+
@course1.save
|
568
|
+
assert_not_nil @course1.id
|
569
|
+
assert_not_nil @course1["_ns"]
|
570
|
+
|
571
|
+
s.add_score(@course1.id, 3.5)
|
572
|
+
s.save
|
573
|
+
|
574
|
+
score = s.scores.first
|
575
|
+
assert_not_nil score
|
576
|
+
assert_equal @course1.name, score.for_course.name
|
570
577
|
|
571
|
-
#
|
572
|
-
#
|
578
|
+
# Now change the name of @course1 and see the student's score's course
|
579
|
+
# name change.
|
580
|
+
@course1.name = 'changed'
|
581
|
+
@course1.save
|
573
582
|
|
574
|
-
|
575
|
-
|
583
|
+
s = Student.find(:first, :conditions => "name = 'Spongebob Squarepants'")
|
584
|
+
assert_not_nil s
|
585
|
+
assert_equal 1, s.scores.length
|
586
|
+
assert_equal 'changed', s.scores.first.for_course.name
|
576
587
|
|
577
|
-
# score = s.scores.first
|
578
|
-
# assert_not_nil score
|
579
|
-
# assert_equal @course1.name, score.for_course.name
|
580
588
|
|
581
|
-
#
|
582
|
-
|
583
|
-
|
584
|
-
|
589
|
+
# Now try with has_many
|
590
|
+
score.save
|
591
|
+
s.scores = [score]
|
592
|
+
s.save
|
585
593
|
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
594
|
+
assert_equal 3.5, s.scores.first.grade
|
595
|
+
|
596
|
+
s = Student.find(:first, :conditions => "name = 'Spongebob Squarepants'")
|
597
|
+
assert_not_nil s
|
598
|
+
assert_equal 1, s.scores.length
|
599
|
+
assert_equal 3.5, s.scores.first.grade
|
600
|
+
|
601
|
+
score.grade = 4.0
|
602
|
+
score.save
|
603
|
+
|
604
|
+
s = Student.find(:first, :conditions => "name = 'Spongebob Squarepants'")
|
605
|
+
assert_not_nil s
|
606
|
+
assert_equal 1, s.scores.length
|
607
|
+
assert_equal 4.0, s.scores.first.grade
|
608
|
+
end
|
591
609
|
|
592
610
|
def test_subobjects_have_no_ids
|
593
611
|
@spongebob_addr.id
|
@@ -637,7 +655,7 @@ class MongoTest < Test::Unit::TestCase
|
|
637
655
|
assert_match /undefined method \`foobar\' for Track:Class/, ex.to_s
|
638
656
|
end
|
639
657
|
end
|
640
|
-
|
658
|
+
|
641
659
|
def test_adding_custom_attributes
|
642
660
|
s = Student.new(:silly_name => 'Yowza!')
|
643
661
|
s.save
|
@@ -653,22 +671,22 @@ class MongoTest < Test::Unit::TestCase
|
|
653
671
|
assert_match(/song: The Mayor Of Simpleton/, str)
|
654
672
|
assert_match(/song: King For A Day/, str)
|
655
673
|
end
|
656
|
-
|
657
|
-
|
658
|
-
#################
|
659
|
-
|
660
|
-
|
674
|
+
|
675
|
+
|
676
|
+
#################
|
677
|
+
|
678
|
+
|
661
679
|
def test_find_all_alias
|
662
680
|
assert_all_songs Track.all.inject('') { |str, t| str + t.to_s }
|
663
|
-
end
|
664
|
-
|
681
|
+
end
|
682
|
+
|
665
683
|
def test_find_first_alias
|
666
684
|
t = Track.first
|
667
685
|
assert t.kind_of?(Track)
|
668
686
|
str = t.to_s
|
669
687
|
assert_match(/artist: [^,]+,/, str, "did not find non-empty artist name")
|
670
688
|
end
|
671
|
-
|
689
|
+
|
672
690
|
def test_find_last
|
673
691
|
c = Course.new(:name=>"History")
|
674
692
|
c.save
|
@@ -698,7 +716,7 @@ class MongoTest < Test::Unit::TestCase
|
|
698
716
|
assert_equal(count, Playlist.count)
|
699
717
|
end
|
700
718
|
|
701
|
-
|
719
|
+
|
702
720
|
def test_update_attributes
|
703
721
|
opts = {:artist => 'Bon Jovi', :album => 'Slippery When Wet', :song => 'Livin On A Prayer'}
|
704
722
|
track = Track.new
|
@@ -706,7 +724,7 @@ class MongoTest < Test::Unit::TestCase
|
|
706
724
|
t = Track.find_by_artist("Bon Jovi")
|
707
725
|
assert_equal(t.album, "Slippery When Wet")
|
708
726
|
end
|
709
|
-
|
727
|
+
|
710
728
|
def test_update_attributes_for_custom_attributes
|
711
729
|
opts = {:artist => 'The Outfield', :album => 'Play Deep', :song => 'Your Love', :year => 1986}
|
712
730
|
playlist = Playlist.new
|
@@ -714,7 +732,7 @@ class MongoTest < Test::Unit::TestCase
|
|
714
732
|
p = Playlist.find_by_artist("The Outfield")
|
715
733
|
assert_equal(p.year, 1986)
|
716
734
|
end
|
717
|
-
|
735
|
+
|
718
736
|
def test_custom_id
|
719
737
|
track = Track.new
|
720
738
|
track.id = 123
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongodb-mongo_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.3"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Menard
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.6.
|
24
|
+
version: 0.6.7
|
25
25
|
version:
|
26
26
|
description: MongoRecord is an ActiveRecord-like framework for the 10gen Mongo database. For more information about Mongo, see http://www.mongodb.org.
|
27
27
|
email: mongodb-user@googlegroups.com
|