mongo_mapper 0.13.0.beta2 → 0.15.0
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.
- 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
|