mongoid 2.3.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|