mongodb-mongo_record 0.2 → 0.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/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
|