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 +1 -1
- data/lib/mongo_mapper.rb +1 -1
- data/lib/mongo_mapper/document.rb +4 -0
- data/lib/mongo_mapper/embedded_document.rb +9 -1
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +4 -4
- data/lib/mongo_mapper/plugins/keys.rb +15 -19
- data/lib/mongo_mapper/plugins/modifiers.rb +4 -0
- data/lib/mongo_mapper/plugins/rails.rb +5 -1
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/query.rb +9 -4
- data/lib/mongo_mapper/support.rb +2 -4
- data/lib/mongo_mapper/version.rb +1 -1
- data/mongo_mapper.gemspec +6 -6
- data/test/active_model_lint_test.rb +2 -0
- data/test/functional/test_document.rb +32 -2
- data/test/functional/test_embedded_document.rb +70 -8
- data/test/functional/test_modifiers.rb +9 -1
- data/test/functional/test_validations.rb +44 -31
- data/test/test_helper.rb +1 -0
- data/test/unit/test_document.rb +0 -6
- data/test/unit/test_embedded_document.rb +1 -7
- data/test/unit/test_query.rb +80 -56
- data/test/unit/test_rails.rb +77 -19
- data/test/unit/test_support.rb +6 -2
- metadata +69 -34
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
|
|
data/lib/mongo_mapper.rb
CHANGED
@@ -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
|
@@ -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 |
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
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
|
168
|
-
|
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
|
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
|
|
@@ -37,7 +37,7 @@ module MongoMapper
|
|
37
37
|
|
38
38
|
def where_conditions(instance)
|
39
39
|
conditions = {}
|
40
|
-
conditions[attribute] =
|
40
|
+
conditions[attribute] = /^#{Regexp.escape(instance[attribute].to_s)}$/i unless case_sensitive
|
41
41
|
conditions
|
42
42
|
end
|
43
43
|
end
|
data/lib/mongo_mapper/query.rb
CHANGED
@@ -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)
|
69
|
-
|
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
|
data/lib/mongo_mapper/support.rb
CHANGED
@@ -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 =>
|
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
|
-
|
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
|
|
data/lib/mongo_mapper/version.rb
CHANGED
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.7.
|
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-
|
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.
|
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"])
|
@@ -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,
|
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,
|
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
|
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
|
64
|
+
address.new?.should be_true
|
65
65
|
end
|
66
66
|
|
67
|
-
should "
|
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
|
71
|
+
doc.foo.new?.should be_false
|
72
72
|
end
|
73
73
|
|
74
|
-
should "
|
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
|
80
|
-
doc.foo.new?.should
|
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
|
|