mongo_mapper-unstable 2009.11.8 → 2009.11.18

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.
Files changed (42) hide show
  1. data/Rakefile +3 -3
  2. data/VERSION +1 -1
  3. data/bin/mmconsole +10 -5
  4. data/lib/mongo_mapper.rb +28 -5
  5. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +1 -1
  6. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +1 -1
  7. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +2 -2
  8. data/lib/mongo_mapper/associations/many_documents_proxy.rb +2 -2
  9. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +2 -1
  10. data/lib/mongo_mapper/document.rb +3 -12
  11. data/lib/mongo_mapper/embedded_document.rb +37 -19
  12. data/lib/mongo_mapper/finder_options.rb +17 -11
  13. data/lib/mongo_mapper/rails_compatibility/document.rb +4 -0
  14. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +4 -0
  15. data/lib/mongo_mapper/serializers/json_serializer.rb +2 -2
  16. data/lib/mongo_mapper/support.rb +16 -44
  17. data/lib/mongo_mapper/types.rb +64 -0
  18. data/lib/mongo_mapper/validations.rb +1 -1
  19. data/mongo_mapper.gemspec +15 -12
  20. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +10 -10
  21. data/test/functional/associations/test_belongs_to_proxy.rb +2 -1
  22. data/test/functional/associations/test_many_documents_as_proxy.rb +13 -12
  23. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +34 -34
  24. data/test/functional/associations/test_many_embedded_proxy.rb +22 -22
  25. data/test/functional/associations/test_many_polymorphic_proxy.rb +10 -10
  26. data/test/functional/associations/test_many_proxy.rb +14 -15
  27. data/test/functional/test_associations.rb +4 -4
  28. data/test/functional/test_binary.rb +1 -1
  29. data/test/functional/test_dirty.rb +6 -6
  30. data/test/functional/test_document.rb +64 -65
  31. data/test/functional/test_embedded_document.rb +34 -14
  32. data/test/functional/test_string_id_compatibility.rb +72 -0
  33. data/test/functional/test_validations.rb +1 -1
  34. data/test/models.rb +24 -24
  35. data/test/unit/test_document.rb +7 -4
  36. data/test/unit/test_embedded_document.rb +47 -5
  37. data/test/unit/test_finder_options.rb +22 -3
  38. data/test/unit/test_mongo_mapper.rb +65 -0
  39. data/test/unit/test_rails_compatibility.rb +14 -0
  40. data/test/unit/test_support.rb +45 -0
  41. metadata +8 -5
  42. data/test/unit/test_mongomapper.rb +0 -28
@@ -51,7 +51,7 @@ module MongoMapper #:nodoc:
51
51
  # "permalink": "1-konata-izumi"}
52
52
  def to_json(options={})
53
53
  apply_to_json_defaults(options)
54
-
54
+
55
55
  if include_root_in_json
56
56
  "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
57
57
  else
@@ -75,7 +75,7 @@ module MongoMapper #:nodoc:
75
75
  @json_class_name ||= name.demodulize.underscore.inspect
76
76
  end
77
77
  end
78
-
78
+
79
79
  private
80
80
  def apply_to_json_defaults(options)
81
81
  unless options[:only]
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  class BasicObject #:nodoc:
2
4
  instance_methods.each { |m| undef_method m unless m =~ /(^__|instance_eval)/ }
3
5
  end unless defined?(BasicObject)
@@ -13,34 +15,6 @@ class Array
13
15
  end
14
16
  end
15
17
 
16
- class Binary
17
- def self.to_mongo(value)
18
- if value.is_a?(ByteBuffer)
19
- value
20
- else
21
- value.nil? ? nil : ByteBuffer.new(value)
22
- end
23
- end
24
-
25
- def self.from_mongo(value)
26
- value
27
- end
28
- end
29
-
30
- class Boolean
31
- def self.to_mongo(value)
32
- if value.is_a?(Boolean)
33
- value
34
- else
35
- ['true', 't', '1'].include?(value.to_s.downcase)
36
- end
37
- end
38
-
39
- def self.from_mongo(value)
40
- !!value
41
- end
42
- end
43
-
44
18
  class Date
45
19
  def self.to_mongo(value)
46
20
  date = Date.parse(value.to_s)
@@ -120,6 +94,16 @@ class Object
120
94
  end
121
95
  end
122
96
 
97
+ class Set
98
+ def self.to_mongo(value)
99
+ value.to_a
100
+ end
101
+
102
+ def self.from_mongo(value)
103
+ Set.new(value || [])
104
+ end
105
+ end
106
+
123
107
  class String
124
108
  def self.to_mongo(value)
125
109
  value.nil? ? nil : value.to_s
@@ -138,33 +122,21 @@ class Symbol
138
122
  end
139
123
  end
140
124
 
141
- class Time
125
+ class Time
142
126
  def self.to_mongo(value)
143
127
  if value.nil? || value == ''
144
128
  nil
145
129
  else
146
- to_utc_time(value)
130
+ time = MongoMapper.time_class.parse(value.to_s)
131
+ time && time.utc
147
132
  end
148
133
  end
149
134
 
150
135
  def self.from_mongo(value)
151
- if Time.respond_to?(:zone) && Time.zone && value.present?
136
+ if MongoMapper.use_time_zone? && value.present?
152
137
  value.in_time_zone(Time.zone)
153
138
  else
154
139
  value
155
140
  end
156
141
  end
157
-
158
- def self.to_utc_time(value)
159
- to_local_time(value).try(:utc)
160
- end
161
-
162
- # make sure we have a time and that it is local
163
- def self.to_local_time(value)
164
- if Time.respond_to?(:zone) && Time.zone
165
- Time.zone.parse(value.to_s)
166
- else
167
- Time.parse(value.to_s)
168
- end
169
- end
170
142
  end
@@ -0,0 +1,64 @@
1
+ module MongoMapper
2
+ module Types
3
+ class Binary
4
+ def self.to_mongo(value)
5
+ if value.is_a?(ByteBuffer)
6
+ value
7
+ else
8
+ value.nil? ? nil : ByteBuffer.new(value)
9
+ end
10
+ end
11
+
12
+ def self.from_mongo(value)
13
+ value
14
+ end
15
+ end
16
+
17
+ class Boolean
18
+ def self.to_mongo(value)
19
+ if value.is_a?(Boolean)
20
+ value
21
+ else
22
+ ['true', 't', '1'].include?(value.to_s.downcase)
23
+ end
24
+ end
25
+
26
+ def self.from_mongo(value)
27
+ !!value
28
+ end
29
+ end
30
+
31
+ class ObjectId
32
+ def self.to_mongo(value)
33
+ if value.nil?
34
+ nil
35
+ elsif value.is_a?(Mongo::ObjectID)
36
+ value
37
+ else
38
+ Mongo::ObjectID.from_string(value.to_s)
39
+ end
40
+ end
41
+
42
+ def self.from_mongo(value)
43
+ value
44
+ end
45
+ end
46
+
47
+ # This allows using just Boolean when defining
48
+ # keys instead of MongoMapper::Types::Boolean
49
+ module Lookup
50
+ def const_missing(name)
51
+ if MongoMapper::Types.const_defined?(name)
52
+ MongoMapper::Types.const_get(name)
53
+ else
54
+ super
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # This was required to get in front of ActiveSupports Class#const_missing
62
+ Class.instance_eval do
63
+ include MongoMapper::Types::Lookup
64
+ end
@@ -15,7 +15,7 @@ module MongoMapper
15
15
  return true if allow_blank && value.blank?
16
16
  base_conditions = case_sensitive ? {self.attribute => value} : {}
17
17
  doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
18
- doc.nil? || instance.id == doc.id
18
+ doc.nil? || instance._id == doc._id
19
19
  end
20
20
 
21
21
  def message(instance)
data/mongo_mapper.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_mapper}
8
- s.version = "0.5.8"
8
+ s.version = "0.6.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-10-29}
12
+ s.date = %q{2009-11-17}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  "lib/mongo_mapper/serialization.rb",
51
51
  "lib/mongo_mapper/serializers/json_serializer.rb",
52
52
  "lib/mongo_mapper/support.rb",
53
+ "lib/mongo_mapper/types.rb",
53
54
  "lib/mongo_mapper/validations.rb",
54
55
  "mongo_mapper.gemspec",
55
56
  "specs.watchr",
@@ -70,6 +71,7 @@ Gem::Specification.new do |s|
70
71
  "test/functional/test_logger.rb",
71
72
  "test/functional/test_pagination.rb",
72
73
  "test/functional/test_rails_compatibility.rb",
74
+ "test/functional/test_string_id_compatibility.rb",
73
75
  "test/functional/test_validations.rb",
74
76
  "test/models.rb",
75
77
  "test/support/custom_matchers.rb",
@@ -82,7 +84,7 @@ Gem::Specification.new do |s|
82
84
  "test/unit/test_embedded_document.rb",
83
85
  "test/unit/test_finder_options.rb",
84
86
  "test/unit/test_key.rb",
85
- "test/unit/test_mongomapper.rb",
87
+ "test/unit/test_mongo_mapper.rb",
86
88
  "test/unit/test_observing.rb",
87
89
  "test/unit/test_pagination.rb",
88
90
  "test/unit/test_rails_compatibility.rb",
@@ -113,6 +115,7 @@ Gem::Specification.new do |s|
113
115
  "test/functional/test_logger.rb",
114
116
  "test/functional/test_pagination.rb",
115
117
  "test/functional/test_rails_compatibility.rb",
118
+ "test/functional/test_string_id_compatibility.rb",
116
119
  "test/functional/test_validations.rb",
117
120
  "test/models.rb",
118
121
  "test/support/custom_matchers.rb",
@@ -125,7 +128,7 @@ Gem::Specification.new do |s|
125
128
  "test/unit/test_embedded_document.rb",
126
129
  "test/unit/test_finder_options.rb",
127
130
  "test/unit/test_key.rb",
128
- "test/unit/test_mongomapper.rb",
131
+ "test/unit/test_mongo_mapper.rb",
129
132
  "test/unit/test_observing.rb",
130
133
  "test/unit/test_pagination.rb",
131
134
  "test/unit/test_rails_compatibility.rb",
@@ -141,29 +144,29 @@ Gem::Specification.new do |s|
141
144
 
142
145
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
143
146
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
144
- s.add_runtime_dependency(%q<mongo>, ["= 0.16"])
147
+ s.add_runtime_dependency(%q<mongo>, ["= 0.17.1"])
145
148
  s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
146
149
  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
147
150
  s.add_development_dependency(%q<shoulda>, ["= 2.10.2"])
148
151
  s.add_development_dependency(%q<timecop>, ["= 0.3.1"])
149
- s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
152
+ s.add_development_dependency(%q<mocha>, ["= 0.9.8"])
150
153
  else
151
154
  s.add_dependency(%q<activesupport>, [">= 2.3"])
152
- s.add_dependency(%q<mongo>, ["= 0.16"])
153
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
155
+ s.add_dependency(%q<mongo>, ["= 0.17.1"])
156
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
154
157
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
155
158
  s.add_dependency(%q<shoulda>, ["= 2.10.2"])
156
159
  s.add_dependency(%q<timecop>, ["= 0.3.1"])
157
- s.add_dependency(%q<mocha>, ["= 0.9.4"])
160
+ s.add_dependency(%q<mocha>, ["= 0.9.8"])
158
161
  end
159
162
  else
160
163
  s.add_dependency(%q<activesupport>, [">= 2.3"])
161
- s.add_dependency(%q<mongo>, ["= 0.16"])
162
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
164
+ s.add_dependency(%q<mongo>, ["= 0.17.1"])
165
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
163
166
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
164
167
  s.add_dependency(%q<shoulda>, ["= 2.10.2"])
165
168
  s.add_dependency(%q<timecop>, ["= 0.3.1"])
166
- s.add_dependency(%q<mocha>, ["= 0.9.4"])
169
+ s.add_dependency(%q<mocha>, ["= 0.9.8"])
167
170
  end
168
171
  end
169
172
 
@@ -19,11 +19,11 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
19
19
  status.target = project
20
20
  status.save.should be_true
21
21
 
22
- from_db = Status.find(status.id)
23
- from_db.target.nil?.should be_false
24
- from_db.target_id.should == project.id
25
- from_db.target_type.should == "Project"
26
- from_db.target.name.should == "mongomapper"
22
+ status = status.reload
23
+ status.target.nil?.should be_false
24
+ status.target_id.should == project._id
25
+ status.target_type.should == "Project"
26
+ status.target.name.should == "mongomapper"
27
27
  end
28
28
 
29
29
  should "unset the association" do
@@ -32,11 +32,11 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
32
32
  status.target = project
33
33
  status.save.should be_true
34
34
 
35
- from_db = Status.find(status.id)
36
- from_db.target = nil
37
- from_db.target_type.nil?.should be_true
38
- from_db.target_id.nil?.should be_true
39
- from_db.target.nil?.should be_true
35
+ status = status.reload
36
+ status.target = nil
37
+ status.target_type.nil?.should be_true
38
+ status.target_id.nil?.should be_true
39
+ status.target.nil?.should be_true
40
40
  end
41
41
 
42
42
  context "association id set but document not found" do
@@ -42,6 +42,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
42
42
  end
43
43
 
44
44
  should "return nil if id set but document not found" do
45
- @comment_class.new(:name => 'Foo', :post_id => '1234').post.nil?.should be_true
45
+ id = Mongo::ObjectID.new
46
+ @comment_class.new(:name => 'Foo', :post_id => id).post.nil?.should be_true
46
47
  end
47
48
  end
@@ -35,19 +35,20 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
35
35
  PostComment.new(:body => 'baz')
36
36
  ]
37
37
  }.should change { PostComment.count }.by(3)
38
-
39
- from_db = Post.find(post.id)
40
- from_db.comments.size.should == 3
41
- from_db.comments[0].body.should == 'foo'
42
- from_db.comments[1].body.should == 'bar'
43
- from_db.comments[2].body.should == 'baz'
38
+
39
+ post = post.reload
40
+ post.comments.size.should == 3
41
+ bodies = post.comments.collect(&:body)
42
+ bodies.should include('foo')
43
+ bodies.should include('bar')
44
+ bodies.should include('baz')
44
45
  end
45
46
 
46
47
  context "build" do
47
48
  should "assign foreign key" do
48
49
  post = Post.new
49
50
  comment = post.comments.build
50
- comment.commentable_id.should == post.id
51
+ comment.commentable_id.should == post._id
51
52
  end
52
53
 
53
54
  should "assign _type" do
@@ -67,7 +68,7 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
67
68
  should "assign foreign key" do
68
69
  post = Post.new
69
70
  comment = post.comments.create
70
- comment.commentable_id.should == post.id
71
+ comment.commentable_id.should == post._id
71
72
  end
72
73
 
73
74
  should "assign _type" do
@@ -166,25 +167,25 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
166
167
 
167
168
  context "with one id" do
168
169
  should "work for id in association" do
169
- @post.comments.find(@comment2.id).should == @comment2
170
+ @post.comments.find(@comment2._id).should == @comment2
170
171
  end
171
172
 
172
173
  should "not work for id not in association" do
173
174
  lambda {
174
- @post.comments.find!(@comment5.id)
175
+ @post.comments.find!(@comment5._id)
175
176
  }.should raise_error(MongoMapper::DocumentNotFound)
176
177
  end
177
178
  end
178
179
 
179
180
  context "with multiple ids" do
180
181
  should "work for ids in association" do
181
- posts = @post.comments.find!(@comment1.id, @comment2.id)
182
+ posts = @post.comments.find!(@comment1._id, @comment2._id)
182
183
  posts.should == [@comment1, @comment2]
183
184
  end
184
185
 
185
186
  should "not work for ids not in association" do
186
187
  lambda {
187
- @post.comments.find!(@comment1.id, @comment2.id, @comment4.id)
188
+ @post.comments.find!(@comment1._id, @comment2._id, @comment4._id)
188
189
  }.should raise_error(MongoMapper::DocumentNotFound)
189
190
  end
190
191
  end
@@ -24,9 +24,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
24
24
  catalog.medias = [Video.new("file" => "video.mpg", "length" => 3600)]
25
25
  catalog.save.should be_true
26
26
 
27
- from_db = Catalog.find(catalog.id)
28
- from_db.medias.size.should == 1
29
- from_db.medias[0].file.should == "video.mpg"
27
+ catalog = catalog.reload
28
+ catalog.medias.size.should == 1
29
+ catalog.medias[0].file.should == "video.mpg"
30
30
  end
31
31
 
32
32
  should "store different associations" do
@@ -38,15 +38,15 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
38
38
  ]
39
39
  catalog.save.should be_true
40
40
 
41
- from_db = Catalog.find(catalog.id)
42
- from_db.medias.size.should == 3
43
- from_db.medias[0].file.should == "video.mpg"
44
- from_db.medias[0].length.should == 3600
45
- from_db.medias[1].file.should == "music.mp3"
46
- from_db.medias[1].bitrate.should == "128kbps"
47
- from_db.medias[2].file.should == "image.png"
48
- from_db.medias[2].width.should == 800
49
- from_db.medias[2].height.should == 600
41
+ catalog = catalog.reload
42
+ catalog.medias.size.should == 3
43
+ catalog.medias[0].file.should == "video.mpg"
44
+ catalog.medias[0].length.should == 3600
45
+ catalog.medias[1].file.should == "music.mp3"
46
+ catalog.medias[1].bitrate.should == "128kbps"
47
+ catalog.medias[2].file.should == "image.png"
48
+ catalog.medias[2].width.should == 800
49
+ catalog.medias[2].height.should == 600
50
50
  end
51
51
 
52
52
  context "With modularized models" do
@@ -75,16 +75,16 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
75
75
  fleet.transports[2].year.should == 2008
76
76
  fleet.save.should be_true
77
77
 
78
- from_db = TrModels::Fleet.find(fleet.id)
79
- from_db.transports.size.should == 3
80
- from_db.transports[0].license_plate.should == "GGG123"
81
- from_db.transports[0].icu.should be_true
82
- from_db.transports[1].license_plate.should == "ABC123"
83
- from_db.transports[1].model.should == "VW Golf"
84
- from_db.transports[1].year.should == 2001
85
- from_db.transports[2].license_plate.should == "DEF123"
86
- from_db.transports[2].model.should == "Honda Accord"
87
- from_db.transports[2].year.should == 2008
78
+ fleet = fleet.reload
79
+ fleet.transports.size.should == 3
80
+ fleet.transports[0].license_plate.should == "GGG123"
81
+ fleet.transports[0].icu.should be_true
82
+ fleet.transports[1].license_plate.should == "ABC123"
83
+ fleet.transports[1].model.should == "VW Golf"
84
+ fleet.transports[1].year.should == 2001
85
+ fleet.transports[2].license_plate.should == "DEF123"
86
+ fleet.transports[2].model.should == "Honda Accord"
87
+ fleet.transports[2].year.should == 2008
88
88
  end
89
89
 
90
90
  should "default reader to empty array" do
@@ -104,9 +104,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
104
104
  fleet.transports = [TrModels::Car.new("license_plate" => "DCU2013", "model" => "Honda Civic")]
105
105
  fleet.save.should be_true
106
106
 
107
- from_db = TrModels::Fleet.find(fleet.id)
108
- from_db.transports.size.should == 1
109
- from_db.transports[0].license_plate.should == "DCU2013"
107
+ fleet = fleet.reload
108
+ fleet.transports.size.should == 1
109
+ fleet.transports[0].license_plate.should == "DCU2013"
110
110
  end
111
111
 
112
112
  should "store different associations" do
@@ -118,15 +118,15 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
118
118
  ]
119
119
  fleet.save.should be_true
120
120
 
121
- from_db = TrModels::Fleet.find(fleet.id)
122
- from_db.transports.size.should == 3
123
- from_db.transports[0].license_plate.should == "ABC1223"
124
- from_db.transports[0].model.should == "Honda Civic"
125
- from_db.transports[0].year.should == 2003
126
- from_db.transports[1].license_plate.should == "XYZ9090"
127
- from_db.transports[1].max_passengers.should == 51
128
- from_db.transports[2].license_plate.should == "HDD3030"
129
- from_db.transports[2].icu.should == true
121
+ fleet = fleet.reload
122
+ fleet.transports.size.should == 3
123
+ fleet.transports[0].license_plate.should == "ABC1223"
124
+ fleet.transports[0].model.should == "Honda Civic"
125
+ fleet.transports[0].year.should == 2003
126
+ fleet.transports[1].license_plate.should == "XYZ9090"
127
+ fleet.transports[1].max_passengers.should == 51
128
+ fleet.transports[2].license_plate.should == "HDD3030"
129
+ fleet.transports[2].icu.should == true
130
130
  end
131
131
  end
132
132