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 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
@@ -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, :_update)
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
- # self.class.mongo_ivar_names.each {|iv| h[iv] = instance_variable_get("@#{iv}").to_mongo_value }
793
- mongo_values = self.instance_values
794
- # If the "_id" value is not set but an "id" value is, set "_id" equal to "id"
795
- if mongo_values["_id"].nil? && !mongo_values["id"].nil?
796
- mongo_values["_id"] = mongo_values["id"]
797
- end
798
- key_names = mongo_values.keys + self.class.subobjects.keys + self.class.arrays.keys
799
- key_names.each {|key| h[key] = instance_variable_get("@#{key}").to_mongo_value }
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| v.kind_of?(MongoRecord::Base) ? v : klazz.new(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.2'
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.1'])
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
- # TODO this should work, but the database does not yet sort this properly
275
- # tracks = Track.find(:all, :order => "artist desc, song")
276
- # assert_not_nil tracks
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
- # # TODO dbrefs are not yet implemented
564
- # # This reproduces a bug where DBRefs weren't being created properly because
565
- # # the MongoRecord::Base objects weren't storing the magic _ns, _update, and
566
- # # other values set by the database.
567
- # def test_db_ref
568
- # s = Student.new(:name => 'Spongebob Squarepants', :address => @spongebob_addr)
569
- # s.save
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
- # @course1.save
572
- # assert_not_nil @course1.id
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
- # s.add_score(@course1.id, 3.5)
575
- # s.save # This used to blow up
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
- # # Now change the name of @course1 and see the student's score's course
582
- # # name change.
583
- # @course1.name = 'changed'
584
- # @course1.save
589
+ # Now try with has_many
590
+ score.save
591
+ s.scores = [score]
592
+ s.save
585
593
 
586
- # s = Student.find(:first, :conditions => "name = 'Spongebob Squarepants'")
587
- # assert_not_nil s
588
- # assert_equal 1, s.scores.length
589
- # assert_equal 'changed', s.scores.first.for_course.name
590
- # end
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.2"
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.1
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