mongodb-mongo_record 0.1.3 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mongo_record/base.rb +149 -53
- data/lib/mongo_record/convert.rb +21 -0
- data/mongo-activerecord-ruby.gemspec +1 -1
- data/tests/test_mongo.rb +100 -6
- metadata +1 -1
data/lib/mongo_record/base.rb
CHANGED
@@ -24,7 +24,7 @@ require 'mongo_record/sql'
|
|
24
24
|
class String
|
25
25
|
# Convert this String to an ObjectID.
|
26
26
|
def to_oid
|
27
|
-
XGen::Mongo::Driver::ObjectID.from_string(self)
|
27
|
+
XGen::Mongo::Driver::ObjectID.legal?(self) ? XGen::Mongo::Driver::ObjectID.from_string(self) : self
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -248,6 +248,12 @@ module MongoRecord
|
|
248
248
|
# This expression is run by the database server against each record
|
249
249
|
# found after the :conditions are run.
|
250
250
|
#
|
251
|
+
# This expression is run by the database server against each record
|
252
|
+
# found after the :conditions are run.
|
253
|
+
#
|
254
|
+
# <code>:criteria</code> - A hash field to pass in MongoDB conditional operators
|
255
|
+
# in a hash format. [$gt, $lt, $gte, $lte, $in, ect.]
|
256
|
+
#
|
251
257
|
# Examples for find by id:
|
252
258
|
# Person.find("48e5307114f4abdf00dfeb86") # returns the object for this ID
|
253
259
|
# Person.find(["a_hex_id", "another_hex_id"]) # returns a Cursor over these two objects
|
@@ -272,6 +278,7 @@ module MongoRecord
|
|
272
278
|
#
|
273
279
|
# Mongo-specific example:
|
274
280
|
# Person.find(:all, :where => "this.address.city == 'New York' || this.age = 42")
|
281
|
+
# Person.find(:all, :criteria => {"followers_count"=>{"$gte"=>410}})
|
275
282
|
#
|
276
283
|
# As a side note, the :order, :limit, and :offset options are passed
|
277
284
|
# on to the Cursor (after the :order option is rewritten to be a
|
@@ -279,17 +286,57 @@ module MongoRecord
|
|
279
286
|
# Person.find(:all, :offset => 10, :limit => 10, :order => :created_on)
|
280
287
|
# is the same as
|
281
288
|
# Person.find(:all).skip(10).limit(10).sort({:created_on => 1})
|
282
|
-
|
283
|
-
|
289
|
+
#
|
290
|
+
|
291
|
+
|
292
|
+
def find(*args)
|
293
|
+
options = extract_options_from_args!(args)
|
294
|
+
options.symbolize_keys!
|
284
295
|
case args.first
|
285
296
|
when :first
|
286
297
|
find_initial(options)
|
287
298
|
when :all
|
288
299
|
find_every(options)
|
300
|
+
when :last
|
301
|
+
find_last(options)
|
289
302
|
else
|
290
303
|
find_from_ids(args, options)
|
291
304
|
end
|
292
305
|
end
|
306
|
+
|
307
|
+
# Yields each record that was found by the find +options+. The find is
|
308
|
+
# performed by find.
|
309
|
+
#
|
310
|
+
# Example:
|
311
|
+
#
|
312
|
+
# Person.find_each(:conditions => "age > 21") do |person|
|
313
|
+
# person.party_all_night!
|
314
|
+
# end
|
315
|
+
|
316
|
+
def find_each(*args)
|
317
|
+
options = extract_options_from_args!(args)
|
318
|
+
options.symbolize_keys!
|
319
|
+
find_every(options).each do |record|
|
320
|
+
yield record
|
321
|
+
end
|
322
|
+
self
|
323
|
+
end
|
324
|
+
|
325
|
+
def all(*args)
|
326
|
+
options = extract_options_from_args!(args)
|
327
|
+
find_every(options)
|
328
|
+
end
|
329
|
+
|
330
|
+
def first(*args)
|
331
|
+
# args = ([:first]<<args).flatten
|
332
|
+
options = extract_options_from_args!(args)
|
333
|
+
find_initial(options)
|
334
|
+
end
|
335
|
+
|
336
|
+
def last(*args)
|
337
|
+
options = extract_options_from_args!(args)
|
338
|
+
find_last(options)
|
339
|
+
end
|
293
340
|
|
294
341
|
# Returns all records matching mql. Not yet implemented.
|
295
342
|
def find_by_mql(mql) # :nodoc:
|
@@ -299,7 +346,7 @@ module MongoRecord
|
|
299
346
|
|
300
347
|
# Returns the number of matching records.
|
301
348
|
def count(options={})
|
302
|
-
criteria = criteria_from(options[:conditions]).merge!(where_func(options[:where]))
|
349
|
+
criteria = criteria_from(options[:conditions],options[:criteria]).merge!(where_func(options[:where]))
|
303
350
|
begin
|
304
351
|
collection.count(criteria)
|
305
352
|
rescue => ex
|
@@ -314,6 +361,11 @@ module MongoRecord
|
|
314
361
|
end
|
315
362
|
end
|
316
363
|
|
364
|
+
def sum(column)
|
365
|
+
x = self.find(:all, :select=>column)
|
366
|
+
x.map {|p1| p1.followers_count}.compact.sum
|
367
|
+
end
|
368
|
+
|
317
369
|
# Deletes the record with the given id from the collection.
|
318
370
|
def delete(id)
|
319
371
|
collection.remove({:_id => id})
|
@@ -407,22 +459,38 @@ module MongoRecord
|
|
407
459
|
args.last.is_a?(Hash) ? args.pop : {}
|
408
460
|
end
|
409
461
|
|
462
|
+
# def find_initial(options)
|
463
|
+
# criteria = criteria_from(options[:conditions]).merge!(where_func(options[:where]))
|
464
|
+
# fields = fields_from(options[:select])
|
465
|
+
# row = collection.find_first(criteria, :fields => fields)
|
466
|
+
# (row.nil? || row['_id'] == nil) ? nil : self.new(row)
|
467
|
+
# end
|
468
|
+
|
410
469
|
def find_initial(options)
|
411
|
-
|
412
|
-
|
413
|
-
row =
|
414
|
-
|
470
|
+
options[:limit] = 1
|
471
|
+
options[:order] = 'created_at asc'
|
472
|
+
row = find_every(options)
|
473
|
+
row.to_a[0]
|
415
474
|
end
|
416
475
|
|
417
|
-
def
|
418
|
-
|
476
|
+
def find_last(options)
|
477
|
+
options[:limit] = 1
|
478
|
+
options[:order] = 'created_at desc'
|
479
|
+
row = find_every(options)
|
480
|
+
row.to_a[0]
|
481
|
+
end
|
419
482
|
|
483
|
+
def find_every(options)
|
484
|
+
options.symbolize_keys!
|
485
|
+
criteria = criteria_from(options[:conditions], options[:criteria]).merge!(where_func(options[:where]))
|
486
|
+
|
420
487
|
find_options = {}
|
421
488
|
find_options[:fields] = fields_from(options[:select]) if options[:select]
|
422
489
|
find_options[:limit] = options[:limit].to_i if options[:limit]
|
423
490
|
find_options[:offset] = options[:offset].to_i if options[:offset]
|
424
491
|
find_options[:sort] = sort_by_from(options[:order]) if options[:order]
|
425
492
|
|
493
|
+
|
426
494
|
cursor = collection.find(criteria, find_options)
|
427
495
|
|
428
496
|
# Override cursor.next_object so it returns a new instance of this class
|
@@ -434,7 +502,8 @@ module MongoRecord
|
|
434
502
|
ids = ids.to_a.flatten.compact.uniq
|
435
503
|
raise RecordNotFound, "Couldn't find #{name} without an ID" unless ids.length > 0
|
436
504
|
|
437
|
-
criteria = criteria_from(options[:conditions]).merge!(where_func(options[:where]))
|
505
|
+
criteria = criteria_from(options[:conditions], options[:criteria]).merge!(where_func(options[:where]))
|
506
|
+
criteria.merge!(options[:criteria]) unless options[:criteria].nil?
|
438
507
|
criteria[:_id] = ids_clause(ids)
|
439
508
|
fields = fields_from(options[:select])
|
440
509
|
|
@@ -446,6 +515,8 @@ module MongoRecord
|
|
446
515
|
find_options = {}
|
447
516
|
find_options[:fields] = fields if fields
|
448
517
|
find_options[:sort] = sort_by_from(options[:order]) if options[:order]
|
518
|
+
find_options[:limit] = options[:limit].to_i if options[:limit]
|
519
|
+
find_options[:offset] = options[:offset].to_i if options[:offset]
|
449
520
|
|
450
521
|
cursor = collection.find(criteria, find_options)
|
451
522
|
|
@@ -456,7 +527,13 @@ module MongoRecord
|
|
456
527
|
end
|
457
528
|
|
458
529
|
def ids_clause(ids)
|
459
|
-
ids.length == 1 ? ids[0].to_oid : {'$in' => ids.collect{|id| id.to_oid}}
|
530
|
+
#ids.length == 1 ? ids[0].to_oid : {'$in' => ids.collect{|id| id.to_oid}}
|
531
|
+
|
532
|
+
if ids.length == 1
|
533
|
+
ids[0].is_a?(String) ? ids[0].to_oid : ids[0]
|
534
|
+
else
|
535
|
+
{'$in' => ids.collect{|id| id.is_a?(String) ? id.to_oid : id}}
|
536
|
+
end
|
460
537
|
end
|
461
538
|
|
462
539
|
# Returns true if all field_names are in @field_names.
|
@@ -490,17 +567,20 @@ module MongoRecord
|
|
490
567
|
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns {:name => 'foo''bar', :group_id => 4}
|
491
568
|
# "name='foo''bar' and group_id='4'" returns {:name => 'foo''bar', :group_id => 4}
|
492
569
|
# { :name => "foo'bar", :group_id => 4 } returns the hash, modified for Mongo
|
493
|
-
def criteria_from(condition) # :nodoc:
|
570
|
+
def criteria_from(condition, criteria={}) # :nodoc:
|
494
571
|
case condition
|
495
572
|
when Array
|
496
|
-
criteria_from_array(condition)
|
573
|
+
opts = criteria_from_array(condition)
|
497
574
|
when String
|
498
|
-
criteria_from_string(condition)
|
575
|
+
opts = criteria_from_string(condition)
|
499
576
|
when Hash
|
500
|
-
criteria_from_hash(condition)
|
577
|
+
opts = criteria_from_hash(condition)
|
501
578
|
else
|
502
|
-
{}
|
503
|
-
end
|
579
|
+
opts = {}
|
580
|
+
end
|
581
|
+
opts ||= {}
|
582
|
+
criteria ||= {}
|
583
|
+
opts.merge!(criteria)
|
504
584
|
end
|
505
585
|
|
506
586
|
# Substitutes values at the end of an array into the string at its
|
@@ -529,11 +609,11 @@ module MongoRecord
|
|
529
609
|
condition.each { |k,v|
|
530
610
|
h[k] = case v
|
531
611
|
when Array
|
532
|
-
{'$in' =>
|
612
|
+
{'$in' => v}
|
533
613
|
when Range
|
534
614
|
{'$gte' => v.first, '$lte' => v.last}
|
535
615
|
else
|
536
|
-
|
616
|
+
v
|
537
617
|
end
|
538
618
|
}
|
539
619
|
h
|
@@ -691,7 +771,7 @@ module MongoRecord
|
|
691
771
|
|
692
772
|
# Save self and returns true if the save was successful, false if not.
|
693
773
|
def save
|
694
|
-
create_or_update
|
774
|
+
create_or_update
|
695
775
|
end
|
696
776
|
|
697
777
|
# Save self and returns true if the save was successful and raises
|
@@ -702,23 +782,31 @@ module MongoRecord
|
|
702
782
|
|
703
783
|
# Return true if this object is new---that is, does not yet have an id.
|
704
784
|
def new_record?
|
705
|
-
@_id
|
785
|
+
@_id.nil? || self.class.collection.find_first("_id" => @_id).nil?
|
706
786
|
end
|
707
787
|
|
708
788
|
# Convert this object to a Mongo value suitable for saving to the
|
709
789
|
# database.
|
710
790
|
def to_mongo_value
|
711
791
|
h = {}
|
712
|
-
self.class.mongo_ivar_names.each {|iv| h[iv] = instance_variable_get("@#{iv}").to_mongo_value }
|
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 }
|
713
800
|
h
|
714
801
|
end
|
715
802
|
|
716
803
|
# Save self to the database and set the id.
|
717
804
|
def create
|
718
|
-
|
805
|
+
create_date = self.instance_variable_defined?("@created_at") ? self.created_at : nil
|
806
|
+
set_create_times(create_date)
|
719
807
|
with_id = self.class.collection.insert(to_mongo_value)
|
720
808
|
@_id = with_id['_id'] || with_id[:_id]
|
721
|
-
|
809
|
+
with_id
|
722
810
|
end
|
723
811
|
|
724
812
|
# Save self to the database. Return +false+ if there was an error,
|
@@ -729,7 +817,7 @@ module MongoRecord
|
|
729
817
|
if self.class.collection.db.error?
|
730
818
|
return false
|
731
819
|
end
|
732
|
-
self
|
820
|
+
self
|
733
821
|
end
|
734
822
|
|
735
823
|
# Remove self from the database and set @_id to nil. If self has no
|
@@ -748,6 +836,24 @@ module MongoRecord
|
|
748
836
|
freeze
|
749
837
|
end
|
750
838
|
|
839
|
+
def [](attr_name)
|
840
|
+
self.send(attr_name)
|
841
|
+
end
|
842
|
+
|
843
|
+
def []=(attr_name, value)
|
844
|
+
self.class.field(attr_name)
|
845
|
+
self.send(attr_name.to_s + '=', value)
|
846
|
+
end
|
847
|
+
|
848
|
+
def method_missing(sym, *args)
|
849
|
+
if self.instance_variables.include?("@#{sym}")
|
850
|
+
self.class.field(sym)
|
851
|
+
return self.send(sym)
|
852
|
+
else
|
853
|
+
super
|
854
|
+
end
|
855
|
+
end
|
856
|
+
|
751
857
|
#--
|
752
858
|
# ================================================================
|
753
859
|
# These methods exist so we can plug in ActiveRecord validation, etc.
|
@@ -760,7 +866,7 @@ module MongoRecord
|
|
760
866
|
# made with this method doesn't get subjected to validation checks.
|
761
867
|
# Hence, attributes can be updated even if the full object isn't valid.
|
762
868
|
def update_attribute(name, value)
|
763
|
-
|
869
|
+
self[name] = value
|
764
870
|
save
|
765
871
|
end
|
766
872
|
|
@@ -768,8 +874,9 @@ module MongoRecord
|
|
768
874
|
# record. If the object is invalid, the saving will fail and false will
|
769
875
|
# be returned.
|
770
876
|
def update_attributes(attributes)
|
771
|
-
|
772
|
-
|
877
|
+
attributes.each do |name, value|
|
878
|
+
update_attribute(name, value)
|
879
|
+
end
|
773
880
|
end
|
774
881
|
|
775
882
|
# Updates an object just like Base.update_attributes but calls save!
|
@@ -784,6 +891,17 @@ module MongoRecord
|
|
784
891
|
|
785
892
|
# ================================================================
|
786
893
|
|
894
|
+
def set_create_times(t=nil)
|
895
|
+
t ||= Time.now
|
896
|
+
t = Time.parse(t) if t.is_a?(String)
|
897
|
+
self["created_at"] = t
|
898
|
+
self["created_on"] = Time.local(t.year, t.month, t.day)
|
899
|
+
self.class.subobjects.keys.each { |iv|
|
900
|
+
val = instance_variable_get("@#{iv}")
|
901
|
+
val.send(:set_create_times, t) if val
|
902
|
+
}
|
903
|
+
end
|
904
|
+
|
787
905
|
private
|
788
906
|
|
789
907
|
def create_or_update
|
@@ -805,32 +923,10 @@ module MongoRecord
|
|
805
923
|
end
|
806
924
|
end
|
807
925
|
|
808
|
-
def set_create_times(t=nil)
|
809
|
-
t ||= Time.now
|
810
|
-
self.class.field_names.each { |iv|
|
811
|
-
case iv
|
812
|
-
when :created_at
|
813
|
-
instance_variable_set("@#{iv}", t)
|
814
|
-
when :created_on
|
815
|
-
instance_variable_set("@#{iv}", Time.local(t.year, t.month, t.day))
|
816
|
-
end
|
817
|
-
}
|
818
|
-
self.class.subobjects.keys.each { |iv|
|
819
|
-
val = instance_variable_get("@#{iv}")
|
820
|
-
val.send(:set_create_times, t) if val
|
821
|
-
}
|
822
|
-
end
|
823
|
-
|
824
926
|
def set_update_times(t=nil)
|
825
927
|
t ||= Time.now
|
826
|
-
self
|
827
|
-
|
828
|
-
when :updated_at
|
829
|
-
instance_variable_set("@#{iv}", t)
|
830
|
-
when :updated_on
|
831
|
-
instance_variable_set("@#{iv}", Time.local(t.year, t.month, t.day))
|
832
|
-
end
|
833
|
-
}
|
928
|
+
self["updated_at"] = t
|
929
|
+
self["updated_on"] = Time.local(t.year, t.month, t.day)
|
834
930
|
self.class.subobjects.keys.each { |iv|
|
835
931
|
val = instance_variable_get("@#{iv}")
|
836
932
|
val.send(:set_update_times, t) if val
|
data/lib/mongo_record/convert.rb
CHANGED
@@ -24,6 +24,15 @@ class Object
|
|
24
24
|
def to_mongo_value
|
25
25
|
self
|
26
26
|
end
|
27
|
+
|
28
|
+
# From Rails
|
29
|
+
def instance_values #:nodoc:
|
30
|
+
instance_variables.inject({}) do |values, name|
|
31
|
+
values[name.to_s[1..-1]] = instance_variable_get(name)
|
32
|
+
values
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
27
36
|
end
|
28
37
|
|
29
38
|
class Array
|
@@ -42,4 +51,16 @@ class Hash
|
|
42
51
|
self.each {|k,v| h[k] = v.to_mongo_value}
|
43
52
|
h
|
44
53
|
end
|
54
|
+
|
55
|
+
# Same symbolize_keys method used in Rails
|
56
|
+
def symbolize_keys
|
57
|
+
inject({}) do |options, (key, value)|
|
58
|
+
options[(key.to_sym rescue key) || key] = value
|
59
|
+
options
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def symbolize_keys!
|
64
|
+
self.replace(self.symbolize_keys)
|
65
|
+
end
|
45
66
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'mongo_record'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.2'
|
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.'
|
data/tests/test_mongo.rb
CHANGED
@@ -23,7 +23,7 @@ require File.join(File.dirname(__FILE__), 'class_in_module')
|
|
23
23
|
|
24
24
|
class Track < MongoRecord::Base
|
25
25
|
collection_name :tracks
|
26
|
-
fields :artist, :album, :song, :track
|
26
|
+
fields :artist, :album, :song, :track, :created_at
|
27
27
|
def to_s
|
28
28
|
# Uses both accessor methods and ivars themselves
|
29
29
|
"artist: #{artist}, album: #{album}, song: #@song, track: #{@track ? @track.to_i : nil}"
|
@@ -39,6 +39,11 @@ class Rubytest < MongoRecord::Base
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
# Class without any fields defined to test inserting custom attributes
|
43
|
+
class Playlist < MongoRecord::Base
|
44
|
+
collection_name :playlists
|
45
|
+
end
|
46
|
+
|
42
47
|
class MongoTest < Test::Unit::TestCase
|
43
48
|
|
44
49
|
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
@@ -47,6 +52,7 @@ class MongoTest < Test::Unit::TestCase
|
|
47
52
|
@@students = @@db.collection('students')
|
48
53
|
@@courses = @@db.collection('courses')
|
49
54
|
@@tracks = @@db.collection('tracks')
|
55
|
+
@@playlists = @@db.collection('playlists')
|
50
56
|
|
51
57
|
def setup
|
52
58
|
super
|
@@ -55,6 +61,7 @@ class MongoTest < Test::Unit::TestCase
|
|
55
61
|
@@students.clear
|
56
62
|
@@courses.clear
|
57
63
|
@@tracks.clear
|
64
|
+
@@playlists.clear
|
58
65
|
|
59
66
|
# Manually insert data without using MongoRecord::Base
|
60
67
|
@@tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'Thomas Dolby', :album => 'Aliens Ate My Buick', :song => 'The Ability to Swing'})
|
@@ -80,6 +87,7 @@ class MongoTest < Test::Unit::TestCase
|
|
80
87
|
@@students.clear
|
81
88
|
@@courses.clear
|
82
89
|
@@tracks.clear
|
90
|
+
@@playlists.clear
|
83
91
|
super
|
84
92
|
end
|
85
93
|
|
@@ -131,6 +139,13 @@ class MongoTest < Test::Unit::TestCase
|
|
131
139
|
assert_equal(@mayor_str, Track.find_by_id(@mayor_id).to_s)
|
132
140
|
end
|
133
141
|
|
142
|
+
def test_find_by_custom_id
|
143
|
+
@@tracks.insert({:_id => 25, :artist => 'Mike D', :album => 'Awesome Blossom', :song => 'Hello World', :track => 5})
|
144
|
+
assert_equal("artist: Mike D, album: Awesome Blossom, song: Hello World, track: 5",
|
145
|
+
Track.find_by_id(25).to_s)
|
146
|
+
|
147
|
+
end
|
148
|
+
|
134
149
|
def test_find_by_song
|
135
150
|
assert_equal("artist: Thomas Dolby, album: Aliens Ate My Buick, song: Budapest by Blimp, track: ", Track.find_by_song('Budapest by Blimp').to_s)
|
136
151
|
end
|
@@ -149,7 +164,7 @@ class MongoTest < Test::Unit::TestCase
|
|
149
164
|
def test_find_all
|
150
165
|
assert_all_songs Track.find(:all).inject('') { |str, t| str + t.to_s }
|
151
166
|
end
|
152
|
-
|
167
|
+
|
153
168
|
def test_find_using_hash
|
154
169
|
str = Track.find(:all, :conditions => {:album => 'Aliens Ate My Buick'}).inject('') { |str, t| str + t.to_s }
|
155
170
|
assert_match(/song: The Ability to Swing/, str)
|
@@ -207,6 +222,7 @@ class MongoTest < Test::Unit::TestCase
|
|
207
222
|
x = Track.new(:artist => 'Level 42', :album => 'Standing In The Light', :song => 'Micro-Kid', :track => 1)
|
208
223
|
assert_nil(x.id)
|
209
224
|
assert x.save, "x.save returned false; expected true"
|
225
|
+
x = Track.last
|
210
226
|
assert_not_nil(x.id)
|
211
227
|
z = Track.find(x.id)
|
212
228
|
assert_equal(x.to_s, z.to_s)
|
@@ -233,16 +249,16 @@ class MongoTest < Test::Unit::TestCase
|
|
233
249
|
|
234
250
|
def test_raise_error_if_bogus_id
|
235
251
|
Track.find("bogus_id")
|
236
|
-
fail 'expected "
|
252
|
+
fail 'expected "find Track with ID=bogus_id" exception'
|
237
253
|
rescue => ex
|
238
|
-
assert_match /
|
254
|
+
assert_match /find Track with ID=bogus_id/, ex.to_s
|
239
255
|
end
|
240
256
|
|
241
257
|
def test_raise_error_if_first_and_bogus_id_in_hash
|
242
258
|
Track.find(:first, :conditions => {:_id => "bogus_id"})
|
243
|
-
fail 'expected "
|
259
|
+
fail 'expected "find Track with ID=bogus_id" exception'
|
244
260
|
rescue => ex
|
245
|
-
assert_match /
|
261
|
+
assert_match /find Track with ID=bogus_id/, ex.to_s
|
246
262
|
end
|
247
263
|
|
248
264
|
def test_find_options
|
@@ -621,6 +637,13 @@ class MongoTest < Test::Unit::TestCase
|
|
621
637
|
assert_match /undefined method \`foobar\' for Track:Class/, ex.to_s
|
622
638
|
end
|
623
639
|
end
|
640
|
+
|
641
|
+
def test_adding_custom_attributes
|
642
|
+
s = Student.new(:silly_name => 'Yowza!')
|
643
|
+
s.save
|
644
|
+
s = Student.last
|
645
|
+
assert_equal s.silly_name, 'Yowza!'
|
646
|
+
end
|
624
647
|
|
625
648
|
def assert_all_songs(str)
|
626
649
|
assert_match(/song: The Ability to Swing/, str)
|
@@ -630,5 +653,76 @@ class MongoTest < Test::Unit::TestCase
|
|
630
653
|
assert_match(/song: The Mayor Of Simpleton/, str)
|
631
654
|
assert_match(/song: King For A Day/, str)
|
632
655
|
end
|
656
|
+
|
657
|
+
|
658
|
+
#################
|
659
|
+
|
660
|
+
|
661
|
+
def test_find_all_alias
|
662
|
+
assert_all_songs Track.all.inject('') { |str, t| str + t.to_s }
|
663
|
+
end
|
664
|
+
|
665
|
+
def test_find_first_alias
|
666
|
+
t = Track.first
|
667
|
+
assert t.kind_of?(Track)
|
668
|
+
str = t.to_s
|
669
|
+
assert_match(/artist: [^,]+,/, str, "did not find non-empty artist name")
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_find_last
|
673
|
+
c = Course.new(:name=>"History")
|
674
|
+
c.save
|
675
|
+
assert_equal Course.last.name, "History"
|
676
|
+
end
|
677
|
+
|
678
|
+
def test_new_and_save_custom_attributes
|
679
|
+
x = Playlist.new(:artist => 'Level 42', :album => 'Standing In The Light', :song => 'Micro-Kid', :track => 1)
|
680
|
+
assert_nil(x.id)
|
681
|
+
x.save
|
682
|
+
x = Playlist.last
|
683
|
+
assert_not_nil(x.id)
|
684
|
+
assert_equal(x.artist, "Level 42")
|
685
|
+
assert_not_nil(x.created_at)
|
686
|
+
assert_not_nil(x.created_on)
|
687
|
+
end
|
688
|
+
|
689
|
+
def test_update_for_custom_attributes
|
690
|
+
p = Playlist.create(:artist => "The Beatles", :song => "Jailhouse Rock")
|
691
|
+
count = Playlist.count
|
692
|
+
p = Playlist.last
|
693
|
+
assert_equal(p.artist, "The Beatles")
|
694
|
+
p.artist = "Elvis"
|
695
|
+
p.save
|
696
|
+
assert_not_nil(p.updated_at)
|
697
|
+
assert_not_nil(p.updated_on)
|
698
|
+
assert_equal(count, Playlist.count)
|
699
|
+
end
|
700
|
+
|
701
|
+
|
702
|
+
def test_update_attributes
|
703
|
+
opts = {:artist => 'Bon Jovi', :album => 'Slippery When Wet', :song => 'Livin On A Prayer'}
|
704
|
+
track = Track.new
|
705
|
+
track.update_attributes(opts)
|
706
|
+
t = Track.find_by_artist("Bon Jovi")
|
707
|
+
assert_equal(t.album, "Slippery When Wet")
|
708
|
+
end
|
709
|
+
|
710
|
+
def test_update_attributes_for_custom_attributes
|
711
|
+
opts = {:artist => 'The Outfield', :album => 'Play Deep', :song => 'Your Love', :year => 1986}
|
712
|
+
playlist = Playlist.new
|
713
|
+
playlist.update_attributes(opts)
|
714
|
+
p = Playlist.find_by_artist("The Outfield")
|
715
|
+
assert_equal(p.year, 1986)
|
716
|
+
end
|
717
|
+
|
718
|
+
def test_custom_id
|
719
|
+
track = Track.new
|
720
|
+
track.id = 123
|
721
|
+
track.artist = "Nickleback"
|
722
|
+
track.song = "Rockstar"
|
723
|
+
track.save
|
724
|
+
p = Track.find(123)
|
725
|
+
assert_equal p.artist, "Nickleback"
|
726
|
+
end
|
633
727
|
|
634
728
|
end
|