mongoid 2.3.1 → 2.3.2
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 +34 -1
- data/lib/mongoid.rb +3 -2
- data/lib/mongoid/atomic.rb +23 -2
- data/lib/mongoid/attributes.rb +0 -21
- data/lib/mongoid/callbacks.rb +9 -1
- data/lib/mongoid/components.rb +2 -0
- data/lib/mongoid/config.rb +4 -2
- data/lib/mongoid/contexts/mongo.rb +19 -8
- data/lib/mongoid/criterion/inclusion.rb +6 -4
- data/lib/mongoid/dirty.rb +1 -0
- data/lib/mongoid/document.rb +1 -25
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +13 -0
- data/lib/mongoid/extensions/object/yoda.rb +1 -0
- data/lib/mongoid/matchers/strategies.rb +6 -1
- data/lib/mongoid/persistence.rb +2 -21
- data/lib/mongoid/railtie.rb +8 -1
- data/lib/mongoid/relations/accessors.rb +7 -5
- data/lib/mongoid/relations/binding.rb +2 -29
- data/lib/mongoid/relations/bindings/embedded/in.rb +4 -4
- data/lib/mongoid/relations/bindings/embedded/many.rb +4 -4
- data/lib/mongoid/relations/bindings/embedded/one.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/in.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/many.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/one.rb +4 -4
- data/lib/mongoid/relations/builder.rb +18 -4
- data/lib/mongoid/relations/builders.rb +0 -17
- data/lib/mongoid/relations/builders/embedded/in.rb +3 -3
- data/lib/mongoid/relations/builders/embedded/many.rb +4 -4
- data/lib/mongoid/relations/builders/embedded/one.rb +3 -3
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -0
- data/lib/mongoid/relations/embedded/in.rb +4 -3
- data/lib/mongoid/relations/embedded/many.rb +6 -5
- data/lib/mongoid/relations/embedded/one.rb +4 -3
- data/lib/mongoid/relations/metadata.rb +20 -5
- data/lib/mongoid/relations/proxy.rb +1 -48
- data/lib/mongoid/relations/referenced/in.rb +4 -3
- data/lib/mongoid/relations/referenced/many.rb +4 -3
- data/lib/mongoid/relations/referenced/many_to_many.rb +5 -4
- data/lib/mongoid/relations/referenced/one.rb +4 -3
- data/lib/mongoid/reloading.rb +91 -0
- data/lib/mongoid/state.rb +15 -22
- data/lib/mongoid/threaded.rb +51 -0
- data/lib/mongoid/threaded/lifecycle.rb +163 -0
- data/lib/mongoid/version.rb +1 -1
- metadata +21 -19
@@ -26,8 +26,8 @@ module Mongoid # :nodoc:
|
|
26
26
|
def bind
|
27
27
|
base.metadata = metadata.inverse_metadata(target)
|
28
28
|
base.parentize(target)
|
29
|
-
unless
|
30
|
-
|
29
|
+
unless _binding?
|
30
|
+
_binding do
|
31
31
|
if base.embedded_many?
|
32
32
|
target.do_or_do_not(metadata.inverse(target)).push(base)
|
33
33
|
else
|
@@ -51,8 +51,8 @@ module Mongoid # :nodoc:
|
|
51
51
|
#
|
52
52
|
# @since 2.0.0.rc.1
|
53
53
|
def unbind
|
54
|
-
unless
|
55
|
-
|
54
|
+
unless _binding?
|
55
|
+
_binding do
|
56
56
|
if base.embedded_many?
|
57
57
|
target.do_or_do_not(metadata.inverse(target)).delete(base)
|
58
58
|
else
|
@@ -42,8 +42,8 @@ module Mongoid # :nodoc:
|
|
42
42
|
# @since 2.0.0.rc.1
|
43
43
|
def bind_one(doc)
|
44
44
|
doc.parentize(base)
|
45
|
-
unless
|
46
|
-
|
45
|
+
unless _binding?
|
46
|
+
_binding do
|
47
47
|
unless metadata.versioned?
|
48
48
|
doc.do_or_do_not(metadata.inverse_setter(target), base)
|
49
49
|
end
|
@@ -80,8 +80,8 @@ module Mongoid # :nodoc:
|
|
80
80
|
#
|
81
81
|
# @since 2.0.0.rc.1
|
82
82
|
def unbind_one(doc)
|
83
|
-
unless
|
84
|
-
|
83
|
+
unless _binding?
|
84
|
+
_binding do
|
85
85
|
doc.do_or_do_not(metadata.inverse_setter(target), nil)
|
86
86
|
end
|
87
87
|
end
|
@@ -25,8 +25,8 @@ module Mongoid # :nodoc:
|
|
25
25
|
# @since 2.0.0.rc.1
|
26
26
|
def bind
|
27
27
|
target.parentize(base)
|
28
|
-
unless
|
29
|
-
|
28
|
+
unless _binding?
|
29
|
+
_binding do
|
30
30
|
target.do_or_do_not(metadata.inverse_setter(target), base)
|
31
31
|
end
|
32
32
|
end
|
@@ -47,8 +47,8 @@ module Mongoid # :nodoc:
|
|
47
47
|
#
|
48
48
|
# @since 2.0.0.rc.1
|
49
49
|
def unbind
|
50
|
-
unless
|
51
|
-
|
50
|
+
unless _binding?
|
51
|
+
_binding do
|
52
52
|
target.do_or_do_not(metadata.inverse_setter(target), nil)
|
53
53
|
end
|
54
54
|
end
|
@@ -19,8 +19,8 @@ module Mongoid # :nodoc:
|
|
19
19
|
#
|
20
20
|
# @since 2.0.0.rc.1
|
21
21
|
def bind
|
22
|
-
unless
|
23
|
-
|
22
|
+
unless _binding?
|
23
|
+
_binding do
|
24
24
|
inverse = metadata.inverse(target)
|
25
25
|
base.you_must(metadata.foreign_key_setter, target.id)
|
26
26
|
if metadata.inverse_type
|
@@ -51,8 +51,8 @@ module Mongoid # :nodoc:
|
|
51
51
|
#
|
52
52
|
# @since 2.0.0.rc.1
|
53
53
|
def unbind
|
54
|
-
unless
|
55
|
-
|
54
|
+
unless _binding?
|
55
|
+
_binding do
|
56
56
|
inverse = metadata.inverse(target)
|
57
57
|
base.you_must(metadata.foreign_key_setter, nil)
|
58
58
|
if metadata.inverse_type
|
@@ -17,8 +17,8 @@ module Mongoid # :nodoc:
|
|
17
17
|
#
|
18
18
|
# @since 2.0.0.rc.1
|
19
19
|
def bind_one(doc)
|
20
|
-
unless
|
21
|
-
|
20
|
+
unless _binding?
|
21
|
+
_binding do
|
22
22
|
doc.you_must(metadata.foreign_key_setter, base.id)
|
23
23
|
if metadata.type
|
24
24
|
doc.you_must(metadata.type_setter, base.class.model_name)
|
@@ -37,8 +37,8 @@ module Mongoid # :nodoc:
|
|
37
37
|
#
|
38
38
|
# @since 2.0.0.rc.1
|
39
39
|
def unbind_one(doc)
|
40
|
-
unless
|
41
|
-
|
40
|
+
unless _binding?
|
41
|
+
_binding do
|
42
42
|
doc.you_must(metadata.foreign_key_setter, nil)
|
43
43
|
if metadata.type
|
44
44
|
doc.you_must(metadata.type_setter, nil)
|
@@ -17,8 +17,8 @@ module Mongoid # :nodoc:
|
|
17
17
|
#
|
18
18
|
# @since 2.0.0.rc.1
|
19
19
|
def bind_one(doc)
|
20
|
-
unless
|
21
|
-
|
20
|
+
unless _binding?
|
21
|
+
_binding do
|
22
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
|
@@ -34,8 +34,8 @@ module Mongoid # :nodoc:
|
|
34
34
|
#
|
35
35
|
# @since 2.0.0.rc.1
|
36
36
|
def unbind_one(doc)
|
37
|
-
unless
|
38
|
-
|
37
|
+
unless _binding?
|
38
|
+
_binding do
|
39
39
|
base.send(metadata.foreign_key).delete_one(doc.id)
|
40
40
|
inverse_keys = doc.you_must(metadata.inverse_foreign_key)
|
41
41
|
inverse_keys.delete_one(base.id) if inverse_keys
|
@@ -19,8 +19,8 @@ module Mongoid # :nodoc:
|
|
19
19
|
#
|
20
20
|
# @since 2.0.0.rc.1
|
21
21
|
def bind
|
22
|
-
unless
|
23
|
-
|
22
|
+
unless _binding?
|
23
|
+
_binding do
|
24
24
|
target.you_must(metadata.foreign_key_setter, base.id)
|
25
25
|
target.send(metadata.inverse_setter, base)
|
26
26
|
if metadata.type
|
@@ -40,8 +40,8 @@ module Mongoid # :nodoc:
|
|
40
40
|
#
|
41
41
|
# @since 2.0.0.rc.1
|
42
42
|
def unbind
|
43
|
-
unless
|
44
|
-
|
43
|
+
unless _binding?
|
44
|
+
_binding do
|
45
45
|
target.you_must(metadata.foreign_key_setter, nil)
|
46
46
|
target.send(metadata.inverse_setter, nil)
|
47
47
|
if metadata.type
|
@@ -6,25 +6,39 @@ module Mongoid # :nodoc:
|
|
6
6
|
# looking up a relation's target from the database, or creating them from a
|
7
7
|
# supplied attributes hash.
|
8
8
|
class Builder
|
9
|
+
include Threaded::Lifecycle
|
9
10
|
|
10
|
-
attr_reader :
|
11
|
+
attr_reader :base, :metadata, :object
|
11
12
|
|
12
13
|
# Instantiate the new builder for a relation.
|
13
14
|
#
|
14
15
|
# @example Create the builder.
|
15
16
|
# Builder.new(metadata, { :field => "value })
|
16
17
|
#
|
18
|
+
# @param [ Document ] base The base document.
|
17
19
|
# @param [ Metdata ] metadata The metadata for the relation.
|
18
20
|
# @param [ Hash, BSON::ObjectId ] object The attributes to build from or
|
19
21
|
# id to query with.
|
20
22
|
#
|
21
23
|
# @since 2.0.0.rc.1
|
22
|
-
def initialize(metadata, object
|
23
|
-
@metadata, @object = metadata, object
|
24
|
-
@loading = loading
|
24
|
+
def initialize(base, metadata, object)
|
25
|
+
@base, @metadata, @object = base, metadata, object
|
25
26
|
end
|
26
27
|
|
27
28
|
protected
|
29
|
+
|
30
|
+
# Get the class from the metadata.
|
31
|
+
#
|
32
|
+
# @example Get the class.
|
33
|
+
# builder.klass
|
34
|
+
#
|
35
|
+
# @return [ Class ] The class from the metadata.
|
36
|
+
#
|
37
|
+
# @since 2.3.2
|
38
|
+
def klass
|
39
|
+
@klass ||= metadata.klass
|
40
|
+
end
|
41
|
+
|
28
42
|
# Do we need to perform a database query? It will be so if the object we
|
29
43
|
# have is not a document.
|
30
44
|
#
|
@@ -32,23 +32,6 @@ module Mongoid # :nodoc:
|
|
32
32
|
module Builders
|
33
33
|
extend ActiveSupport::Concern
|
34
34
|
|
35
|
-
# Execute a block in building mode.
|
36
|
-
#
|
37
|
-
# @example Execute in building mode.
|
38
|
-
# _building do
|
39
|
-
# relation.push(doc)
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# @return [ Object ] The return value of the block.
|
43
|
-
#
|
44
|
-
# @since 2.1.0
|
45
|
-
def _building
|
46
|
-
Threaded.begin_build
|
47
|
-
yield
|
48
|
-
ensure
|
49
|
-
Threaded.exit_build
|
50
|
-
end
|
51
|
-
|
52
35
|
module ClassMethods #:nodoc:
|
53
36
|
|
54
37
|
# Defines a builder method for an embeds_one relation. This is
|
@@ -16,10 +16,10 @@ module Mongoid # :nodoc:
|
|
16
16
|
# @return [ Document ] A single document.
|
17
17
|
def build(type = nil)
|
18
18
|
return object unless object.is_a?(Hash)
|
19
|
-
if
|
20
|
-
|
19
|
+
if _loading?
|
20
|
+
Factory.from_db(klass, object)
|
21
21
|
else
|
22
|
-
|
22
|
+
Factory.build(klass, object)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
2
|
require "mongoid/relations/embedded/sort"
|
4
3
|
|
5
4
|
module Mongoid # :nodoc:
|
@@ -8,6 +7,7 @@ module Mongoid # :nodoc:
|
|
8
7
|
module Embedded #:nodoc:
|
9
8
|
class Many < Builder #:nodoc:
|
10
9
|
include Relations::Embedded::Sort
|
10
|
+
|
11
11
|
# Builds the document out of the attributes using the provided
|
12
12
|
# metadata on the relation. Instantiates through the factory in order
|
13
13
|
# to make sure subclasses and allocation are used if fitting. This
|
@@ -24,10 +24,10 @@ module Mongoid # :nodoc:
|
|
24
24
|
return object if object.first.is_a?(Document)
|
25
25
|
[].tap do |docs|
|
26
26
|
object.each do |attrs|
|
27
|
-
if
|
28
|
-
docs <<
|
27
|
+
if _loading?
|
28
|
+
docs << Factory.from_db(klass, attrs)
|
29
29
|
else
|
30
|
-
docs <<
|
30
|
+
docs << Factory.build(klass, attrs)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
sort_documents!(docs, metadata) if metadata.order
|
@@ -17,10 +17,10 @@ module Mongoid # :nodoc:
|
|
17
17
|
# @return [ Document ] A single document.
|
18
18
|
def build(type = nil)
|
19
19
|
return object unless object.is_a?(Hash)
|
20
|
-
if
|
21
|
-
|
20
|
+
if _loading?
|
21
|
+
Factory.from_db(klass, object)
|
22
22
|
else
|
23
|
-
|
23
|
+
Factory.build(klass, object)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -91,7 +91,7 @@ module Mongoid # :nodoc:
|
|
91
91
|
# @param [ Hash ] attrs The single document attributes to process.
|
92
92
|
def process(parent, attrs)
|
93
93
|
return if reject?(parent, attrs)
|
94
|
-
if id = attrs
|
94
|
+
if id = attrs.extract_id
|
95
95
|
doc = existing.find(convert_id(id))
|
96
96
|
if destroyable?(attrs)
|
97
97
|
existing.delete(doc)
|
@@ -89,7 +89,7 @@ module Mongoid # :nodoc:
|
|
89
89
|
#
|
90
90
|
# @since 2.1.0
|
91
91
|
def persistable?
|
92
|
-
target.persisted? && !
|
92
|
+
target.persisted? && !_binding? && !_building?
|
93
93
|
end
|
94
94
|
|
95
95
|
class << self
|
@@ -100,14 +100,15 @@ module Mongoid # :nodoc:
|
|
100
100
|
# @example Get the builder.
|
101
101
|
# Embedded::In.builder(meta, object, person)
|
102
102
|
#
|
103
|
+
# @param [ Document ] base The base document.
|
103
104
|
# @param [ Metadata ] meta The metadata of the relation.
|
104
105
|
# @param [ Document, Hash ] object A document or attributes to build with.
|
105
106
|
#
|
106
107
|
# @return [ Builder ] A newly instantiated builder object.
|
107
108
|
#
|
108
109
|
# @since 2.0.0.rc.1
|
109
|
-
def builder(meta, object
|
110
|
-
Builders::Embedded::In.new(meta, object
|
110
|
+
def builder(base, meta, object)
|
111
|
+
Builders::Embedded::In.new(base, meta, object)
|
111
112
|
end
|
112
113
|
|
113
114
|
# Returns true if the relation is an embedded one. In this case
|
@@ -145,7 +145,7 @@ module Mongoid # :nodoc:
|
|
145
145
|
# @since 2.0.0.rc.1
|
146
146
|
def delete(document)
|
147
147
|
target.delete_one(document).tap do |doc|
|
148
|
-
if doc && !
|
148
|
+
if doc && !_binding?
|
149
149
|
if _assigning?
|
150
150
|
base.add_atomic_pull(doc)
|
151
151
|
else
|
@@ -261,7 +261,7 @@ module Mongoid # :nodoc:
|
|
261
261
|
else
|
262
262
|
atomically(:$set) do
|
263
263
|
if replacement.first.is_a?(Hash)
|
264
|
-
replacement = Many.builder(metadata, replacement).build
|
264
|
+
replacement = Many.builder(base, metadata, replacement).build
|
265
265
|
end
|
266
266
|
proxy.target = replacement.compact
|
267
267
|
if _assigning?
|
@@ -390,7 +390,7 @@ module Mongoid # :nodoc:
|
|
390
390
|
#
|
391
391
|
# @since 2.1.0
|
392
392
|
def persistable?
|
393
|
-
base.persisted? && !
|
393
|
+
base.persisted? && !_binding?
|
394
394
|
end
|
395
395
|
|
396
396
|
# Reindex all the target elements. This is useful when performing
|
@@ -437,6 +437,7 @@ module Mongoid # :nodoc:
|
|
437
437
|
# @example Get the builder.
|
438
438
|
# Embedded::Many.builder(meta, object)
|
439
439
|
#
|
440
|
+
# @param [ Document ] base The base document.
|
440
441
|
# @param [ Metadata ] meta The metadata of the relation.
|
441
442
|
# @param [ Document, Hash ] object A document or attributes to build
|
442
443
|
# with.
|
@@ -444,8 +445,8 @@ module Mongoid # :nodoc:
|
|
444
445
|
# @return [ Builder ] A newly instantiated builder object.
|
445
446
|
#
|
446
447
|
# @since 2.0.0.rc.1
|
447
|
-
def builder(meta, object
|
448
|
-
Builders::Embedded::Many.new(meta, object
|
448
|
+
def builder(base, meta, object)
|
449
|
+
Builders::Embedded::Many.new(base, meta, object)
|
449
450
|
end
|
450
451
|
|
451
452
|
# Returns true if the relation is an embedded one. In this case
|
@@ -73,7 +73,7 @@ module Mongoid # :nodoc:
|
|
73
73
|
#
|
74
74
|
# @since 2.1.0
|
75
75
|
def persistable?
|
76
|
-
base.persisted? && !
|
76
|
+
base.persisted? && !_binding? && !_building? && !_assigning?
|
77
77
|
end
|
78
78
|
|
79
79
|
class << self
|
@@ -84,14 +84,15 @@ module Mongoid # :nodoc:
|
|
84
84
|
# @example Get the builder.
|
85
85
|
# Embedded::One.builder(meta, object, person)
|
86
86
|
#
|
87
|
+
# @param [ Document ] base The base document.
|
87
88
|
# @param [ Metadata ] meta The metadata of the relation.
|
88
89
|
# @param [ Document, Hash ] object A document or attributes to build with.
|
89
90
|
#
|
90
91
|
# @return [ Builder ] A newly instantiated builder object.
|
91
92
|
#
|
92
93
|
# @since 2.0.0.rc.1
|
93
|
-
def builder(meta, object
|
94
|
-
Builders::Embedded::One.new(meta, object
|
94
|
+
def builder(base, meta, object)
|
95
|
+
Builders::Embedded::One.new(base, meta, object)
|
95
96
|
end
|
96
97
|
|
97
98
|
# Returns true if the relation is an embedded one. In this case
|
@@ -62,13 +62,14 @@ module Mongoid # :nodoc:
|
|
62
62
|
# @example Get the builder.
|
63
63
|
# metadata.builder(document)
|
64
64
|
#
|
65
|
+
# @param [ Document ] base The base document.
|
65
66
|
# @param [ Object ] object A document or attributes to give the builder.
|
66
67
|
#
|
67
68
|
# @return [ Builder ] The builder for the relation.
|
68
69
|
#
|
69
70
|
# @since 2.0.0.rc.1
|
70
|
-
def builder(
|
71
|
-
relation.builder(self, object
|
71
|
+
def builder(base, object)
|
72
|
+
relation.builder(base, self, object)
|
72
73
|
end
|
73
74
|
|
74
75
|
# Returns the name of the strategy used for handling dependent relations.
|
@@ -401,9 +402,7 @@ module Mongoid # :nodoc:
|
|
401
402
|
#
|
402
403
|
# @since 2.0.0.rc.1
|
403
404
|
def inverse_foreign_key
|
404
|
-
@inverse_foreign_key ||=
|
405
|
-
( inverse_of ? inverse_of.to_s.singularize : inverse_class_name.demodulize.underscore ) <<
|
406
|
-
relation.foreign_key_suffix
|
405
|
+
@inverse_foreign_key ||= determine_inverse_foreign_key
|
407
406
|
end
|
408
407
|
|
409
408
|
# Returns the inverse class of the proxied relation.
|
@@ -809,6 +808,22 @@ module Mongoid # :nodoc:
|
|
809
808
|
end
|
810
809
|
end
|
811
810
|
|
811
|
+
# Determine the inverse foreign key of the relation.
|
812
|
+
#
|
813
|
+
# @example Determine the inverse foreign key.
|
814
|
+
# metadata.determine_inverse_foreign_key
|
815
|
+
#
|
816
|
+
# @return [ String ] The inverse.
|
817
|
+
#
|
818
|
+
# @since 2.3.2
|
819
|
+
def determine_inverse_foreign_key
|
820
|
+
if has_key?(:inverse_of)
|
821
|
+
inverse_of ? "#{inverse_of.to_s.singularize}#{relation.foreign_key_suffix}" : nil
|
822
|
+
else
|
823
|
+
"#{inverse_class_name.demodulize.underscore}#{relation.foreign_key_suffix}"
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
812
827
|
# Determine the inverse relation. Memoizing #inverse_relation and adding
|
813
828
|
# this method dropped 5 seconds off the test suite as a performance
|
814
829
|
# improvement.
|