mongo_mapper 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
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