mongoid 4.0.0.alpha2 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +13 -0
- data/lib/mongoid.rb +3 -1
- data/lib/mongoid/atomic.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
- data/lib/mongoid/attributes.rb +23 -1
- data/lib/mongoid/attributes/processing.rb +1 -1
- data/lib/mongoid/composable.rb +3 -2
- data/lib/mongoid/contextual/command.rb +0 -26
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/mongo.rb +6 -29
- data/lib/mongoid/contextual/text_search.rb +3 -5
- data/lib/mongoid/criteria.rb +1 -1
- data/lib/mongoid/criteria/modifiable.rb +27 -7
- data/lib/mongoid/criteria/permission.rb +70 -0
- data/lib/mongoid/document.rb +5 -6
- data/lib/mongoid/errors.rb +2 -0
- data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
- data/lib/mongoid/errors/readonly_document.rb +24 -0
- data/lib/mongoid/extensions/boolean.rb +1 -0
- data/lib/mongoid/extensions/hash.rb +1 -1
- data/lib/mongoid/factory.rb +5 -3
- data/lib/mongoid/fields.rb +32 -0
- data/lib/mongoid/fields/localized.rb +1 -1
- data/lib/mongoid/fields/standard.rb +1 -1
- data/lib/mongoid/findable.rb +1 -0
- data/lib/mongoid/interceptable.rb +11 -6
- data/lib/mongoid/log_subscriber.rb +34 -1
- data/lib/mongoid/persistable/deletable.rb +1 -0
- data/lib/mongoid/persistable/destroyable.rb +7 -2
- data/lib/mongoid/persistable/updatable.rb +27 -26
- data/lib/mongoid/query_cache.rb +246 -0
- data/lib/mongoid/railties/database.rake +4 -26
- data/lib/mongoid/relations.rb +8 -22
- data/lib/mongoid/relations/accessors.rb +0 -3
- data/lib/mongoid/relations/binding.rb +1 -1
- data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
- data/lib/mongoid/relations/eager.rb +5 -6
- data/lib/mongoid/relations/eager/base.rb +97 -5
- data/lib/mongoid/relations/eager/belongs_to.rb +1 -0
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +16 -9
- data/lib/mongoid/relations/eager/has_many.rb +1 -0
- data/lib/mongoid/relations/eager/has_one.rb +1 -0
- data/lib/mongoid/relations/embedded/batchable.rb +1 -1
- data/lib/mongoid/relations/embedded/in.rb +4 -4
- data/lib/mongoid/relations/embedded/many.rb +7 -5
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/macros.rb +1 -0
- data/lib/mongoid/relations/marshalable.rb +3 -3
- data/lib/mongoid/relations/proxy.rb +12 -10
- data/lib/mongoid/relations/referenced/in.rb +2 -2
- data/lib/mongoid/relations/referenced/many.rb +9 -9
- data/lib/mongoid/relations/referenced/many_to_many.rb +7 -7
- data/lib/mongoid/relations/referenced/one.rb +4 -4
- data/lib/mongoid/{state.rb → stateful.rb} +13 -1
- data/lib/mongoid/tasks/database.rake +31 -0
- data/lib/mongoid/tasks/database.rb +107 -0
- data/lib/mongoid/threaded.rb +0 -47
- data/lib/mongoid/validatable/uniqueness.rb +4 -16
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -3
- data/lib/rails/mongoid.rb +0 -124
- data/spec/app/models/edit.rb +5 -0
- data/spec/app/models/even.rb +7 -0
- data/spec/app/models/line_item.rb +1 -1
- data/spec/app/models/note.rb +2 -0
- data/spec/app/models/odd.rb +7 -0
- data/spec/app/models/record.rb +5 -0
- data/spec/app/models/wiki_page.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +76 -1
- data/spec/mongoid/changeable_spec.rb +6 -2
- data/spec/mongoid/contextual/mongo_spec.rb +3 -1
- data/spec/mongoid/contextual/text_search_spec.rb +3 -1
- data/spec/mongoid/criteria/modifiable_spec.rb +192 -0
- data/spec/mongoid/criteria_spec.rb +6 -2
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
- data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
- data/spec/mongoid/fields/localized_spec.rb +15 -0
- data/spec/mongoid/fields_spec.rb +88 -2
- data/spec/mongoid/log_subscriber_spec.rb +3 -3
- data/spec/mongoid/persistable/deletable_spec.rb +14 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +45 -1
- data/spec/mongoid/persistable/savable_spec.rb +34 -5
- data/spec/mongoid/query_cache_spec.rb +197 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +2 -2
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +1 -1
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +11 -37
- data/spec/mongoid/relations/eager/has_one_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/in_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/many_spec.rb +10 -10
- data/spec/mongoid/relations/embedded/one_spec.rb +10 -2
- data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +37 -2
- data/spec/mongoid/relations/touchable_spec.rb +20 -0
- data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +26 -1
- data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
- data/spec/mongoid/tasks/database_spec.rb +148 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +7 -0
- data/spec/rails/mongoid_spec.rb +0 -316
- data/spec/spec_helper.rb +1 -0
- metadata +30 -8
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Mongoid
|
2
3
|
module Relations
|
3
4
|
module Eager
|
@@ -9,18 +10,24 @@ module Mongoid
|
|
9
10
|
set_relation(d, [])
|
10
11
|
end
|
11
12
|
|
12
|
-
entries =
|
13
|
+
entries = {}
|
13
14
|
each_loaded_document do |doc|
|
15
|
+
entries[doc.send(key)] = doc
|
16
|
+
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
@docs.each do |d|
|
19
|
+
keys = d.send(group_by_key)
|
20
|
+
docs = entries.values_at(*keys)
|
21
|
+
set_relation(d, docs)
|
19
22
|
end
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
def keys_from_docs
|
26
|
+
keys = Set.new
|
27
|
+
@docs.each do |d|
|
28
|
+
keys += d.send(group_by_key)
|
23
29
|
end
|
30
|
+
keys.to_a
|
24
31
|
end
|
25
32
|
|
26
33
|
def set_relation(doc, element)
|
@@ -28,11 +35,11 @@ module Mongoid
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def group_by_key
|
31
|
-
@metadata.
|
38
|
+
@metadata.foreign_key
|
32
39
|
end
|
33
40
|
|
34
41
|
def key
|
35
|
-
@metadata.
|
42
|
+
@metadata.primary_key
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
@@ -198,7 +198,7 @@ module Mongoid
|
|
198
198
|
def normalize_docs(docs)
|
199
199
|
if docs.first.is_a?(::Hash)
|
200
200
|
docs.map do |doc|
|
201
|
-
attributes = {
|
201
|
+
attributes = { __metadata: __metadata, _parent: base }
|
202
202
|
attributes.merge!(doc)
|
203
203
|
Factory.build(klass, attributes)
|
204
204
|
end
|
@@ -61,7 +61,7 @@ module Mongoid
|
|
61
61
|
#
|
62
62
|
# @since 2.0.0.rc.1
|
63
63
|
def binding
|
64
|
-
Bindings::Embedded::In.new(base, target,
|
64
|
+
Bindings::Embedded::In.new(base, target, __metadata)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Characterize the document.
|
@@ -73,8 +73,8 @@ module Mongoid
|
|
73
73
|
#
|
74
74
|
# @since 2.1.0
|
75
75
|
def characterize_one(document)
|
76
|
-
unless base.
|
77
|
-
base.
|
76
|
+
unless base.__metadata
|
77
|
+
base.__metadata = __metadata.inverse_metadata(document)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -209,7 +209,7 @@ module Mongoid
|
|
209
209
|
#
|
210
210
|
# @since 2.1.0
|
211
211
|
def valid_options
|
212
|
-
[ :autobuild, :cyclic, :polymorphic ]
|
212
|
+
[ :autobuild, :cyclic, :polymorphic, :touch ]
|
213
213
|
end
|
214
214
|
|
215
215
|
# Get the default validation setting for the relation. Determines if
|
@@ -79,7 +79,7 @@ module Mongoid
|
|
79
79
|
#
|
80
80
|
# @return [ Document ] The new document.
|
81
81
|
def build(attributes = {}, type = nil)
|
82
|
-
doc = Factory.build(type ||
|
82
|
+
doc = Factory.build(type || __metadata.klass, attributes)
|
83
83
|
append(doc)
|
84
84
|
doc.apply_post_processed_defaults
|
85
85
|
yield(doc) if block_given?
|
@@ -341,7 +341,7 @@ module Mongoid
|
|
341
341
|
#
|
342
342
|
# @since 2.0.0.rc.1
|
343
343
|
def binding
|
344
|
-
Bindings::Embedded::Many.new(base, target,
|
344
|
+
Bindings::Embedded::Many.new(base, target, __metadata)
|
345
345
|
end
|
346
346
|
|
347
347
|
# Returns the criteria object for the target class with its documents set
|
@@ -355,7 +355,9 @@ module Mongoid
|
|
355
355
|
criterion = klass.scoped
|
356
356
|
criterion.embedded = true
|
357
357
|
criterion.documents = target
|
358
|
-
|
358
|
+
criterion.parent_document = base
|
359
|
+
criterion.metadata = relation_metadata
|
360
|
+
Many.apply_ordering(criterion, __metadata)
|
359
361
|
end
|
360
362
|
|
361
363
|
# Deletes one document from the target and unscoped.
|
@@ -443,8 +445,8 @@ module Mongoid
|
|
443
445
|
#
|
444
446
|
# @since 2.4.0
|
445
447
|
def scope(docs)
|
446
|
-
return docs unless
|
447
|
-
crit =
|
448
|
+
return docs unless __metadata.order || __metadata.klass.default_scoping?
|
449
|
+
crit = __metadata.klass.order_by(__metadata.order)
|
448
450
|
crit.embedded = true
|
449
451
|
crit.documents = docs
|
450
452
|
crit.entries
|
@@ -12,7 +12,7 @@ module Mongoid
|
|
12
12
|
#
|
13
13
|
# @since 3.0.15
|
14
14
|
def marshal_dump
|
15
|
-
[ base, target,
|
15
|
+
[ base, target, __metadata ]
|
16
16
|
end
|
17
17
|
|
18
18
|
# Takes the provided data and sets it back on the proxy.
|
@@ -24,8 +24,8 @@ module Mongoid
|
|
24
24
|
#
|
25
25
|
# @since 3.0.15
|
26
26
|
def marshal_load(data)
|
27
|
-
@base, @target, @
|
28
|
-
extend_proxy(
|
27
|
+
@base, @target, @__metadata = data
|
28
|
+
extend_proxy(__metadata.extension) if __metadata.extension?
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -18,10 +18,11 @@ module Mongoid
|
|
18
18
|
include Threaded::Lifecycle
|
19
19
|
include Marshalable
|
20
20
|
|
21
|
-
attr_accessor :base, :
|
21
|
+
attr_accessor :base, :__metadata, :target
|
22
|
+
alias :relation_metadata :__metadata
|
22
23
|
|
23
24
|
# Backwards compatibility with Mongoid beta releases.
|
24
|
-
delegate :foreign_key, :inverse_foreign_key, to: :
|
25
|
+
delegate :foreign_key, :inverse_foreign_key, to: :__metadata
|
25
26
|
delegate :bind_one, :unbind_one, to: :binding
|
26
27
|
delegate :collection_name, to: :base
|
27
28
|
|
@@ -37,7 +38,7 @@ module Mongoid
|
|
37
38
|
#
|
38
39
|
# @since 2.0.0.rc.1
|
39
40
|
def init(base, target, metadata)
|
40
|
-
@base, @target, @
|
41
|
+
@base, @target, @__metadata = base, target, metadata
|
41
42
|
yield(self) if block_given?
|
42
43
|
extend_proxies(metadata.extension) if metadata.extension?
|
43
44
|
end
|
@@ -56,7 +57,7 @@ module Mongoid
|
|
56
57
|
#
|
57
58
|
# @since 3.0.15
|
58
59
|
def klass
|
59
|
-
|
60
|
+
__metadata ? __metadata.klass : nil
|
60
61
|
end
|
61
62
|
|
62
63
|
# Resets the criteria inside the relation proxy. Used by many to many
|
@@ -137,7 +138,7 @@ module Mongoid
|
|
137
138
|
#
|
138
139
|
# @since 2.0.0.rc.4
|
139
140
|
def characterize_one(document)
|
140
|
-
document.
|
141
|
+
document.__metadata = __metadata unless document.__metadata
|
141
142
|
end
|
142
143
|
|
143
144
|
# Default behavior of method missing should be to delegate all calls
|
@@ -159,7 +160,7 @@ module Mongoid
|
|
159
160
|
#
|
160
161
|
# @since 2.0.0
|
161
162
|
def raise_mixed
|
162
|
-
raise Errors::MixedRelations.new(base.class,
|
163
|
+
raise Errors::MixedRelations.new(base.class, __metadata.klass)
|
163
164
|
end
|
164
165
|
|
165
166
|
# When the base is not yet saved and the user calls create or create!
|
@@ -189,11 +190,12 @@ module Mongoid
|
|
189
190
|
# @since 3.1.0
|
190
191
|
def callback_method(callback_name)
|
191
192
|
methods = []
|
192
|
-
|
193
|
-
|
194
|
-
|
193
|
+
metadata = __metadata[callback_name]
|
194
|
+
if metadata
|
195
|
+
if metadata.is_a?(Array)
|
196
|
+
methods.concat(metadata)
|
195
197
|
else
|
196
|
-
methods << metadata
|
198
|
+
methods << metadata
|
197
199
|
end
|
198
200
|
end
|
199
201
|
methods
|
@@ -71,7 +71,7 @@ module Mongoid
|
|
71
71
|
#
|
72
72
|
# @since 2.0.0.rc.1
|
73
73
|
def binding
|
74
|
-
Bindings::Referenced::In.new(base, target,
|
74
|
+
Bindings::Referenced::In.new(base, target, __metadata)
|
75
75
|
end
|
76
76
|
|
77
77
|
# Normalize the value provided as a replacement for substitution.
|
@@ -88,7 +88,7 @@ module Mongoid
|
|
88
88
|
# @since 3.1.5
|
89
89
|
def normalize(replacement)
|
90
90
|
return replacement if replacement.is_a?(Document)
|
91
|
-
|
91
|
+
__metadata.builder(klass, replacement).build
|
92
92
|
end
|
93
93
|
|
94
94
|
# Are we able to persist this relation?
|
@@ -245,7 +245,7 @@ module Mongoid
|
|
245
245
|
#
|
246
246
|
# @since 2.0.0.beta.1
|
247
247
|
def purge
|
248
|
-
unless
|
248
|
+
unless __metadata.destructive?
|
249
249
|
nullify
|
250
250
|
else
|
251
251
|
after_remove_error = nil
|
@@ -304,7 +304,7 @@ module Mongoid
|
|
304
304
|
# @since 2.4.0
|
305
305
|
def unscoped
|
306
306
|
klass.unscoped.where(
|
307
|
-
foreign_key => Conversions.flag(base.id,
|
307
|
+
foreign_key => Conversions.flag(base.id, __metadata)
|
308
308
|
)
|
309
309
|
end
|
310
310
|
|
@@ -340,7 +340,7 @@ module Mongoid
|
|
340
340
|
#
|
341
341
|
# @since 2.0.0.rc.1
|
342
342
|
def binding
|
343
|
-
Bindings::Referenced::Many.new(base, target,
|
343
|
+
Bindings::Referenced::Many.new(base, target, __metadata)
|
344
344
|
end
|
345
345
|
|
346
346
|
# Get the collection of the relation in question.
|
@@ -366,8 +366,8 @@ module Mongoid
|
|
366
366
|
# @since 2.0.0.beta.1
|
367
367
|
def criteria
|
368
368
|
Many.criteria(
|
369
|
-
|
370
|
-
Conversions.flag(base.send(
|
369
|
+
__metadata,
|
370
|
+
Conversions.flag(base.send(__metadata.primary_key), __metadata),
|
371
371
|
base.class
|
372
372
|
)
|
373
373
|
end
|
@@ -385,8 +385,8 @@ module Mongoid
|
|
385
385
|
# @since 2.1.0
|
386
386
|
def cascade!(document)
|
387
387
|
if persistable?
|
388
|
-
if
|
389
|
-
document.send(
|
388
|
+
if __metadata.destructive?
|
389
|
+
document.send(__metadata.dependent)
|
390
390
|
else
|
391
391
|
document.save
|
392
392
|
end
|
@@ -486,7 +486,7 @@ module Mongoid
|
|
486
486
|
# @since 2.4.0
|
487
487
|
def remove_not_in(ids)
|
488
488
|
removed = criteria.not_in(_id: ids)
|
489
|
-
if
|
489
|
+
if __metadata.destructive?
|
490
490
|
removed.delete_all
|
491
491
|
else
|
492
492
|
removed.update_all(foreign_key => nil)
|
@@ -495,7 +495,7 @@ module Mongoid
|
|
495
495
|
if !ids.include?(doc.id)
|
496
496
|
unbind_one(doc)
|
497
497
|
target.delete(doc)
|
498
|
-
if
|
498
|
+
if __metadata.destructive?
|
499
499
|
doc.destroyed = true
|
500
500
|
end
|
501
501
|
end
|
@@ -29,7 +29,7 @@ module Mongoid
|
|
29
29
|
return concat(docs) if docs.size > 1
|
30
30
|
if doc = docs.first
|
31
31
|
append(doc)
|
32
|
-
base.add_to_set(foreign_key => doc.send(
|
32
|
+
base.add_to_set(foreign_key => doc.send(__metadata.primary_key))
|
33
33
|
if child_persistable?(doc)
|
34
34
|
doc.save
|
35
35
|
end
|
@@ -114,7 +114,7 @@ module Mongoid
|
|
114
114
|
def delete(document)
|
115
115
|
doc = super
|
116
116
|
if doc && persistable?
|
117
|
-
base.pull(foreign_key => doc.send(
|
117
|
+
base.pull(foreign_key => doc.send(__metadata.primary_key))
|
118
118
|
target._unloaded = criteria
|
119
119
|
unsynced(base, foreign_key)
|
120
120
|
end
|
@@ -133,7 +133,7 @@ module Mongoid
|
|
133
133
|
target.each do |doc|
|
134
134
|
execute_callback :before_remove, doc
|
135
135
|
end
|
136
|
-
unless
|
136
|
+
unless __metadata.forced_nil_inverse?
|
137
137
|
criteria.pull(inverse_foreign_key => base.id)
|
138
138
|
end
|
139
139
|
if persistable?
|
@@ -142,7 +142,7 @@ module Mongoid
|
|
142
142
|
after_remove_error = nil
|
143
143
|
many_to_many = target.clear do |doc|
|
144
144
|
unbind_one(doc)
|
145
|
-
unless
|
145
|
+
unless __metadata.forced_nil_inverse?
|
146
146
|
doc.changed_attributes.delete(inverse_foreign_key)
|
147
147
|
end
|
148
148
|
begin
|
@@ -221,7 +221,7 @@ module Mongoid
|
|
221
221
|
#
|
222
222
|
# @since 2.0.0.rc.1
|
223
223
|
def binding
|
224
|
-
Bindings::Referenced::ManyToMany.new(base, target,
|
224
|
+
Bindings::Referenced::ManyToMany.new(base, target, __metadata)
|
225
225
|
end
|
226
226
|
|
227
227
|
# Determine if the child document should be persisted.
|
@@ -238,7 +238,7 @@ module Mongoid
|
|
238
238
|
# @since 3.0.20
|
239
239
|
def child_persistable?(doc)
|
240
240
|
(persistable? || _creating?) &&
|
241
|
-
!(doc.persisted? &&
|
241
|
+
!(doc.persisted? && __metadata.forced_nil_inverse?)
|
242
242
|
end
|
243
243
|
|
244
244
|
# Returns the criteria object for the target class with its documents set
|
@@ -249,7 +249,7 @@ module Mongoid
|
|
249
249
|
#
|
250
250
|
# @return [ Criteria ] A new criteria.
|
251
251
|
def criteria
|
252
|
-
ManyToMany.criteria(
|
252
|
+
ManyToMany.criteria(__metadata, base.send(foreign_key))
|
253
253
|
end
|
254
254
|
|
255
255
|
# Flag the base as unsynced with respect to the foreign key.
|
@@ -53,13 +53,13 @@ module Mongoid
|
|
53
53
|
def substitute(replacement)
|
54
54
|
unbind_one
|
55
55
|
if persistable?
|
56
|
-
if
|
57
|
-
send(
|
56
|
+
if __metadata.destructive?
|
57
|
+
send(__metadata.dependent)
|
58
58
|
else
|
59
59
|
save if persisted?
|
60
60
|
end
|
61
61
|
end
|
62
|
-
One.new(base, replacement,
|
62
|
+
One.new(base, replacement, __metadata) if replacement
|
63
63
|
end
|
64
64
|
|
65
65
|
private
|
@@ -73,7 +73,7 @@ module Mongoid
|
|
73
73
|
#
|
74
74
|
# @return [ Binding ] The binding object.
|
75
75
|
def binding
|
76
|
-
Bindings::Referenced::One.new(base, target,
|
76
|
+
Bindings::Referenced::One.new(base, target, __metadata)
|
77
77
|
end
|
78
78
|
|
79
79
|
# Are we able to persist this relation?
|
@@ -3,7 +3,7 @@ module Mongoid
|
|
3
3
|
|
4
4
|
# This module contains the behaviour for getting the various states a
|
5
5
|
# document can transition through.
|
6
|
-
module
|
6
|
+
module Stateful
|
7
7
|
|
8
8
|
attr_writer :destroyed, :flagged_for_destroy, :new_record
|
9
9
|
|
@@ -70,6 +70,18 @@ module Mongoid
|
|
70
70
|
!_parent.delayed_atomic_sets[atomic_path]
|
71
71
|
end
|
72
72
|
|
73
|
+
# Is the document readonly?
|
74
|
+
#
|
75
|
+
# @example Is the document readonly?
|
76
|
+
# document.readonly?
|
77
|
+
#
|
78
|
+
# @return [ true, false ] If the document is readonly.
|
79
|
+
#
|
80
|
+
# @since 4.0.0
|
81
|
+
def readonly?
|
82
|
+
__selected_fields != nil
|
83
|
+
end
|
84
|
+
|
73
85
|
# Determine if the document can be set.
|
74
86
|
#
|
75
87
|
# @example Is this settable?
|