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