djsun-mongomapper 0.3.1.1 → 0.3.3
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/History +20 -1
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/base.rb +3 -5
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +5 -3
- data/lib/mongomapper/associations/belongs_to_proxy.rb +4 -4
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +38 -15
- data/lib/mongomapper/document.rb +165 -95
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +116 -88
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +12 -16
- data/lib/mongomapper/serializers/json_serializer.rb +15 -12
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +7 -33
- data/mongomapper.gemspec +10 -7
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +14 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +10 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +46 -52
- data/test/functional/associations/test_many_proxy.rb +71 -12
- data/test/functional/test_associations.rb +9 -2
- data/test/functional/test_document.rb +281 -20
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +39 -8
- data/test/unit/serializers/test_json_serializer.rb +46 -12
- data/test/unit/test_association_base.rb +10 -2
- data/test/unit/test_document.rb +7 -9
- data/test/unit/test_embedded_document.rb +180 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +54 -24
- metadata +5 -5
- data/test/unit/test_mongo_id.rb +0 -35
@@ -1,36 +1,36 @@
|
|
1
1
|
require 'observer'
|
2
2
|
|
3
3
|
module MongoMapper
|
4
|
-
module EmbeddedDocument
|
4
|
+
module EmbeddedDocument
|
5
5
|
def self.included(model)
|
6
6
|
model.class_eval do
|
7
7
|
extend ClassMethods
|
8
8
|
include InstanceMethods
|
9
|
-
|
9
|
+
|
10
10
|
extend Associations::ClassMethods
|
11
11
|
include Associations::InstanceMethods
|
12
|
-
|
12
|
+
|
13
13
|
include RailsCompatibility::EmbeddedDocument
|
14
14
|
include Validatable
|
15
15
|
include Serialization
|
16
16
|
|
17
|
-
key :_id,
|
17
|
+
key :_id, String
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
module ClassMethods
|
22
22
|
def inherited(subclass)
|
23
23
|
unless subclass.embeddable?
|
24
24
|
subclass.collection(self.collection.name)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
(@subclasses ||= []) << subclass
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def subclasses
|
31
31
|
@subclasses
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def keys
|
35
35
|
@keys ||= if parent = parent_model
|
36
36
|
parent.keys.dup
|
@@ -38,90 +38,104 @@ module MongoMapper
|
|
38
38
|
HashWithIndifferentAccess.new
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
42
|
-
def key(
|
43
|
-
key = Key.new(
|
44
|
-
keys[key.name] = key
|
45
|
-
|
46
|
-
create_accessors_for(key)
|
47
|
-
add_to_subclasses(name, type, options)
|
48
|
-
apply_validations_for(key)
|
49
|
-
create_indexes_for(key)
|
50
|
-
|
51
|
-
key
|
52
|
-
end
|
53
|
-
|
54
|
-
def create_accessors_for(key)
|
55
|
-
define_method(key.name) do
|
56
|
-
read_attribute(key.name)
|
57
|
-
end
|
58
|
-
|
59
|
-
define_method("#{key.name}_before_typecast") do
|
60
|
-
read_attribute_before_typecast(key.name)
|
61
|
-
end
|
62
|
-
|
63
|
-
define_method("#{key.name}=") do |value|
|
64
|
-
write_attribute(key.name, value)
|
65
|
-
end
|
41
|
+
|
42
|
+
def key(*args)
|
43
|
+
key = Key.new(*args)
|
66
44
|
|
67
|
-
|
68
|
-
|
45
|
+
if keys[key.name].blank?
|
46
|
+
keys[key.name] = key
|
47
|
+
|
48
|
+
create_accessors_for(key)
|
49
|
+
add_to_subclasses(*args)
|
50
|
+
apply_validations_for(key)
|
51
|
+
create_indexes_for(key)
|
52
|
+
|
53
|
+
key
|
69
54
|
end
|
70
55
|
end
|
71
|
-
|
72
|
-
def add_to_subclasses(
|
56
|
+
|
57
|
+
def add_to_subclasses(*args)
|
73
58
|
return if subclasses.blank?
|
74
|
-
|
59
|
+
|
75
60
|
subclasses.each do |subclass|
|
76
|
-
subclass.key
|
61
|
+
subclass.key(*args)
|
77
62
|
end
|
78
63
|
end
|
79
|
-
|
64
|
+
|
80
65
|
def ensure_index(name_or_array, options={})
|
81
66
|
keys_to_index = if name_or_array.is_a?(Array)
|
82
67
|
name_or_array.map { |pair| [pair[0], pair[1]] }
|
83
68
|
else
|
84
69
|
name_or_array
|
85
70
|
end
|
86
|
-
|
71
|
+
|
87
72
|
collection.create_index(keys_to_index, options.delete(:unique))
|
88
73
|
end
|
89
|
-
|
74
|
+
|
90
75
|
def embeddable?
|
91
76
|
!self.ancestors.include?(Document)
|
92
77
|
end
|
93
|
-
|
78
|
+
|
94
79
|
def parent_model
|
95
|
-
|
96
|
-
|
80
|
+
(ancestors - [self,EmbeddedDocument]).find do |parent_class|
|
81
|
+
parent_class.ancestors.include?(EmbeddedDocument)
|
97
82
|
end
|
98
83
|
end
|
99
|
-
|
84
|
+
|
100
85
|
private
|
86
|
+
def accessors_module
|
87
|
+
if const_defined?('MongoMapperKeys') && constants.include?( 'MongoMapperKeys' )
|
88
|
+
const_get 'MongoMapperKeys'
|
89
|
+
else
|
90
|
+
const_set 'MongoMapperKeys', Module.new
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_accessors_for(key)
|
95
|
+
accessors_module.module_eval <<-end_eval
|
96
|
+
def #{key.name}
|
97
|
+
read_attribute( :'#{key.name}' )
|
98
|
+
end
|
99
|
+
|
100
|
+
def #{key.name}_before_typecast
|
101
|
+
read_attribute_before_typecast(:'#{key.name}')
|
102
|
+
end
|
103
|
+
|
104
|
+
def #{key.name}=(value)
|
105
|
+
write_attribute(:'#{key.name}', value)
|
106
|
+
end
|
107
|
+
|
108
|
+
def #{key.name}?
|
109
|
+
read_attribute(:#{key.name}).present?
|
110
|
+
end
|
111
|
+
end_eval
|
112
|
+
include accessors_module
|
113
|
+
end
|
114
|
+
|
101
115
|
def create_indexes_for(key)
|
102
116
|
ensure_index key.name if key.options[:index]
|
103
117
|
end
|
104
|
-
|
118
|
+
|
105
119
|
def apply_validations_for(key)
|
106
120
|
attribute = key.name.to_sym
|
107
|
-
|
121
|
+
|
108
122
|
if key.options[:required]
|
109
123
|
validates_presence_of(attribute)
|
110
124
|
end
|
111
|
-
|
125
|
+
|
112
126
|
if key.options[:unique]
|
113
127
|
validates_uniqueness_of(attribute)
|
114
128
|
end
|
115
|
-
|
129
|
+
|
116
130
|
if key.options[:numeric]
|
117
131
|
number_options = key.type == Integer ? {:only_integer => true} : {}
|
118
132
|
validates_numericality_of(attribute, number_options)
|
119
133
|
end
|
120
|
-
|
134
|
+
|
121
135
|
if key.options[:format]
|
122
136
|
validates_format_of(attribute, :with => key.options[:format])
|
123
137
|
end
|
124
|
-
|
138
|
+
|
125
139
|
if key.options[:length]
|
126
140
|
length_options = case key.options[:length]
|
127
141
|
when Integer
|
@@ -135,7 +149,7 @@ module MongoMapper
|
|
135
149
|
end
|
136
150
|
end
|
137
151
|
end
|
138
|
-
|
152
|
+
|
139
153
|
module InstanceMethods
|
140
154
|
def initialize(attrs={})
|
141
155
|
unless attrs.nil?
|
@@ -144,90 +158,104 @@ module MongoMapper
|
|
144
158
|
send("#{association.name}=", collection)
|
145
159
|
end
|
146
160
|
end
|
147
|
-
|
161
|
+
|
148
162
|
self.attributes = attrs
|
149
163
|
end
|
150
|
-
|
164
|
+
|
151
165
|
if self.class.embeddable? && read_attribute(:_id).blank?
|
152
|
-
write_attribute :_id, XGen::Mongo::Driver::ObjectID.new
|
166
|
+
write_attribute :_id, XGen::Mongo::Driver::ObjectID.new.to_s
|
153
167
|
end
|
154
168
|
end
|
155
|
-
|
169
|
+
|
156
170
|
def attributes=(attrs)
|
157
171
|
return if attrs.blank?
|
158
|
-
attrs.each_pair do |
|
159
|
-
|
172
|
+
attrs.each_pair do |name, value|
|
173
|
+
writer_method = "#{name}="
|
174
|
+
|
175
|
+
if respond_to?(writer_method)
|
176
|
+
self.send(writer_method, value)
|
177
|
+
else
|
178
|
+
self[name.to_s] = value
|
179
|
+
end
|
160
180
|
end
|
161
181
|
end
|
162
|
-
|
182
|
+
|
163
183
|
def attributes
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
184
|
+
attrs = HashWithIndifferentAccess.new
|
185
|
+
self.class.keys.each_pair do |name, key|
|
186
|
+
value =
|
187
|
+
if key.native?
|
188
|
+
read_attribute(key.name)
|
189
|
+
else
|
190
|
+
if embedded_document = read_attribute(key.name)
|
191
|
+
embedded_document.attributes
|
192
|
+
end
|
193
|
+
end
|
169
194
|
|
170
|
-
|
195
|
+
attrs[name] = value unless value.nil?
|
171
196
|
end
|
197
|
+
attrs.merge!(embedded_association_attributes)
|
172
198
|
end
|
173
|
-
|
199
|
+
|
174
200
|
def [](name)
|
175
201
|
read_attribute(name)
|
176
202
|
end
|
177
|
-
|
203
|
+
|
178
204
|
def []=(name, value)
|
205
|
+
ensure_key_exists(name)
|
179
206
|
write_attribute(name, value)
|
180
207
|
end
|
181
|
-
|
208
|
+
|
182
209
|
def ==(other)
|
183
210
|
other.is_a?(self.class) && id == other.id
|
184
211
|
end
|
185
|
-
|
212
|
+
|
186
213
|
def id
|
187
|
-
|
214
|
+
read_attribute(:_id)
|
188
215
|
end
|
189
|
-
|
216
|
+
|
190
217
|
def id=(value)
|
191
|
-
|
218
|
+
@using_custom_id = true
|
219
|
+
write_attribute :_id, value
|
192
220
|
end
|
193
221
|
|
222
|
+
def using_custom_id?
|
223
|
+
!!@using_custom_id
|
224
|
+
end
|
225
|
+
|
194
226
|
def inspect
|
195
227
|
attributes_as_nice_string = self.class.keys.keys.collect do |name|
|
196
228
|
"#{name}: #{read_attribute(name)}"
|
197
229
|
end.join(", ")
|
198
230
|
"#<#{self.class} #{attributes_as_nice_string}>"
|
199
231
|
end
|
200
|
-
|
232
|
+
|
201
233
|
private
|
202
|
-
def
|
203
|
-
|
204
|
-
read_attribute(key.name)
|
205
|
-
else
|
206
|
-
embedded_document = read_attribute(key.name)
|
207
|
-
embedded_document && embedded_document.attributes
|
208
|
-
end
|
234
|
+
def ensure_key_exists(name)
|
235
|
+
self.class.key(name) unless respond_to?("#{name}=")
|
209
236
|
end
|
210
|
-
|
237
|
+
|
211
238
|
def read_attribute(name)
|
212
|
-
|
213
|
-
instance_variable_set "@#{name}",
|
239
|
+
value = self.class.keys[name].get(instance_variable_get("@#{name}"))
|
240
|
+
instance_variable_set "@#{name}", value if !frozen?
|
241
|
+
value
|
214
242
|
end
|
215
|
-
|
243
|
+
|
216
244
|
def read_attribute_before_typecast(name)
|
217
245
|
instance_variable_get("@#{name}_before_typecast")
|
218
246
|
end
|
219
|
-
|
247
|
+
|
220
248
|
def write_attribute(name, value)
|
221
249
|
instance_variable_set "@#{name}_before_typecast", value
|
222
250
|
instance_variable_set "@#{name}", self.class.keys[name].set(value)
|
223
251
|
end
|
224
|
-
|
252
|
+
|
225
253
|
def embedded_association_attributes
|
226
254
|
returning HashWithIndifferentAccess.new do |attrs|
|
227
255
|
self.class.associations.each_pair do |name, association|
|
228
256
|
next unless association.embeddable?
|
229
257
|
next unless documents = instance_variable_get(association.ivar)
|
230
|
-
|
258
|
+
|
231
259
|
attrs[name] = documents.collect { |doc| doc.attributes }
|
232
260
|
end
|
233
261
|
end
|
@@ -7,26 +7,15 @@ module MongoMapper
|
|
7
7
|
conditions.each_pair do |field, value|
|
8
8
|
case value
|
9
9
|
when Array
|
10
|
-
operator_present = field.to_s =~ /^\$/
|
11
|
-
|
12
|
-
dealing_with_ids = field.to_s == '_id' ||
|
13
|
-
(parent_key && parent_key.to_s == '_id')
|
14
|
-
|
15
|
-
criteria[field] = if dealing_with_ids
|
16
|
-
ids = value.map { |id| MongoID.mm_typecast(id) }
|
17
|
-
operator_present ? ids : {'$in' => ids}
|
18
|
-
elsif operator_present
|
10
|
+
operator_present = field.to_s =~ /^\$/
|
11
|
+
criteria[field] = if operator_present
|
19
12
|
value
|
20
13
|
else
|
21
14
|
{'$in' => value}
|
22
15
|
end
|
23
16
|
when Hash
|
24
17
|
criteria[field] = to_mongo_criteria(value, field)
|
25
|
-
else
|
26
|
-
if field.to_s == '_id'
|
27
|
-
value = MongoID.mm_typecast(value)
|
28
|
-
end
|
29
|
-
|
18
|
+
else
|
30
19
|
criteria[field] = value
|
31
20
|
end
|
32
21
|
end
|
data/lib/mongomapper/key.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module MongoMapper
|
2
2
|
class Key
|
3
3
|
# DateTime and Date are currently not supported by mongo's bson so just use Time
|
4
|
-
NativeTypes = [String, Float, Time, Integer, Boolean, Array, Hash
|
4
|
+
NativeTypes = [String, Float, Time, Integer, Boolean, Array, Hash]
|
5
5
|
|
6
6
|
attr_accessor :name, :type, :options, :default_value
|
7
|
-
|
8
|
-
def initialize(
|
9
|
-
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
options = args.extract_options!
|
10
|
+
@name, @type = args.shift.to_s, args.shift
|
10
11
|
self.options = (options || {}).symbolize_keys
|
11
12
|
self.default_value = self.options.delete(:default)
|
12
13
|
end
|
@@ -20,11 +21,11 @@ module MongoMapper
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def native?
|
23
|
-
@native ||= NativeTypes.include?(type)
|
24
|
+
@native ||= NativeTypes.include?(type) || type.nil?
|
24
25
|
end
|
25
26
|
|
26
27
|
def embedded_document?
|
27
|
-
type.
|
28
|
+
type.respond_to?(:embeddable?) && type.embeddable?
|
28
29
|
end
|
29
30
|
|
30
31
|
def get(value)
|
@@ -40,26 +41,21 @@ module MongoMapper
|
|
40
41
|
|
41
42
|
private
|
42
43
|
def typecast(value)
|
44
|
+
return value if type.nil?
|
43
45
|
return HashWithIndifferentAccess.new(value) if value.is_a?(Hash) && type == Hash
|
46
|
+
return value.utc if type == Time && value.kind_of?(type)
|
44
47
|
return value if value.kind_of?(type) || value.nil?
|
45
48
|
begin
|
46
49
|
if type == String then value.to_s
|
47
50
|
elsif type == Float then value.to_f
|
48
51
|
elsif type == Array then value.to_a
|
49
|
-
elsif type == Time then Time.parse(value.to_s)
|
50
|
-
elsif type == MongoID then MongoID.mm_typecast(value)
|
51
|
-
#elsif type == Date then Date.parse(value.to_s)
|
52
|
+
elsif type == Time then Time.parse(value.to_s).utc
|
52
53
|
elsif type == Boolean then Boolean.mm_typecast(value)
|
53
54
|
elsif type == Integer
|
54
55
|
# ganked from datamapper
|
55
56
|
value_to_i = value.to_i
|
56
|
-
if value_to_i == 0
|
57
|
-
|
58
|
-
begin
|
59
|
-
Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
|
60
|
-
rescue ArgumentError
|
61
|
-
nil
|
62
|
-
end
|
57
|
+
if value_to_i == 0
|
58
|
+
value.to_s =~ /^(0x|0b)?0+/ ? 0 : nil
|
63
59
|
else
|
64
60
|
value_to_i
|
65
61
|
end
|
@@ -50,18 +50,8 @@ module MongoMapper #:nodoc:
|
|
50
50
|
# "created_at": "2006/08/01", "awesome": true,
|
51
51
|
# "permalink": "1-konata-izumi"}
|
52
52
|
def to_json(options = {})
|
53
|
-
|
54
|
-
|
55
|
-
if o && o.is_a?(Array)
|
56
|
-
o << :id
|
57
|
-
elsif o
|
58
|
-
o = [o, :id]
|
59
|
-
else
|
60
|
-
o = :id
|
61
|
-
end
|
62
|
-
options[:methods] = o
|
63
|
-
end
|
64
|
-
options.reverse_merge!(:except => :_id)
|
53
|
+
apply_to_json_defaults(options)
|
54
|
+
|
65
55
|
if include_root_in_json
|
66
56
|
"{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
|
67
57
|
else
|
@@ -85,5 +75,18 @@ module MongoMapper #:nodoc:
|
|
85
75
|
@json_class_name ||= name.demodulize.underscore.inspect
|
86
76
|
end
|
87
77
|
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def apply_to_json_defaults(options)
|
81
|
+
unless options[:only]
|
82
|
+
methods = [options.delete(:methods)].flatten.compact
|
83
|
+
methods << :id
|
84
|
+
options[:methods] = methods.uniq
|
85
|
+
end
|
86
|
+
|
87
|
+
except = [options.delete(:except)].flatten.compact
|
88
|
+
except << :_id
|
89
|
+
options[:except] = except
|
90
|
+
end
|
88
91
|
end
|
89
92
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class BasicObject #:nodoc:
|
2
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|instance_eval|proxy_|^object_id$)/ }
|
3
|
+
end unless defined?(BasicObject)
|
4
|
+
|
5
|
+
class Boolean
|
6
|
+
def self.mm_typecast(value)
|
7
|
+
['true', 't', '1'].include?(value.to_s.downcase)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Object
|
12
|
+
# The hidden singleton lurks behind everyone
|
13
|
+
def metaclass
|
14
|
+
class << self; self end
|
15
|
+
end
|
16
|
+
|
17
|
+
def meta_eval(&blk)
|
18
|
+
metaclass.instance_eval(&blk)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Adds methods to a metaclass
|
22
|
+
def meta_def(name, &blk)
|
23
|
+
meta_eval { define_method(name, &blk) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Defines an instance method within a class
|
27
|
+
def class_def(name, &blk)
|
28
|
+
class_eval { define_method(name, &blk) }
|
29
|
+
end
|
30
|
+
end
|
data/lib/mongomapper.rb
CHANGED
@@ -2,43 +2,17 @@ require 'pathname'
|
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
4
|
gem 'activesupport'
|
5
|
-
gem 'mongodb-mongo', '0.
|
5
|
+
gem 'mongodb-mongo', '0.11.1'
|
6
6
|
gem 'jnunemaker-validatable', '1.7.2'
|
7
7
|
|
8
8
|
require 'activesupport'
|
9
9
|
require 'mongo'
|
10
10
|
require 'validatable'
|
11
11
|
|
12
|
-
class BasicObject #:nodoc:
|
13
|
-
instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval/ }
|
14
|
-
end unless defined?(BasicObject)
|
15
|
-
|
16
|
-
class Boolean
|
17
|
-
def self.mm_typecast(value)
|
18
|
-
['true', 't', '1'].include?(value.to_s.downcase)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class MongoID < XGen::Mongo::Driver::ObjectID
|
23
|
-
def self.mm_typecast(value)
|
24
|
-
begin
|
25
|
-
if value.is_a?(XGen::Mongo::Driver::ObjectID)
|
26
|
-
value
|
27
|
-
else
|
28
|
-
XGen::Mongo::Driver::ObjectID::from_string(value.to_s)
|
29
|
-
end
|
30
|
-
rescue => exception
|
31
|
-
if exception.message == 'illegal ObjectID format'
|
32
|
-
raise MongoMapper::IllegalID
|
33
|
-
else
|
34
|
-
raise exception
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
12
|
dir = Pathname(__FILE__).dirname.expand_path + 'mongomapper'
|
41
13
|
|
14
|
+
require dir + 'support'
|
15
|
+
|
42
16
|
require dir + 'associations'
|
43
17
|
require dir + 'associations/base'
|
44
18
|
|
@@ -54,6 +28,7 @@ require dir + 'associations/many_embedded_polymorphic_proxy'
|
|
54
28
|
|
55
29
|
require dir + 'callbacks'
|
56
30
|
require dir + 'finder_options'
|
31
|
+
require dir + 'dynamic_finder'
|
57
32
|
require dir + 'key'
|
58
33
|
require dir + 'observing'
|
59
34
|
require dir + 'pagination'
|
@@ -68,16 +43,15 @@ require dir + 'embedded_document'
|
|
68
43
|
require dir + 'document'
|
69
44
|
|
70
45
|
module MongoMapper
|
71
|
-
DocumentNotFound
|
72
|
-
IllegalID = Class.new(StandardError)
|
46
|
+
DocumentNotFound = Class.new(StandardError)
|
73
47
|
|
74
|
-
DocumentNotValid
|
48
|
+
DocumentNotValid = Class.new(StandardError) do
|
75
49
|
def initialize(document)
|
76
50
|
@document = document
|
77
51
|
super("Validation failed: #{@document.errors.full_messages.join(", ")}")
|
78
52
|
end
|
79
53
|
end
|
80
|
-
|
54
|
+
|
81
55
|
def self.connection
|
82
56
|
@@connection ||= XGen::Mongo::Driver::Mongo.new
|
83
57
|
end
|
data/mongomapper.gemspec
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{mongomapper}
|
5
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.3"
|
6
9
|
|
7
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["John Nunemaker"]
|
9
|
-
s.date = %q{2009-08-
|
12
|
+
s.date = %q{2009-08-16}
|
10
13
|
s.default_executable = %q{mmconsole}
|
11
14
|
s.email = %q{nunemaker@gmail.com}
|
12
15
|
s.executables = ["mmconsole"]
|
@@ -35,6 +38,7 @@ Gem::Specification.new do |s|
|
|
35
38
|
"lib/mongomapper/associations/proxy.rb",
|
36
39
|
"lib/mongomapper/callbacks.rb",
|
37
40
|
"lib/mongomapper/document.rb",
|
41
|
+
"lib/mongomapper/dynamic_finder.rb",
|
38
42
|
"lib/mongomapper/embedded_document.rb",
|
39
43
|
"lib/mongomapper/finder_options.rb",
|
40
44
|
"lib/mongomapper/key.rb",
|
@@ -45,6 +49,7 @@ Gem::Specification.new do |s|
|
|
45
49
|
"lib/mongomapper/save_with_validation.rb",
|
46
50
|
"lib/mongomapper/serialization.rb",
|
47
51
|
"lib/mongomapper/serializers/json_serializer.rb",
|
52
|
+
"lib/mongomapper/support.rb",
|
48
53
|
"lib/mongomapper/validations.rb",
|
49
54
|
"mongomapper.gemspec",
|
50
55
|
"test/NOTE_ON_TESTING",
|
@@ -68,7 +73,6 @@ Gem::Specification.new do |s|
|
|
68
73
|
"test/unit/test_embedded_document.rb",
|
69
74
|
"test/unit/test_finder_options.rb",
|
70
75
|
"test/unit/test_key.rb",
|
71
|
-
"test/unit/test_mongo_id.rb",
|
72
76
|
"test/unit/test_mongomapper.rb",
|
73
77
|
"test/unit/test_observing.rb",
|
74
78
|
"test/unit/test_pagination.rb",
|
@@ -103,7 +107,6 @@ Gem::Specification.new do |s|
|
|
103
107
|
"test/unit/test_embedded_document.rb",
|
104
108
|
"test/unit/test_finder_options.rb",
|
105
109
|
"test/unit/test_key.rb",
|
106
|
-
"test/unit/test_mongo_id.rb",
|
107
110
|
"test/unit/test_mongomapper.rb",
|
108
111
|
"test/unit/test_observing.rb",
|
109
112
|
"test/unit/test_pagination.rb",
|
@@ -118,20 +121,20 @@ Gem::Specification.new do |s|
|
|
118
121
|
|
119
122
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
120
123
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
121
|
-
s.add_runtime_dependency(%q<mongodb-mongo>, ["= 0.
|
124
|
+
s.add_runtime_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
122
125
|
s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
123
126
|
s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
|
124
127
|
s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
125
128
|
else
|
126
129
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
127
|
-
s.add_dependency(%q<mongodb-mongo>, ["= 0.
|
130
|
+
s.add_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
128
131
|
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
129
132
|
s.add_dependency(%q<mocha>, ["= 0.9.4"])
|
130
133
|
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
131
134
|
end
|
132
135
|
else
|
133
136
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
134
|
-
s.add_dependency(%q<mongodb-mongo>, ["= 0.
|
137
|
+
s.add_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
135
138
|
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
136
139
|
s.add_dependency(%q<mocha>, ["= 0.9.4"])
|
137
140
|
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
@@ -36,4 +36,18 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
|
36
36
|
from_db.target_id.should be_nil
|
37
37
|
from_db.target.should be_nil
|
38
38
|
end
|
39
|
+
|
40
|
+
context "association id set but document not found" do
|
41
|
+
setup do
|
42
|
+
@status = Status.new
|
43
|
+
project = Project.new(:name => "mongomapper")
|
44
|
+
@status.target = project
|
45
|
+
@status.save.should be_true
|
46
|
+
project.destroy
|
47
|
+
end
|
48
|
+
|
49
|
+
should "return nil instead of raising error" do
|
50
|
+
@status.target.should be_nil
|
51
|
+
end
|
52
|
+
end
|
39
53
|
end
|
@@ -32,4 +32,14 @@ class BelongsToProxyTest < Test::Unit::TestCase
|
|
32
32
|
from_db.project = nil
|
33
33
|
from_db.project.should be_nil
|
34
34
|
end
|
35
|
+
|
36
|
+
context "association id set but document not found" do
|
37
|
+
setup do
|
38
|
+
@status = Status.new(:name => 'Foo', :project_id => '1234')
|
39
|
+
end
|
40
|
+
|
41
|
+
should "return nil instead of raising error" do
|
42
|
+
@status.project.should be_nil
|
43
|
+
end
|
44
|
+
end
|
35
45
|
end
|