jnunemaker-mongomapper 0.3.2 → 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 +10 -0
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +3 -1
- data/lib/mongomapper/associations/belongs_to_proxy.rb +2 -2
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +44 -9
- data/lib/mongomapper/document.rb +142 -89
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +102 -85
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +10 -15
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +4 -31
- data/mongomapper.gemspec +12 -10
- 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_proxy.rb +63 -4
- data/test/functional/test_document.rb +371 -120
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +10 -6
- data/test/unit/serializers/test_json_serializer.rb +1 -1
- data/test/unit/test_document.rb +7 -1
- data/test/unit/test_embedded_document.rb +115 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +46 -23
- metadata +7 -7
- data/test/unit/test_mongo_id.rb +0 -35
@@ -0,0 +1,38 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
class DynamicFinder
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(model, method)
|
6
|
+
@model = model
|
7
|
+
@options = {}
|
8
|
+
@options[:method] = method
|
9
|
+
match
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
@options[:finder].present?
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def match
|
18
|
+
@options[:finder] = :first
|
19
|
+
|
20
|
+
case @options[:method].to_s
|
21
|
+
when /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/
|
22
|
+
@options[:finder] = :last if $1 == 'last_by'
|
23
|
+
@options[:finder] = :all if $1 == 'all_by'
|
24
|
+
names = $2
|
25
|
+
when /^find_by_([_a-zA-Z]\w*)\!$/
|
26
|
+
@options[:bang] = true
|
27
|
+
names = $1
|
28
|
+
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
|
29
|
+
@options[:instantiator] = $1 == 'initialize' ? :new : :create
|
30
|
+
names = $2
|
31
|
+
else
|
32
|
+
@options[:finder] = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
@options[:attribute_names] = names && names.split('_and_')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -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,93 @@ 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
80
|
if parent = ancestors[1]
|
96
81
|
parent if parent.ancestors.include?(EmbeddedDocument)
|
97
82
|
end
|
98
83
|
end
|
99
|
-
|
84
|
+
|
100
85
|
private
|
86
|
+
def create_accessors_for(key)
|
87
|
+
define_method(key.name) do
|
88
|
+
read_attribute(key.name)
|
89
|
+
end
|
90
|
+
|
91
|
+
define_method("#{key.name}_before_typecast") do
|
92
|
+
read_attribute_before_typecast(key.name)
|
93
|
+
end
|
94
|
+
|
95
|
+
define_method("#{key.name}=") do |value|
|
96
|
+
write_attribute(key.name, value)
|
97
|
+
end
|
98
|
+
|
99
|
+
define_method("#{key.name}?") do
|
100
|
+
read_attribute(key.name).present?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
101
104
|
def create_indexes_for(key)
|
102
105
|
ensure_index key.name if key.options[:index]
|
103
106
|
end
|
104
|
-
|
107
|
+
|
105
108
|
def apply_validations_for(key)
|
106
109
|
attribute = key.name.to_sym
|
107
|
-
|
110
|
+
|
108
111
|
if key.options[:required]
|
109
112
|
validates_presence_of(attribute)
|
110
113
|
end
|
111
|
-
|
114
|
+
|
112
115
|
if key.options[:unique]
|
113
116
|
validates_uniqueness_of(attribute)
|
114
117
|
end
|
115
|
-
|
118
|
+
|
116
119
|
if key.options[:numeric]
|
117
120
|
number_options = key.type == Integer ? {:only_integer => true} : {}
|
118
121
|
validates_numericality_of(attribute, number_options)
|
119
122
|
end
|
120
|
-
|
123
|
+
|
121
124
|
if key.options[:format]
|
122
125
|
validates_format_of(attribute, :with => key.options[:format])
|
123
126
|
end
|
124
|
-
|
127
|
+
|
125
128
|
if key.options[:length]
|
126
129
|
length_options = case key.options[:length]
|
127
130
|
when Integer
|
@@ -135,7 +138,7 @@ module MongoMapper
|
|
135
138
|
end
|
136
139
|
end
|
137
140
|
end
|
138
|
-
|
141
|
+
|
139
142
|
module InstanceMethods
|
140
143
|
def initialize(attrs={})
|
141
144
|
unless attrs.nil?
|
@@ -144,90 +147,104 @@ module MongoMapper
|
|
144
147
|
send("#{association.name}=", collection)
|
145
148
|
end
|
146
149
|
end
|
147
|
-
|
150
|
+
|
148
151
|
self.attributes = attrs
|
149
152
|
end
|
150
|
-
|
153
|
+
|
151
154
|
if self.class.embeddable? && read_attribute(:_id).blank?
|
152
|
-
write_attribute :_id, XGen::Mongo::Driver::ObjectID.new
|
155
|
+
write_attribute :_id, XGen::Mongo::Driver::ObjectID.new.to_s
|
153
156
|
end
|
154
157
|
end
|
155
|
-
|
158
|
+
|
156
159
|
def attributes=(attrs)
|
157
160
|
return if attrs.blank?
|
158
|
-
attrs.each_pair do |
|
159
|
-
|
161
|
+
attrs.each_pair do |name, value|
|
162
|
+
writer_method = "#{name}="
|
163
|
+
|
164
|
+
if respond_to?(writer_method)
|
165
|
+
self.send(writer_method, value)
|
166
|
+
else
|
167
|
+
self[name.to_s] = value
|
168
|
+
end
|
160
169
|
end
|
161
170
|
end
|
162
|
-
|
171
|
+
|
163
172
|
def attributes
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
173
|
+
attrs = HashWithIndifferentAccess.new
|
174
|
+
self.class.keys.each_pair do |name, key|
|
175
|
+
value =
|
176
|
+
if key.native?
|
177
|
+
read_attribute(key.name)
|
178
|
+
else
|
179
|
+
if embedded_document = read_attribute(key.name)
|
180
|
+
embedded_document.attributes
|
181
|
+
end
|
182
|
+
end
|
169
183
|
|
170
|
-
|
184
|
+
attrs[name] = value unless value.nil?
|
171
185
|
end
|
186
|
+
attrs.merge!(embedded_association_attributes)
|
172
187
|
end
|
173
|
-
|
188
|
+
|
174
189
|
def [](name)
|
175
190
|
read_attribute(name)
|
176
191
|
end
|
177
|
-
|
192
|
+
|
178
193
|
def []=(name, value)
|
194
|
+
ensure_key_exists(name)
|
179
195
|
write_attribute(name, value)
|
180
196
|
end
|
181
|
-
|
197
|
+
|
182
198
|
def ==(other)
|
183
199
|
other.is_a?(self.class) && id == other.id
|
184
200
|
end
|
185
|
-
|
201
|
+
|
186
202
|
def id
|
187
|
-
|
203
|
+
read_attribute(:_id)
|
188
204
|
end
|
189
|
-
|
205
|
+
|
190
206
|
def id=(value)
|
191
|
-
|
207
|
+
@using_custom_id = true
|
208
|
+
write_attribute :_id, value
|
192
209
|
end
|
193
210
|
|
211
|
+
def using_custom_id?
|
212
|
+
!!@using_custom_id
|
213
|
+
end
|
214
|
+
|
194
215
|
def inspect
|
195
216
|
attributes_as_nice_string = self.class.keys.keys.collect do |name|
|
196
217
|
"#{name}: #{read_attribute(name)}"
|
197
218
|
end.join(", ")
|
198
219
|
"#<#{self.class} #{attributes_as_nice_string}>"
|
199
220
|
end
|
200
|
-
|
221
|
+
|
201
222
|
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
|
223
|
+
def ensure_key_exists(name)
|
224
|
+
self.class.key(name) unless respond_to?("#{name}=")
|
209
225
|
end
|
210
|
-
|
226
|
+
|
211
227
|
def read_attribute(name)
|
212
228
|
value = self.class.keys[name].get(instance_variable_get("@#{name}"))
|
213
|
-
instance_variable_set "@#{name}", value
|
229
|
+
instance_variable_set "@#{name}", value if !frozen?
|
230
|
+
value
|
214
231
|
end
|
215
|
-
|
232
|
+
|
216
233
|
def read_attribute_before_typecast(name)
|
217
234
|
instance_variable_get("@#{name}_before_typecast")
|
218
235
|
end
|
219
|
-
|
236
|
+
|
220
237
|
def write_attribute(name, value)
|
221
238
|
instance_variable_set "@#{name}_before_typecast", value
|
222
239
|
instance_variable_set "@#{name}", self.class.keys[name].set(value)
|
223
240
|
end
|
224
|
-
|
241
|
+
|
225
242
|
def embedded_association_attributes
|
226
243
|
returning HashWithIndifferentAccess.new do |attrs|
|
227
244
|
self.class.associations.each_pair do |name, association|
|
228
245
|
next unless association.embeddable?
|
229
246
|
next unless documents = instance_variable_get(association.ivar)
|
230
|
-
|
247
|
+
|
231
248
|
attrs[name] = documents.collect { |doc| doc.attributes }
|
232
249
|
end
|
233
250
|
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,6 +41,7 @@ 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
|
44
46
|
return value.utc if type == Time && value.kind_of?(type)
|
45
47
|
return value if value.kind_of?(type) || value.nil?
|
@@ -48,19 +50,12 @@ module MongoMapper
|
|
48
50
|
elsif type == Float then value.to_f
|
49
51
|
elsif type == Array then value.to_a
|
50
52
|
elsif type == Time then Time.parse(value.to_s).utc
|
51
|
-
elsif type == MongoID then MongoID.mm_typecast(value)
|
52
|
-
#elsif type == Date then Date.parse(value.to_s)
|
53
53
|
elsif type == Boolean then Boolean.mm_typecast(value)
|
54
54
|
elsif type == Integer
|
55
55
|
# ganked from datamapper
|
56
56
|
value_to_i = value.to_i
|
57
|
-
if value_to_i == 0
|
58
|
-
|
59
|
-
begin
|
60
|
-
Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
|
61
|
-
rescue ArgumentError
|
62
|
-
nil
|
63
|
-
end
|
57
|
+
if value_to_i == 0
|
58
|
+
value.to_s =~ /^(0x|0b)?0+/ ? 0 : nil
|
64
59
|
else
|
65
60
|
value_to_i
|
66
61
|
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'
|
@@ -69,8 +44,6 @@ require dir + 'document'
|
|
69
44
|
|
70
45
|
module MongoMapper
|
71
46
|
DocumentNotFound = Class.new(StandardError)
|
72
|
-
IllegalID = Class.new(StandardError)
|
73
|
-
|
74
47
|
DocumentNotValid = Class.new(StandardError) do
|
75
48
|
def initialize(document)
|
76
49
|
@document = document
|
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",
|
@@ -76,12 +80,11 @@ Gem::Specification.new do |s|
|
|
76
80
|
"test/unit/test_serializations.rb",
|
77
81
|
"test/unit/test_validations.rb"
|
78
82
|
]
|
79
|
-
s.has_rdoc = true
|
80
83
|
s.homepage = %q{http://github.com/jnunemaker/mongomapper}
|
81
84
|
s.rdoc_options = ["--charset=UTF-8"]
|
82
85
|
s.require_paths = ["lib"]
|
83
86
|
s.rubyforge_project = %q{mongomapper}
|
84
|
-
s.rubygems_version = %q{1.3.
|
87
|
+
s.rubygems_version = %q{1.3.5}
|
85
88
|
s.summary = %q{Awesome gem for modeling your domain and storing it in mongo}
|
86
89
|
s.test_files = [
|
87
90
|
"test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
|
@@ -104,7 +107,6 @@ Gem::Specification.new do |s|
|
|
104
107
|
"test/unit/test_embedded_document.rb",
|
105
108
|
"test/unit/test_finder_options.rb",
|
106
109
|
"test/unit/test_key.rb",
|
107
|
-
"test/unit/test_mongo_id.rb",
|
108
110
|
"test/unit/test_mongomapper.rb",
|
109
111
|
"test/unit/test_observing.rb",
|
110
112
|
"test/unit/test_pagination.rb",
|
@@ -115,24 +117,24 @@ Gem::Specification.new do |s|
|
|
115
117
|
|
116
118
|
if s.respond_to? :specification_version then
|
117
119
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
118
|
-
s.specification_version =
|
120
|
+
s.specification_version = 3
|
119
121
|
|
120
122
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
121
123
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
122
|
-
s.add_runtime_dependency(%q<mongodb-mongo>, ["= 0.
|
124
|
+
s.add_runtime_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
123
125
|
s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
124
126
|
s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
|
125
127
|
s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
126
128
|
else
|
127
129
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
128
|
-
s.add_dependency(%q<mongodb-mongo>, ["= 0.
|
130
|
+
s.add_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
129
131
|
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
130
132
|
s.add_dependency(%q<mocha>, ["= 0.9.4"])
|
131
133
|
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
132
134
|
end
|
133
135
|
else
|
134
136
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
135
|
-
s.add_dependency(%q<mongodb-mongo>, ["= 0.
|
137
|
+
s.add_dependency(%q<mongodb-mongo>, ["= 0.11.1"])
|
136
138
|
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.2"])
|
137
139
|
s.add_dependency(%q<mocha>, ["= 0.9.4"])
|
138
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
|