mongoid 2.2.0 → 2.2.1
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/CHANGELOG.md +57 -3
- data/Rakefile +1 -1
- data/lib/mongoid/atomic/modifiers.rb +2 -1
- data/lib/mongoid/config.rb +0 -1
- data/lib/mongoid/config/replset_database.rb +2 -2
- data/lib/mongoid/contexts/mongo.rb +14 -5
- data/lib/mongoid/criteria.rb +4 -4
- data/lib/mongoid/criterion/inclusion.rb +16 -1
- data/lib/mongoid/document.rb +2 -4
- data/lib/mongoid/extensions.rb +7 -0
- data/lib/mongoid/extensions/integer/checks.rb +23 -0
- data/lib/mongoid/extensions/object/yoda.rb +16 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +1 -1
- data/lib/mongoid/extensions/string/checks.rb +24 -0
- data/lib/mongoid/extensions/string/inflections.rb +1 -1
- data/lib/mongoid/fields.rb +4 -2
- data/lib/mongoid/fields/serializable.rb +26 -18
- data/lib/mongoid/fields/serializable/array.rb +0 -1
- data/lib/mongoid/fields/serializable/boolean.rb +0 -1
- data/lib/mongoid/fields/serializable/float.rb +0 -1
- data/lib/mongoid/fields/serializable/integer.rb +1 -2
- data/lib/mongoid/fields/serializable/object_id.rb +0 -1
- data/lib/mongoid/fields/serializable/string.rb +0 -1
- data/lib/mongoid/fields/serializable/symbol.rb +0 -1
- data/lib/mongoid/matchers/strategies.rb +25 -2
- data/lib/mongoid/nested_attributes.rb +1 -1
- data/lib/mongoid/persistence/atomic.rb +2 -2
- data/lib/mongoid/persistence/atomic/{set.rb → sets.rb} +1 -1
- data/lib/mongoid/persistence/deletion.rb +1 -1
- data/lib/mongoid/relations/bindings/referenced/in.rb +5 -5
- data/lib/mongoid/relations/bindings/referenced/many.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +2 -2
- data/lib/mongoid/relations/bindings/referenced/one.rb +4 -4
- data/lib/mongoid/relations/builder.rb +1 -2
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +5 -4
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/many.rb +4 -2
- data/lib/mongoid/relations/cascading/destroy.rb +8 -1
- data/lib/mongoid/relations/embedded/in.rb +1 -1
- data/lib/mongoid/relations/embedded/many.rb +15 -2
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/nested_builder.rb +11 -4
- data/lib/mongoid/relations/referenced/many.rb +4 -2
- data/lib/mongoid/relations/referenced/many_to_many.rb +2 -1
- data/lib/mongoid/relations/synchronization.rb +39 -2
- data/lib/mongoid/relations/targets/enumerable.rb +2 -2
- data/lib/mongoid/serialization.rb +1 -1
- data/lib/mongoid/state.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +15 -1
- metadata +26 -22
- data/lib/mongoid/criterion/unconvertable.rb +0 -20
@@ -21,12 +21,11 @@ module Mongoid #:nodoc:
|
|
21
21
|
def serialize(object)
|
22
22
|
return nil if object.blank?
|
23
23
|
begin
|
24
|
-
object.to_s =~
|
24
|
+
object.to_s =~ /(^[-+]?[0-9]+$)|(\.0+)$/ ? Integer(object) : Float(object)
|
25
25
|
rescue
|
26
26
|
object
|
27
27
|
end
|
28
28
|
end
|
29
|
-
alias :set :serialize
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
@@ -49,15 +49,38 @@ module Mongoid #:nodoc:
|
|
49
49
|
# @since 2.0.0.rc.7
|
50
50
|
def matcher(document, key, value)
|
51
51
|
if value.is_a?(Hash)
|
52
|
-
MATCHERS[value.keys.first].new(document
|
52
|
+
MATCHERS[value.keys.first].new(extract_attribute(document, key))
|
53
53
|
else
|
54
54
|
if key == "$or"
|
55
55
|
Matchers::Or.new(value, document)
|
56
56
|
else
|
57
|
-
Default.new(document
|
57
|
+
Default.new(extract_attribute(document, key))
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Extract the attribute from the key, being smarter about dot notation.
|
65
|
+
#
|
66
|
+
# @example Extract the attribute.
|
67
|
+
# strategy.extract_attribute(doc, "info.field")
|
68
|
+
#
|
69
|
+
# @param [ Document ] document The document.
|
70
|
+
# @param [ String ] key The key.
|
71
|
+
#
|
72
|
+
# @return [ Object ] The value of the attribute.
|
73
|
+
#
|
74
|
+
# @since 2.2.1
|
75
|
+
def extract_attribute(document, key)
|
76
|
+
if (key_string = key.to_s) =~ /.+\..+/
|
77
|
+
key_string.split('.').inject(document.attributes) do |attribs, key|
|
78
|
+
attribs.try(:[], key)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
document.attributes[key_string]
|
82
|
+
end
|
83
|
+
end
|
61
84
|
end
|
62
85
|
end
|
63
86
|
end
|
@@ -45,7 +45,7 @@ module Mongoid #:nodoc:
|
|
45
45
|
# by a hash of options.
|
46
46
|
#
|
47
47
|
# @option *args [ true, false ] :allow_destroy Can deletion occur?
|
48
|
-
# @option *args [ Proc ] :reject_if Block to reject documents with.
|
48
|
+
# @option *args [ Proc, Symbol ] :reject_if Block or symbol pointing to a class method to reject documents with.
|
49
49
|
# @option *args [ Integer ] :limit The max number to create.
|
50
50
|
# @option *args [ true, false ] :update_only Only update existing docs.
|
51
51
|
def accepts_nested_attributes_for(*args)
|
@@ -9,7 +9,7 @@ require "mongoid/persistence/atomic/pull_all"
|
|
9
9
|
require "mongoid/persistence/atomic/push"
|
10
10
|
require "mongoid/persistence/atomic/push_all"
|
11
11
|
require "mongoid/persistence/atomic/rename"
|
12
|
-
require "mongoid/persistence/atomic/
|
12
|
+
require "mongoid/persistence/atomic/sets"
|
13
13
|
require "mongoid/persistence/atomic/unset"
|
14
14
|
|
15
15
|
module Mongoid #:nodoc:
|
@@ -201,7 +201,7 @@ module Mongoid #:nodoc:
|
|
201
201
|
#
|
202
202
|
# @since 2.1.0
|
203
203
|
def set(field, value = nil, options = {})
|
204
|
-
|
204
|
+
Sets.new(self, field, value, options).persist
|
205
205
|
end
|
206
206
|
|
207
207
|
# Performs the atomic $unset on the supplied field.
|
@@ -19,10 +19,10 @@ module Mongoid #:nodoc:
|
|
19
19
|
#
|
20
20
|
# @since 2.1.0
|
21
21
|
def prepare(&block)
|
22
|
+
document.cascade!
|
22
23
|
yield(document)
|
23
24
|
document.freeze
|
24
25
|
document.destroyed = true
|
25
|
-
document.cascade!
|
26
26
|
IdentityMap.remove(document)
|
27
27
|
Threaded.clear_safety_options!
|
28
28
|
true
|
@@ -22,13 +22,13 @@ module Mongoid # :nodoc:
|
|
22
22
|
unless binding?
|
23
23
|
binding do
|
24
24
|
inverse = metadata.inverse(target)
|
25
|
-
base.
|
25
|
+
base.you_must(metadata.foreign_key_setter, target.id)
|
26
26
|
if metadata.inverse_type
|
27
|
-
base.
|
27
|
+
base.you_must(metadata.inverse_type_setter, target.class.model_name)
|
28
28
|
end
|
29
29
|
if inverse
|
30
30
|
inverse_metadata = metadata.inverse_metadata(target)
|
31
|
-
if inverse_metadata != metadata
|
31
|
+
if inverse_metadata != metadata && !inverse_metadata.nil?
|
32
32
|
base.metadata = inverse_metadata
|
33
33
|
if base.referenced_many?
|
34
34
|
target.send(inverse).push(base)
|
@@ -54,9 +54,9 @@ module Mongoid # :nodoc:
|
|
54
54
|
unless binding?
|
55
55
|
binding do
|
56
56
|
inverse = metadata.inverse(target)
|
57
|
-
base.
|
57
|
+
base.you_must(metadata.foreign_key_setter, nil)
|
58
58
|
if metadata.inverse_type
|
59
|
-
base.
|
59
|
+
base.you_must(metadata.inverse_type_setter, nil)
|
60
60
|
end
|
61
61
|
if inverse
|
62
62
|
if base.referenced_many?
|
@@ -19,9 +19,9 @@ module Mongoid # :nodoc:
|
|
19
19
|
def bind_one(doc)
|
20
20
|
unless binding?
|
21
21
|
binding do
|
22
|
-
doc.
|
22
|
+
doc.you_must(metadata.foreign_key_setter, base.id)
|
23
23
|
if metadata.type
|
24
|
-
doc.
|
24
|
+
doc.you_must(metadata.type_setter, base.class.model_name)
|
25
25
|
end
|
26
26
|
doc.send(metadata.inverse_setter, base)
|
27
27
|
end
|
@@ -39,9 +39,9 @@ module Mongoid # :nodoc:
|
|
39
39
|
def unbind_one(doc)
|
40
40
|
unless binding?
|
41
41
|
binding do
|
42
|
-
doc.
|
42
|
+
doc.you_must(metadata.foreign_key_setter, nil)
|
43
43
|
if metadata.type
|
44
|
-
doc.
|
44
|
+
doc.you_must(metadata.type_setter, nil)
|
45
45
|
end
|
46
46
|
doc.send(metadata.inverse_setter, nil)
|
47
47
|
end
|
@@ -19,7 +19,7 @@ module Mongoid # :nodoc:
|
|
19
19
|
def bind_one(doc)
|
20
20
|
unless binding?
|
21
21
|
binding do
|
22
|
-
inverse_keys = doc.
|
22
|
+
inverse_keys = doc.you_must(metadata.inverse_foreign_key)
|
23
23
|
inverse_keys.push(base.id) if inverse_keys
|
24
24
|
base.synced[metadata.foreign_key] = true
|
25
25
|
doc.synced[metadata.inverse_foreign_key] = true
|
@@ -37,7 +37,7 @@ module Mongoid # :nodoc:
|
|
37
37
|
unless binding?
|
38
38
|
binding do
|
39
39
|
base.send(metadata.foreign_key).delete_one(doc.id)
|
40
|
-
inverse_keys = doc.
|
40
|
+
inverse_keys = doc.you_must(metadata.inverse_foreign_key)
|
41
41
|
inverse_keys.delete_one(base.id) if inverse_keys
|
42
42
|
base.synced[metadata.foreign_key] = true
|
43
43
|
doc.synced[metadata.inverse_foreign_key] = true
|
@@ -21,10 +21,10 @@ module Mongoid # :nodoc:
|
|
21
21
|
def bind
|
22
22
|
unless binding?
|
23
23
|
binding do
|
24
|
-
target.
|
24
|
+
target.you_must(metadata.foreign_key_setter, base.id)
|
25
25
|
target.send(metadata.inverse_setter, base)
|
26
26
|
if metadata.type
|
27
|
-
target.
|
27
|
+
target.you_must(metadata.type_setter, base.class.model_name)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -42,10 +42,10 @@ module Mongoid # :nodoc:
|
|
42
42
|
def unbind
|
43
43
|
unless binding?
|
44
44
|
binding do
|
45
|
-
target.
|
45
|
+
target.you_must(metadata.foreign_key_setter, nil)
|
46
46
|
target.send(metadata.inverse_setter, nil)
|
47
47
|
if metadata.type
|
48
|
-
target.
|
48
|
+
target.you_must(metadata.type_setter, nil)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -25,9 +25,9 @@ module Mongoid # :nodoc:
|
|
25
25
|
end
|
26
26
|
attributes.each do |attrs|
|
27
27
|
if attrs.respond_to?(:with_indifferent_access)
|
28
|
-
process(attrs)
|
28
|
+
process(parent, attrs)
|
29
29
|
else
|
30
|
-
process(attrs[1])
|
30
|
+
process(parent, attrs[1])
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -89,12 +89,13 @@ module Mongoid # :nodoc:
|
|
89
89
|
# builder.process({ "id" => 1, "street" => "Bond" })
|
90
90
|
#
|
91
91
|
# @param [ Hash ] attrs The single document attributes to process.
|
92
|
-
def process(attrs)
|
93
|
-
return if reject?(attrs)
|
92
|
+
def process(parent, attrs)
|
93
|
+
return if reject?(parent, attrs)
|
94
94
|
if id = attrs["id"] || attrs["_id"]
|
95
95
|
doc = existing.find(convert_id(id))
|
96
96
|
if destroyable?(attrs)
|
97
97
|
existing.delete(doc)
|
98
|
+
doc.destroy unless doc.embedded?
|
98
99
|
else
|
99
100
|
metadata.embedded? ? doc.attributes = attrs : doc.update_attributes(attrs)
|
100
101
|
end
|
@@ -22,7 +22,7 @@ module Mongoid # :nodoc:
|
|
22
22
|
#
|
23
23
|
# parent: The parent document of the relation.
|
24
24
|
def build(parent)
|
25
|
-
return if reject?(attributes)
|
25
|
+
return if reject?(parent, attributes)
|
26
26
|
@existing = parent.send(metadata.name)
|
27
27
|
if update?
|
28
28
|
existing.attributes = attributes
|
@@ -29,7 +29,7 @@ module Mongoid # :nodoc:
|
|
29
29
|
# @example Get the value.
|
30
30
|
# builder.convertable
|
31
31
|
#
|
32
|
-
# @return [ String,
|
32
|
+
# @return [ String, BSON::ObjectId ] The string or object id.
|
33
33
|
#
|
34
34
|
# @since 2.0.2
|
35
35
|
def convertable(metadata, object)
|
@@ -37,7 +37,9 @@ module Mongoid # :nodoc:
|
|
37
37
|
if inverse.using_object_ids? || object.is_a?(BSON::ObjectId)
|
38
38
|
object
|
39
39
|
else
|
40
|
-
|
40
|
+
object.tap do |obj|
|
41
|
+
obj.unconvertable_to_bson = true if obj.is_a?(String)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
@@ -11,7 +11,14 @@ module Mongoid # :nodoc:
|
|
11
11
|
# @example Perform the cascading destroy.
|
12
12
|
# strategy.cascade
|
13
13
|
def cascade
|
14
|
-
|
14
|
+
if relation
|
15
|
+
if relation.is_a?(Enumerable)
|
16
|
+
relation.entries
|
17
|
+
relation.each { |doc| doc.destroy }
|
18
|
+
else
|
19
|
+
relation.destroy
|
20
|
+
end
|
21
|
+
end
|
15
22
|
end
|
16
23
|
end
|
17
24
|
end
|
@@ -268,6 +268,19 @@ module Mongoid # :nodoc:
|
|
268
268
|
end
|
269
269
|
end
|
270
270
|
|
271
|
+
# Get a criteria for the embedded documents without the default scoping
|
272
|
+
# applied.
|
273
|
+
#
|
274
|
+
# @example Get the unscoped criteria.
|
275
|
+
# person.addresses.unscoped
|
276
|
+
#
|
277
|
+
# @return [ Criteria ] The unscoped criteria.
|
278
|
+
#
|
279
|
+
# @since 2.2.1
|
280
|
+
def unscoped
|
281
|
+
criteria(false)
|
282
|
+
end
|
283
|
+
|
271
284
|
private
|
272
285
|
|
273
286
|
# Appends the document to the target array, updating the index on the
|
@@ -306,8 +319,8 @@ module Mongoid # :nodoc:
|
|
306
319
|
# relation.criteria
|
307
320
|
#
|
308
321
|
# @return [ Criteria ] A new criteria.
|
309
|
-
def criteria
|
310
|
-
klass.criteria(true).tap do |criterion|
|
322
|
+
def criteria(scoped = true)
|
323
|
+
klass.criteria(true, scoped).tap do |criterion|
|
311
324
|
criterion.documents = target
|
312
325
|
end
|
313
326
|
end
|
@@ -25,14 +25,21 @@ module Mongoid # :nodoc:
|
|
25
25
|
# @example Is there a reject proc?
|
26
26
|
# builder.reject?
|
27
27
|
#
|
28
|
+
# @param The parent document of the relation
|
28
29
|
# @param [ Hash ] attrs The attributes to check for rejection.
|
29
30
|
#
|
30
|
-
# @return [ true, false ] True and call proc if rejectable, false if not.
|
31
|
+
# @return [ true, false ] True and call proc or method if rejectable, false if not.
|
31
32
|
#
|
32
33
|
# @since 2.0.0.rc.1
|
33
|
-
def reject?(attrs)
|
34
|
-
|
35
|
-
|
34
|
+
def reject?(document, attrs)
|
35
|
+
case callback = options[:reject_if]
|
36
|
+
when Symbol
|
37
|
+
document.method(callback).arity == 0 ? document.send(callback) : document.send(callback, attrs)
|
38
|
+
when Proc
|
39
|
+
callback.call(attrs)
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
45
|
# Determines if only updates can occur. Only valid for one-to-one
|
@@ -329,7 +329,7 @@ module Mongoid #:nodoc:
|
|
329
329
|
# @example Get the value.
|
330
330
|
# relation.convertable
|
331
331
|
#
|
332
|
-
# @return [ String,
|
332
|
+
# @return [ String, BSON::ObjectId ] The string or object id.
|
333
333
|
#
|
334
334
|
# @since 2.0.2
|
335
335
|
def convertable
|
@@ -337,7 +337,9 @@ module Mongoid #:nodoc:
|
|
337
337
|
if inverse.using_object_ids? || base.id.is_a?(BSON::ObjectId)
|
338
338
|
base.id
|
339
339
|
else
|
340
|
-
|
340
|
+
base.id.tap do |id|
|
341
|
+
id.unconvertable_to_bson = true if id.is_a?(String)
|
342
|
+
end
|
341
343
|
end
|
342
344
|
end
|
343
345
|
|
@@ -35,6 +35,7 @@ module Mongoid # :nodoc:
|
|
35
35
|
doc.save
|
36
36
|
else
|
37
37
|
base.send(metadata.foreign_key).push(doc.id)
|
38
|
+
base.synced[metadata.foreign_key] = false
|
38
39
|
end
|
39
40
|
end
|
40
41
|
if persistable? || creating?
|
@@ -142,7 +143,7 @@ module Mongoid # :nodoc:
|
|
142
143
|
# @since 2.0.0.rc.1
|
143
144
|
def nullify
|
144
145
|
criteria.pull(metadata.inverse_foreign_key, base.id)
|
145
|
-
|
146
|
+
if persistable?
|
146
147
|
base.set(
|
147
148
|
metadata.foreign_key,
|
148
149
|
base.send(metadata.foreign_key).clear
|