mongo_mapper 0.13.0.beta2 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +64 -0
- data/examples/keys.rb +3 -3
- data/examples/modifiers/set.rb +2 -2
- data/examples/querying.rb +3 -3
- data/examples/safe.rb +2 -2
- data/examples/scopes.rb +1 -1
- data/lib/mongo_mapper.rb +5 -0
- data/lib/mongo_mapper/connection.rb +16 -37
- data/lib/mongo_mapper/document.rb +4 -0
- data/lib/mongo_mapper/extensions/array.rb +14 -6
- data/lib/mongo_mapper/extensions/hash.rb +15 -3
- data/lib/mongo_mapper/extensions/object.rb +4 -0
- data/lib/mongo_mapper/extensions/object_id.rb +5 -1
- data/lib/mongo_mapper/extensions/string.rb +13 -5
- data/lib/mongo_mapper/extensions/symbol.rb +18 -0
- data/lib/mongo_mapper/plugins/accessible.rb +14 -4
- data/lib/mongo_mapper/plugins/associations.rb +7 -6
- data/lib/mongo_mapper/plugins/associations/base.rb +18 -13
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +10 -1
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +9 -8
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +12 -11
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -4
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +24 -23
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +18 -16
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +55 -48
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +14 -13
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +7 -6
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +7 -5
- data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +17 -14
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +14 -13
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +9 -9
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +27 -26
- data/lib/mongo_mapper/plugins/associations/proxy.rb +31 -28
- data/lib/mongo_mapper/plugins/callbacks.rb +14 -1
- data/lib/mongo_mapper/plugins/counter_cache.rb +97 -0
- data/lib/mongo_mapper/plugins/dirty.rb +29 -37
- data/lib/mongo_mapper/plugins/document.rb +1 -1
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +10 -9
- data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +18 -17
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +2 -1
- data/lib/mongo_mapper/plugins/embedded_document.rb +1 -1
- data/lib/mongo_mapper/plugins/identity_map.rb +1 -1
- data/lib/mongo_mapper/plugins/indexes.rb +37 -2
- data/lib/mongo_mapper/plugins/keys.rb +202 -142
- data/lib/mongo_mapper/plugins/keys/key.rb +22 -13
- data/lib/mongo_mapper/plugins/keys/static.rb +45 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +59 -28
- data/lib/mongo_mapper/plugins/partial_updates.rb +86 -0
- data/lib/mongo_mapper/plugins/persistence.rb +13 -8
- data/lib/mongo_mapper/plugins/protected.rb +6 -5
- data/lib/mongo_mapper/plugins/querying.rb +85 -42
- data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +32 -9
- data/lib/mongo_mapper/plugins/rails.rb +1 -0
- data/lib/mongo_mapper/plugins/safe.rb +10 -4
- data/lib/mongo_mapper/plugins/sci.rb +4 -1
- data/lib/mongo_mapper/plugins/scopes.rb +78 -7
- data/lib/mongo_mapper/plugins/stats.rb +17 -0
- data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
- data/lib/mongo_mapper/plugins/touch.rb +1 -1
- data/lib/mongo_mapper/plugins/validations.rb +7 -2
- data/lib/mongo_mapper/railtie.rb +20 -0
- data/lib/mongo_mapper/railtie/database.rake +1 -1
- data/lib/mongo_mapper/utils.rb +2 -2
- data/lib/mongo_mapper/version.rb +1 -1
- data/lib/rails/generators/mongo_mapper/config/config_generator.rb +12 -13
- data/lib/rails/generators/mongo_mapper/model/model_generator.rb +9 -9
- data/spec/examples.txt +1643 -0
- data/spec/functional/accessible_spec.rb +13 -13
- data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +13 -13
- data/spec/functional/associations/belongs_to_proxy_spec.rb +18 -19
- data/spec/functional/associations/in_array_proxy_spec.rb +10 -10
- data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
- data/spec/functional/associations/many_documents_proxy_spec.rb +85 -14
- data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +13 -13
- data/spec/functional/associations/many_embedded_proxy_spec.rb +1 -1
- data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
- data/spec/functional/associations/one_as_proxy_spec.rb +10 -10
- data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +9 -9
- data/spec/functional/associations/one_embedded_proxy_spec.rb +3 -3
- data/spec/functional/associations/one_proxy_spec.rb +10 -10
- data/spec/functional/associations_spec.rb +3 -3
- data/spec/functional/binary_spec.rb +2 -2
- data/spec/functional/caching_spec.rb +8 -15
- data/spec/functional/callbacks_spec.rb +89 -2
- data/spec/functional/counter_cache_spec.rb +235 -0
- data/spec/functional/dirty_spec.rb +63 -46
- data/spec/functional/document_spec.rb +30 -2
- data/spec/functional/dumpable_spec.rb +1 -1
- data/spec/functional/embedded_document_spec.rb +18 -18
- data/spec/functional/identity_map_spec.rb +27 -14
- data/spec/functional/indexes_spec.rb +44 -19
- data/spec/functional/keys_spec.rb +117 -15
- data/spec/functional/logger_spec.rb +3 -3
- data/spec/functional/modifiers_spec.rb +67 -19
- data/spec/functional/partial_updates_spec.rb +577 -0
- data/spec/functional/protected_spec.rb +14 -14
- data/spec/functional/querying_spec.rb +55 -28
- data/spec/functional/safe_spec.rb +23 -27
- data/spec/functional/sci_spec.rb +49 -14
- data/spec/functional/scopes_spec.rb +235 -2
- data/spec/functional/static_keys_spec.rb +153 -0
- data/spec/functional/stats_spec.rb +86 -0
- data/spec/functional/touch_spec.rb +6 -6
- data/spec/functional/validations_spec.rb +51 -57
- data/spec/quality_spec.rb +51 -0
- data/spec/spec_helper.rb +37 -9
- data/spec/support/matchers.rb +5 -14
- data/spec/unit/associations/base_spec.rb +12 -12
- data/spec/unit/associations/belongs_to_association_spec.rb +2 -2
- data/spec/unit/associations/many_association_spec.rb +2 -2
- data/spec/unit/associations/one_association_spec.rb +2 -2
- data/spec/unit/associations/proxy_spec.rb +19 -16
- data/spec/unit/clone_spec.rb +1 -1
- data/spec/unit/document_spec.rb +8 -8
- data/spec/unit/dynamic_finder_spec.rb +8 -8
- data/spec/unit/embedded_document_spec.rb +18 -19
- data/spec/unit/extensions_spec.rb +41 -17
- data/spec/unit/identity_map_middleware_spec.rb +65 -96
- data/spec/unit/inspect_spec.rb +4 -4
- data/spec/unit/key_spec.rb +28 -26
- data/spec/unit/keys_spec.rb +10 -10
- data/spec/unit/model_generator_spec.rb +2 -4
- data/spec/unit/mongo_mapper_spec.rb +38 -85
- data/spec/unit/rails_spec.rb +5 -0
- data/spec/unit/serialization_spec.rb +1 -1
- data/spec/unit/time_zones_spec.rb +2 -2
- data/spec/unit/validations_spec.rb +28 -15
- metadata +188 -161
- data/README.rdoc +0 -55
- data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
@@ -29,16 +29,17 @@ module MongoMapper
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
private
|
33
|
+
|
34
|
+
def method_missing(method, *args, &block)
|
35
|
+
finder = DynamicFinder.new(method)
|
36
|
+
|
37
|
+
if finder.found?
|
38
|
+
dynamic_find(finder, args)
|
39
|
+
else
|
40
|
+
super
|
41
41
|
end
|
42
|
+
end
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
@@ -20,25 +20,26 @@ module MongoMapper
|
|
20
20
|
bang == true
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
def match
|
25
|
-
case method.to_s
|
26
|
-
when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
|
27
|
-
@finder = :all if $1 == 'all_by'
|
28
|
-
names = $2
|
29
|
-
when /^find_by_([_a-zA-Z]\w*)\!$/
|
30
|
-
@bang = true
|
31
|
-
names = $1
|
32
|
-
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
|
33
|
-
@instantiator = $1 == 'initialize' ? :new : :create
|
34
|
-
names = $2
|
35
|
-
else
|
36
|
-
@finder = nil
|
37
|
-
end
|
23
|
+
protected
|
38
24
|
|
39
|
-
|
25
|
+
def match
|
26
|
+
case method.to_s
|
27
|
+
when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
|
28
|
+
@finder = :all if $1 == 'all_by'
|
29
|
+
names = $2
|
30
|
+
when /^find_by_([_a-zA-Z]\w*)\!$/
|
31
|
+
@bang = true
|
32
|
+
names = $1
|
33
|
+
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
|
34
|
+
@instantiator = $1 == 'initialize' ? :new : :create
|
35
|
+
names = $2
|
36
|
+
else
|
37
|
+
@finder = nil
|
40
38
|
end
|
39
|
+
|
40
|
+
@attributes = names && names.split('_and_')
|
41
|
+
end
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
44
|
-
end
|
45
|
+
end
|
@@ -8,7 +8,7 @@ module MongoMapper
|
|
8
8
|
extend ::ActiveModel::Callbacks
|
9
9
|
|
10
10
|
define_model_callbacks :save, :create, :update, :destroy, :only => [:before, :after]
|
11
|
-
define_model_callbacks :touch, :only => [:after]
|
11
|
+
define_model_callbacks :initialize, :find, :touch, :only => [:after]
|
12
12
|
|
13
13
|
proxy_callbacks(
|
14
14
|
:before => [:save, :create, :update, :destroy],
|
@@ -44,6 +44,7 @@ module MongoMapper
|
|
44
44
|
definition.each do |prefix, suffixes|
|
45
45
|
suffixes.each do |suffix|
|
46
46
|
callback = "%s_%s" % [prefix, suffix]
|
47
|
+
|
47
48
|
class_eval <<-CALLBACK, __FILE__, __LINE__ + 1
|
48
49
|
class << self
|
49
50
|
alias_method :__original_#{callback}, :#{callback}
|
@@ -5,8 +5,43 @@ module MongoMapper
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
-
|
9
|
-
|
8
|
+
def ensure_index(spec, options = {})
|
9
|
+
#TODO: should we emulate the mongo 1.x behaviour of caching attempts to create indexes?
|
10
|
+
collection.indexes.create_one dealias_options(spec), options
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_index(spec, options = {})
|
14
|
+
collection.indexes.create_one dealias_options(spec), options
|
15
|
+
end
|
16
|
+
|
17
|
+
def drop_index(name)
|
18
|
+
collection.indexes.drop_one name
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_indexes
|
22
|
+
collection.indexes.drop_all
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def dealias_options(options)
|
28
|
+
case options
|
29
|
+
when Symbol, String
|
30
|
+
{abbr(options) => 1}
|
31
|
+
when Hash
|
32
|
+
dealias_keys(options)
|
33
|
+
when Array
|
34
|
+
if options.first.is_a?(Hash)
|
35
|
+
options.map {|o| dealias_options(o) }
|
36
|
+
elsif options.first.is_a?(Array) # [[:foo, 1], [:bar, 1]]
|
37
|
+
options.inject({}) {|acc, tuple| acc.merge(dealias_options(tuple))}
|
38
|
+
else
|
39
|
+
dealias_keys(Hash[*options])
|
40
|
+
end
|
41
|
+
else
|
42
|
+
options
|
43
|
+
end
|
44
|
+
end
|
10
45
|
end
|
11
46
|
end
|
12
47
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'mongo_mapper/plugins/keys/key'
|
3
|
+
require 'mongo_mapper/plugins/keys/static'
|
3
4
|
|
4
5
|
module MongoMapper
|
5
6
|
module Plugins
|
@@ -35,11 +36,29 @@ module MongoMapper
|
|
35
36
|
@unaliased_keys ||= Hash[*keys.select {|k, v| k == v.name }.flatten(1)]
|
36
37
|
end
|
37
38
|
|
39
|
+
def dealias_keys(hash)
|
40
|
+
out = {}
|
41
|
+
hash.each do |k, v|
|
42
|
+
key = keys[k.to_s]
|
43
|
+
name = key && key.abbr || k
|
44
|
+
out[name] = k.to_s.match(/^\$/) && v.is_a?(Hash) ? dealias_keys(v) : v
|
45
|
+
end
|
46
|
+
out
|
47
|
+
end
|
48
|
+
|
49
|
+
def dealias_key(name)
|
50
|
+
key = keys[name.to_s]
|
51
|
+
key && key.abbr || k
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :dealias, :dealias_keys
|
55
|
+
alias_method :unalias, :dealias_keys
|
56
|
+
|
38
57
|
def key(*args)
|
39
58
|
Key.new(*args).tap do |key|
|
40
59
|
keys[key.name] = key
|
41
60
|
keys[key.abbr] = key if key.abbr
|
42
|
-
create_accessors_for(key) if key.valid_ruby_name?
|
61
|
+
create_accessors_for(key) if key.valid_ruby_name? && !key.reserved_name?
|
43
62
|
create_key_in_descendants(*args)
|
44
63
|
create_indexes_for(key)
|
45
64
|
create_validations_for(key)
|
@@ -47,8 +66,26 @@ module MongoMapper
|
|
47
66
|
end
|
48
67
|
end
|
49
68
|
|
69
|
+
def remove_key(name)
|
70
|
+
if key = keys[name.to_s]
|
71
|
+
keys.delete key.name
|
72
|
+
keys.delete key.abbr
|
73
|
+
remove_method key.name if respond_to? "#{key.name}"
|
74
|
+
remove_method "#{key.name}=" if respond_to? "#{key.name}="
|
75
|
+
remove_method "#{key.name}?" if respond_to? "#{key.name}?"
|
76
|
+
remove_method "#{key.name}_before_type_cast" if respond_to? "#{key.name}_before_type_cast"
|
77
|
+
remove_key_in_descendants key.name
|
78
|
+
remove_validations_for key.name
|
79
|
+
@dynamic_keys = @defined_keys = @unaliased_keys = @object_id_keys = nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
50
83
|
def persisted_name(name)
|
51
|
-
keys[name.to_s]
|
84
|
+
if key = keys[name.to_s]
|
85
|
+
key.persisted_name
|
86
|
+
else
|
87
|
+
name
|
88
|
+
end
|
52
89
|
end
|
53
90
|
alias_method :abbr, :persisted_name
|
54
91
|
|
@@ -86,120 +123,144 @@ module MongoMapper
|
|
86
123
|
end.allocate.initialize_from_database(attrs, with_cast)
|
87
124
|
end
|
88
125
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
# :nocov:
|
126
|
+
private
|
127
|
+
|
128
|
+
def key_accessors_module_defined?
|
129
|
+
# :nocov:
|
130
|
+
if IS_RUBY_1_9
|
131
|
+
const_defined?('MongoMapperKeys')
|
132
|
+
else
|
133
|
+
const_defined?('MongoMapperKeys', false)
|
98
134
|
end
|
135
|
+
# :nocov:
|
136
|
+
end
|
99
137
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
138
|
+
def accessors_module
|
139
|
+
if key_accessors_module_defined?
|
140
|
+
const_get 'MongoMapperKeys'
|
141
|
+
else
|
142
|
+
const_set 'MongoMapperKeys', Module.new
|
106
143
|
end
|
144
|
+
end
|
107
145
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
def #{key.name}_before_type_cast
|
117
|
-
read_key_before_type_cast(:#{key.name})
|
118
|
-
end
|
119
|
-
end_eval
|
120
|
-
end
|
146
|
+
def create_accessors_for(key)
|
147
|
+
accessors = ""
|
148
|
+
if key.read_accessor?
|
149
|
+
accessors << <<-end_eval
|
150
|
+
def #{key.name}
|
151
|
+
read_key(:#{key.name})
|
152
|
+
end
|
121
153
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end_eval
|
128
|
-
end
|
154
|
+
def #{key.name}_before_type_cast
|
155
|
+
read_key_before_type_cast(:#{key.name})
|
156
|
+
end
|
157
|
+
end_eval
|
158
|
+
end
|
129
159
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
160
|
+
if key.write_accessor?
|
161
|
+
accessors << <<-end_eval
|
162
|
+
def #{key.name}=(value)
|
163
|
+
write_key(:#{key.name}, value)
|
164
|
+
end
|
165
|
+
end_eval
|
166
|
+
end
|
137
167
|
|
138
|
-
|
139
|
-
|
140
|
-
|
168
|
+
if key.predicate_accessor?
|
169
|
+
accessors << <<-end_eval
|
170
|
+
def #{key.name}?
|
171
|
+
read_key(:#{key.name}).present?
|
141
172
|
end
|
142
|
-
|
173
|
+
end_eval
|
174
|
+
end
|
143
175
|
|
144
|
-
|
145
|
-
|
176
|
+
if block_given?
|
177
|
+
accessors_module.module_eval do
|
178
|
+
yield
|
179
|
+
end
|
146
180
|
end
|
147
181
|
|
148
|
-
|
149
|
-
|
182
|
+
accessors_module.module_eval accessors
|
183
|
+
include accessors_module
|
184
|
+
end
|
185
|
+
|
186
|
+
def create_key_in_descendants(*args)
|
187
|
+
descendants.each { |descendant| descendant.key(*args) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def remove_key_in_descendants(name)
|
191
|
+
descendants.each { |descendant| descendant.remove_key(name) }
|
192
|
+
end
|
193
|
+
|
194
|
+
def create_indexes_for(key)
|
195
|
+
if key.options[:index] && !key.embeddable?
|
196
|
+
warn "[DEPRECATION] :index option when defining key #{key.name.inspect} is deprecated. Put indexes in `db/indexes.rb`"
|
197
|
+
ensure_index key.name
|
150
198
|
end
|
199
|
+
end
|
151
200
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
201
|
+
def create_validations_for(key)
|
202
|
+
attribute = key.name.to_sym
|
203
|
+
|
204
|
+
if key.options[:required]
|
205
|
+
if key.type == Boolean
|
206
|
+
validates_inclusion_of attribute, :in => [true, false]
|
207
|
+
else
|
208
|
+
validates_presence_of(attribute)
|
156
209
|
end
|
157
210
|
end
|
158
211
|
|
159
|
-
|
160
|
-
attribute
|
212
|
+
if key.options[:unique]
|
213
|
+
validates_uniqueness_of(attribute)
|
214
|
+
end
|
161
215
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
validates_presence_of(attribute)
|
167
|
-
end
|
168
|
-
end
|
216
|
+
if key.options[:numeric]
|
217
|
+
number_options = key.type == Integer ? {:only_integer => true} : {}
|
218
|
+
validates_numericality_of(attribute, number_options)
|
219
|
+
end
|
169
220
|
|
170
|
-
|
171
|
-
|
172
|
-
|
221
|
+
if key.options[:format]
|
222
|
+
validates_format_of(attribute, :with => key.options[:format])
|
223
|
+
end
|
173
224
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
225
|
+
if key.options[:in]
|
226
|
+
validates_inclusion_of(attribute, :in => key.options[:in])
|
227
|
+
end
|
178
228
|
|
179
|
-
|
180
|
-
|
181
|
-
|
229
|
+
if key.options[:not_in]
|
230
|
+
validates_exclusion_of(attribute, :in => key.options[:not_in])
|
231
|
+
end
|
182
232
|
|
183
|
-
|
184
|
-
|
233
|
+
if key.options[:length]
|
234
|
+
length_options = case key.options[:length]
|
235
|
+
when Integer
|
236
|
+
{:minimum => 0, :maximum => key.options[:length]}
|
237
|
+
when Range
|
238
|
+
{:within => key.options[:length]}
|
239
|
+
when Hash
|
240
|
+
key.options[:length]
|
185
241
|
end
|
242
|
+
validates_length_of(attribute, length_options)
|
243
|
+
end
|
244
|
+
end
|
186
245
|
|
187
|
-
|
188
|
-
|
189
|
-
|
246
|
+
def remove_validations_for(name)
|
247
|
+
name = name.to_sym
|
248
|
+
a_name = [name]
|
190
249
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
250
|
+
_validators.reject!{ |key, _| key == name }
|
251
|
+
remove_validate_callbacks a_name
|
252
|
+
end
|
253
|
+
|
254
|
+
def remove_validate_callbacks(a_name)
|
255
|
+
chain = _validate_callbacks.dup.reject do |callback|
|
256
|
+
f = callback.raw_filter
|
257
|
+
f.respond_to?(:attributes) && f.attributes == a_name
|
258
|
+
end
|
259
|
+
reset_callbacks(:validate)
|
260
|
+
chain.each do |callback|
|
261
|
+
set_callback 'validate', callback.raw_filter
|
202
262
|
end
|
263
|
+
end
|
203
264
|
end
|
204
265
|
|
205
266
|
def initialize(attrs={})
|
@@ -235,7 +296,7 @@ module MongoMapper
|
|
235
296
|
end
|
236
297
|
|
237
298
|
def to_mongo(include_abbreviatons = true)
|
238
|
-
|
299
|
+
Hash.new.tap do |attrs|
|
239
300
|
self.class.unaliased_keys.each do |name, key|
|
240
301
|
value = self.read_key(key.name)
|
241
302
|
if key.type == ObjectId || !value.nil?
|
@@ -245,7 +306,7 @@ module MongoMapper
|
|
245
306
|
|
246
307
|
embedded_associations.each do |association|
|
247
308
|
if documents = instance_variable_get(association.ivar)
|
248
|
-
if association.
|
309
|
+
if association.is_a?(Associations::OneAssociation)
|
249
310
|
attrs[association.name] = documents.to_mongo
|
250
311
|
else
|
251
312
|
attrs[association.name] = documents.map(&:to_mongo)
|
@@ -312,8 +373,8 @@ module MongoMapper
|
|
312
373
|
end
|
313
374
|
end
|
314
375
|
|
315
|
-
|
316
|
-
|
376
|
+
def [](key_name); read_key(key_name); end
|
377
|
+
def attribute(key_name); read_key(key_name); end
|
317
378
|
|
318
379
|
def []=(name, value)
|
319
380
|
write_key(name, value)
|
@@ -331,7 +392,7 @@ module MongoMapper
|
|
331
392
|
@embedded_keys ||= keys.values.select(&:embeddable?)
|
332
393
|
end
|
333
394
|
|
334
|
-
|
395
|
+
protected
|
335
396
|
|
336
397
|
def unalias_key(name)
|
337
398
|
name = name.to_s
|
@@ -342,67 +403,66 @@ module MongoMapper
|
|
342
403
|
end
|
343
404
|
end
|
344
405
|
|
345
|
-
|
406
|
+
private
|
346
407
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
408
|
+
def init_ivars
|
409
|
+
@__mm_keys = self.class.keys # Not dumpable
|
410
|
+
@__mm_default_keys = @__mm_keys.values.select(&:default?) # Not dumpable
|
411
|
+
@_dynamic_attributes = {} # Dumpable
|
412
|
+
end
|
352
413
|
|
353
|
-
|
354
|
-
|
414
|
+
def load_from_database(attrs, with_cast = false)
|
415
|
+
return if attrs == nil || attrs.blank?
|
355
416
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
end
|
417
|
+
attrs.each do |key, value|
|
418
|
+
if !@__mm_keys.key?(key) && respond_to?(:"#{key}=")
|
419
|
+
self.send(:"#{key}=", value)
|
420
|
+
else
|
421
|
+
internal_write_key key, value, with_cast
|
362
422
|
end
|
363
423
|
end
|
424
|
+
end
|
364
425
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
end
|
426
|
+
def set_parent_document(key, value)
|
427
|
+
if key.type and value.instance_of?(key.type) && key.embeddable? && value.respond_to?(:_parent_document)
|
428
|
+
value._parent_document = self
|
369
429
|
end
|
430
|
+
end
|
370
431
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
432
|
+
# This exists to be patched over by plugins, while letting us still get to the undecorated
|
433
|
+
# version of the method.
|
434
|
+
def write_key(name, value)
|
435
|
+
init_ivars unless @__mm_keys
|
436
|
+
internal_write_key(name.to_s, value)
|
437
|
+
end
|
377
438
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
end
|
387
|
-
instance_variable_set key.ivar, as_typecast
|
388
|
-
else
|
389
|
-
@_dynamic_attributes[key.name.to_sym] = as_typecast
|
439
|
+
def internal_write_key(name, value, cast = true)
|
440
|
+
key = @__mm_keys[name] || dynamic_key(name)
|
441
|
+
as_mongo = cast ? key.set(value) : value
|
442
|
+
as_typecast = key.get(as_mongo)
|
443
|
+
if key.ivar
|
444
|
+
if key.embeddable?
|
445
|
+
set_parent_document(key, value)
|
446
|
+
set_parent_document(key, as_typecast)
|
390
447
|
end
|
391
|
-
|
448
|
+
instance_variable_set key.ivar, as_typecast
|
449
|
+
else
|
450
|
+
@_dynamic_attributes[key.name.to_sym] = as_typecast
|
392
451
|
end
|
452
|
+
value
|
453
|
+
end
|
393
454
|
|
394
|
-
|
395
|
-
|
396
|
-
|
455
|
+
def dynamic_key(name)
|
456
|
+
self.class.key(name, :__dynamic => true)
|
457
|
+
end
|
397
458
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
end
|
459
|
+
def initialize_default_values(except = {})
|
460
|
+
@__mm_default_keys.each do |key|
|
461
|
+
if !(except && except.key?(key.name))
|
462
|
+
internal_write_key key.name, key.default_value, false
|
403
463
|
end
|
404
464
|
end
|
405
|
-
|
465
|
+
end
|
406
466
|
end
|
407
467
|
end
|
408
468
|
end
|