mongo_mapper 0.7.1 → 0.7.2

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/Rakefile CHANGED
@@ -12,7 +12,7 @@ Jeweler::Tasks.new do |gem|
12
12
  gem.authors = ["John Nunemaker"]
13
13
  gem.version = MongoMapper::Version
14
14
 
15
- gem.add_dependency('activesupport', '>= 2.3')
15
+ gem.add_dependency('activesupport', '>= 2.3.4')
16
16
  gem.add_dependency('mongo', '0.19.1')
17
17
  gem.add_dependency('jnunemaker-validatable', '1.8.3')
18
18
 
@@ -6,7 +6,7 @@ require 'uri'
6
6
  # so i want to make sure that if you are using gems you do in fact have the correct versions
7
7
  # if there is a better way to do this, please enlighten me!
8
8
  if self.class.const_defined?(:Gem)
9
- gem 'activesupport', '>= 2.3'
9
+ gem 'activesupport', '>= 2.3.4'
10
10
  gem 'mongo', '0.19.1'
11
11
  gem 'jnunemaker-validatable', '1.8.3'
12
12
  end
@@ -315,6 +315,10 @@ module MongoMapper
315
315
  self.class.delete(id) unless new?
316
316
  end
317
317
 
318
+ def new?
319
+ @new
320
+ end
321
+
318
322
  def destroyed?
319
323
  @_destroyed == true
320
324
  end
@@ -38,6 +38,14 @@ module MongoMapper
38
38
  end
39
39
 
40
40
  module InstanceMethods
41
+ def destroyed?
42
+ !!_root_document.try(:destroyed?)
43
+ end
44
+
45
+ def new?
46
+ _root_document.try(:new?) || @new
47
+ end
48
+
41
49
  def save(options={})
42
50
  if result = _root_document.try(:save, options)
43
51
  @new = false
@@ -51,7 +59,7 @@ module MongoMapper
51
59
  end
52
60
  result
53
61
  end
54
-
62
+
55
63
  def _parent_document=(value)
56
64
  @_root_document = value._root_document
57
65
  @_parent_document = value
@@ -11,10 +11,10 @@ module MongoMapper
11
11
 
12
12
  private
13
13
  def find_target
14
- (@_values || []).map do |v|
15
- child = klass.load(v)
16
- assign_references(child)
17
- child
14
+ (@_values || []).map do |attrs|
15
+ klass.load(attrs).tap do |child|
16
+ assign_references(child)
17
+ end
18
18
  end
19
19
  end
20
20
  end
@@ -146,15 +146,9 @@ module MongoMapper
146
146
 
147
147
  module InstanceMethods
148
148
  def initialize(attrs={}, from_database=false)
149
- unless attrs.nil?
150
- provided_keys = attrs.keys.map { |k| k.to_s }
151
- unless provided_keys.include?('_id') || provided_keys.include?('id')
152
- write_key :_id, Mongo::ObjectID.new
153
- end
154
- end
155
-
156
- assign_type_if_present
157
-
149
+ default_id_value(attrs)
150
+ assign_type
151
+
158
152
  if from_database
159
153
  @new = false
160
154
  self.attributes = attrs
@@ -164,8 +158,8 @@ module MongoMapper
164
158
  end
165
159
  end
166
160
 
167
- def new?
168
- @new
161
+ def persisted?
162
+ !new? && !destroyed?
169
163
  end
170
164
 
171
165
  def attributes=(attrs)
@@ -175,9 +169,6 @@ module MongoMapper
175
169
  writer_method = "#{name}="
176
170
 
177
171
  if respond_to?(writer_method)
178
- if writer_method == '_root_document='
179
- puts "_root_document= #{value.inspect}"
180
- end
181
172
  self.send(writer_method, value)
182
173
  else
183
174
  self[name.to_s] = value
@@ -238,28 +229,33 @@ module MongoMapper
238
229
  write_key(name, value)
239
230
  end
240
231
 
241
- # @api public
242
232
  def keys
243
233
  self.class.keys
244
234
  end
245
235
 
246
- # @api private?
247
236
  def key_names
248
237
  keys.keys
249
238
  end
250
239
 
251
- # @api private?
252
240
  def non_embedded_keys
253
241
  keys.values.select { |key| !key.embeddable? }
254
242
  end
255
243
 
256
- # @api private?
257
244
  def embedded_keys
258
245
  keys.values.select { |key| key.embeddable? }
259
246
  end
260
247
 
261
248
  private
262
- def assign_type_if_present
249
+ def default_id_value(attrs)
250
+ unless attrs.nil?
251
+ provided_keys = attrs.keys.map { |k| k.to_s }
252
+ unless provided_keys.include?('_id') || provided_keys.include?('id')
253
+ write_key :_id, Mongo::ObjectID.new
254
+ end
255
+ end
256
+ end
257
+
258
+ def assign_type
263
259
  self._type = self.class.name if respond_to?(:_type=)
264
260
  end
265
261
 
@@ -81,6 +81,10 @@ module MongoMapper
81
81
  def push_uniq(hash)
82
82
  self.class.push_uniq({:_id => id}, hash)
83
83
  end
84
+
85
+ def pop(hash)
86
+ self.class.pop({:_id => id}, hash)
87
+ end
84
88
  end
85
89
  end
86
90
  end
@@ -7,13 +7,17 @@ module MongoMapper
7
7
 
8
8
  module InstanceMethods
9
9
  def to_param
10
- id.to_s
10
+ id.to_s if persisted?
11
11
  end
12
12
 
13
13
  def to_model
14
14
  self
15
15
  end
16
16
 
17
+ def to_key
18
+ [id] if persisted?
19
+ end
20
+
17
21
  def new_record?
18
22
  new?
19
23
  end
@@ -37,7 +37,7 @@ module MongoMapper
37
37
 
38
38
  def where_conditions(instance)
39
39
  conditions = {}
40
- conditions[attribute] = /#{instance[attribute].to_s}/i unless case_sensitive
40
+ conditions[attribute] = /^#{Regexp.escape(instance[attribute].to_s)}$/i unless case_sensitive
41
41
  conditions
42
42
  end
43
43
  end
@@ -65,8 +65,13 @@ module MongoMapper
65
65
  conditions.each_pair do |key, value|
66
66
  key = normalized_key(key)
67
67
 
68
- if model.object_id_key?(key) && value.is_a?(String)
69
- value = Mongo::ObjectID.from_string(value)
68
+ if model.object_id_key?(key)
69
+ case value
70
+ when String
71
+ value = Mongo::ObjectID.from_string(value)
72
+ when Array
73
+ value.map! { |id| ObjectId.to_mongo(id) }
74
+ end
70
75
  end
71
76
 
72
77
  if symbol_operator?(key)
@@ -102,8 +107,8 @@ module MongoMapper
102
107
 
103
108
  def normalized_value(field, value)
104
109
  case value
105
- when Array
106
- modifier?(field) ? value : {'$in' => value}
110
+ when Array, Set
111
+ modifier?(field) ? value.to_a : {'$in' => value.to_a}
107
112
  when Hash
108
113
  to_criteria(value, field)
109
114
  when Time
@@ -26,16 +26,14 @@ end
26
26
  class Boolean
27
27
  BOOLEAN_MAPPING = {
28
28
  true => true, 'true' => true, 'TRUE' => true, 'True' => true, 't' => true, 'T' => true, '1' => true, 1 => true, 1.0 => true,
29
- false => false, 'false' => false, 'FALSE' => false, 'False' => false, 'f' => false, 'F' => false, '0' => false, 0 => false, 0.0 => false, nil => false
29
+ false => false, 'false' => false, 'FALSE' => false, 'False' => false, 'f' => false, 'F' => false, '0' => false, 0 => false, 0.0 => false, nil => nil
30
30
  }
31
31
 
32
32
  def self.to_mongo(value)
33
33
  if value.is_a?(Boolean)
34
34
  value
35
35
  else
36
- v = BOOLEAN_MAPPING[value]
37
- v = value.to_s.downcase == 'true' if v.nil? # Check all mixed case spellings for true
38
- v
36
+ BOOLEAN_MAPPING[value]
39
37
  end
40
38
  end
41
39
 
@@ -1,3 +1,3 @@
1
1
  module MongoMapper
2
- Version = '0.7.1'
2
+ Version = '0.7.2'
3
3
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_mapper}
8
- s.version = "0.7.1"
8
+ s.version = "0.7.2"
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{2010-03-09}
12
+ s.date = %q{2010-03-26}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -120,7 +120,7 @@ Gem::Specification.new do |s|
120
120
  s.homepage = %q{http://github.com/jnunemaker/mongomapper}
121
121
  s.rdoc_options = ["--charset=UTF-8"]
122
122
  s.require_paths = ["lib"]
123
- s.rubygems_version = %q{1.3.5}
123
+ s.rubygems_version = %q{1.3.6}
124
124
  s.summary = %q{A Ruby Object Mapper for Mongo}
125
125
  s.test_files = [
126
126
  "test/active_model_lint_test.rb",
@@ -178,7 +178,7 @@ Gem::Specification.new do |s|
178
178
  s.specification_version = 3
179
179
 
180
180
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
181
- s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
181
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
182
182
  s.add_runtime_dependency(%q<mongo>, ["= 0.19.1"])
183
183
  s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.8.3"])
184
184
  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
@@ -186,7 +186,7 @@ Gem::Specification.new do |s|
186
186
  s.add_development_dependency(%q<timecop>, ["= 0.3.1"])
187
187
  s.add_development_dependency(%q<mocha>, ["= 0.9.8"])
188
188
  else
189
- s.add_dependency(%q<activesupport>, [">= 2.3"])
189
+ s.add_dependency(%q<activesupport>, [">= 2.3.4"])
190
190
  s.add_dependency(%q<mongo>, ["= 0.19.1"])
191
191
  s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.3"])
192
192
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
@@ -195,7 +195,7 @@ Gem::Specification.new do |s|
195
195
  s.add_dependency(%q<mocha>, ["= 0.9.8"])
196
196
  end
197
197
  else
198
- s.add_dependency(%q<activesupport>, [">= 2.3"])
198
+ s.add_dependency(%q<activesupport>, [">= 2.3.4"])
199
199
  s.add_dependency(%q<mongo>, ["= 0.19.1"])
200
200
  s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.3"])
201
201
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
@@ -1,4 +1,6 @@
1
1
  require 'test_helper'
2
+ # For testing against edge rails also.
3
+ # $:.unshift '/Users/jnunemaker/dev/ruby/rails/activemodel/lib'
2
4
  require 'active_model'
3
5
  require 'models'
4
6
 
@@ -290,17 +290,25 @@ class DocumentTest < Test::Unit::TestCase
290
290
  @document.find(@doc1._id, @doc2._id).should == [@doc1, @doc2]
291
291
  end
292
292
 
293
+ should "work as arguments with string ids" do
294
+ @document.find(@doc1._id.to_s, @doc2._id.to_s).should == [@doc1, @doc2]
295
+ end
296
+
293
297
  should "work as array" do
294
298
  @document.find([@doc1._id, @doc2._id]).should == [@doc1, @doc2]
295
299
  end
296
300
 
301
+ should "work as array with string ids" do
302
+ @document.find([@doc1._id.to_s, @doc2._id.to_s]).should == [@doc1, @doc2]
303
+ end
304
+
297
305
  should "compact not found when using find" do
298
- @document.find(@doc1._id, 1234).should == [@doc1]
306
+ @document.find(@doc1._id, Mongo::ObjectID.new.to_s).should == [@doc1]
299
307
  end
300
308
 
301
309
  should "raise error if not all found when using find!" do
302
310
  assert_raises(MongoMapper::DocumentNotFound) do
303
- @document.find!(@doc1._id, 1234)
311
+ @document.find!(@doc1._id, Mongo::ObjectID.new.to_s)
304
312
  end
305
313
  end
306
314
 
@@ -908,6 +916,28 @@ class DocumentTest < Test::Unit::TestCase
908
916
  end
909
917
  end
910
918
 
919
+ context "#persisted?" do
920
+ setup do
921
+ @doc = @document.new(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
922
+ end
923
+
924
+ should "be false if new" do
925
+ @doc.should_not be_persisted
926
+ end
927
+
928
+ should "be false if destroyed" do
929
+ @doc.save
930
+ @doc.destroy
931
+ @doc.should be_destroyed
932
+ @doc.should_not be_persisted
933
+ end
934
+
935
+ should "be true if not new or destroyed" do
936
+ @doc.save
937
+ @doc.should be_persisted
938
+ end
939
+ end
940
+
911
941
  context "Single collection inheritance" do
912
942
  setup do
913
943
  class ::DocParent
@@ -53,31 +53,93 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
53
53
  doc1.reload.message.class.should be(Enter)
54
54
  end
55
55
 
56
- context "new?" do
56
+ context "new? (embedded key)" do
57
57
  setup do
58
58
  @klass.key :foo, @address_class
59
59
  end
60
60
 
61
- should "be new until document is saved" do
61
+ should "be true until document is saved" do
62
62
  address = @address_class.new(:city => 'South Bend', :state => 'IN')
63
63
  doc = @klass.new(:foo => address)
64
- address.new?.should == true
64
+ address.new?.should be_true
65
65
  end
66
66
 
67
- should "not be new after document is saved" do
67
+ should "be false after document is saved" do
68
68
  address = @address_class.new(:city => 'South Bend', :state => 'IN')
69
69
  doc = @klass.new(:foo => address)
70
70
  doc.save
71
- doc.foo.new?.should == false
71
+ doc.foo.new?.should be_false
72
72
  end
73
73
 
74
- should "not be new when document is read back" do
74
+ should "be false when loaded from database" do
75
75
  address = @address_class.new(:city => 'South Bend', :state => 'IN')
76
76
  doc = @klass.new(:foo => address)
77
77
  doc.save
78
78
 
79
- doc = doc.reload
80
- doc.foo.new?.should == false
79
+ doc.reload
80
+ doc.foo.new?.should be_false
81
+ end
82
+ end
83
+
84
+ context "new? (embedded association)" do
85
+ setup do
86
+ @doc = @klass.new(:pets => [{:name => 'poo bear'}])
87
+ end
88
+
89
+ should "be true until document is saved" do
90
+ @doc.should be_new
91
+ @doc.pets.first.should be_new
92
+ end
93
+
94
+ should "be false after document is saved" do
95
+ @doc.save
96
+ @doc.pets.first.should_not be_new
97
+ end
98
+
99
+ should "be false when loaded from database" do
100
+ @doc.save
101
+ @doc.pets.first.should_not be_new
102
+ @doc.reload
103
+ @doc.pets.first.should_not be_new
104
+ end
105
+ end
106
+
107
+ context "#destroyed?" do
108
+ setup do
109
+ @doc = @klass.create(:pets => [@pet_klass.new(:name => 'sparky')])
110
+ end
111
+
112
+ should "be false if root document is not destroyed" do
113
+ @doc.should_not be_destroyed
114
+ @doc.pets.first.should_not be_destroyed
115
+ end
116
+
117
+ should "be true if root document is destroyed" do
118
+ @doc.destroy
119
+ @doc.should be_destroyed
120
+ @doc.pets.first.should be_destroyed
121
+ end
122
+ end
123
+
124
+ context "#persisted?" do
125
+ setup do
126
+ @doc = @klass.new(:name => 'persisted doc', :pets => [@pet_klass.new(:name => 'persisted pet')])
127
+ end
128
+
129
+ should_eventually "be false if new" do
130
+ @doc.pets.first.should_not be_persisted
131
+ end
132
+
133
+ should "be false if destroyed" do
134
+ @doc.save
135
+ @doc.destroy
136
+ @doc.pets.first.should be_destroyed
137
+ @doc.pets.first.should_not be_persisted
138
+ end
139
+
140
+ should "be true if not new or destroyed" do
141
+ @doc.save
142
+ @doc.pets.first.should be_persisted
81
143
  end
82
144
  end
83
145