forked from mongodb/mongoid
/
in.rb
231 lines (214 loc) · 7.2 KB
/
in.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# encoding: utf-8
module Mongoid
module Relations
module Embedded
# This class defines the behaviour necessary to handle relations that are
# embedded within another relation, either as a single document or
# multiple documents.
class In < Relations::One
# Instantiate a new embedded_in relation.
#
# @example Create the new relation.
# Embedded::In.new(name, person, metadata)
#
# @param [ Document ] base The document the relation hangs off of.
# @param [ Document ] target The target (parent) of the relation.
# @param [ Metadata ] metadata The relation metadata.
#
# @return [ In ] The proxy.
def initialize(base, target, metadata)
init(base, target, metadata) do
characterize_one(target)
bind_one
end
end
# Substitutes the supplied target documents for the existing document
# in the relation.
#
# @example Substitute the new document.
# person.name.substitute(new_name)
#
# @param [ Document ] other A document to replace the target.
#
# @return [ Document, nil ] The relation or nil.
#
# @since 2.0.0.rc.1
def substitute(replacement)
unbind_one
unless replacement
base.delete if persistable?
return nil
end
base.new_record = true
self.target = replacement
bind_one
self
end
private
# Instantiate the binding associated with this relation.
#
# @example Get the binding.
# binding([ address ])
#
# @param [ Proxy ] new_target The new documents to bind with.
#
# @return [ Binding ] A binding object.
#
# @since 2.0.0.rc.1
def binding
Bindings::Embedded::In.new(base, target, __metadata)
end
# Characterize the document.
#
# @example Set the base metadata.
# relation.characterize_one(document)
#
# @param [ Document ] document The document to set the metadata on.
#
# @since 2.1.0
def characterize_one(document)
unless base.__metadata
base.__metadata = __metadata.inverse_metadata(document)
end
end
# Are we able to persist this relation?
#
# @example Can we persist the relation?
# relation.persistable?
#
# @return [ true, false ] If the relation is persistable.
#
# @since 2.1.0
def persistable?
target.persisted? && !_binding? && !_building?
end
class << self
# Return the builder that is responsible for generating the documents
# that will be used by this relation.
#
# @example Get the builder.
# Embedded::In.builder(meta, object, person)
#
# @param [ Document ] base The base document.
# @param [ Metadata ] meta The metadata of the relation.
# @param [ Document, Hash ] object A document or attributes to build with.
#
# @return [ Builder ] A newly instantiated builder object.
#
# @since 2.0.0.rc.1
def builder(base, meta, object)
Builders::Embedded::In.new(base, meta, object)
end
# Returns true if the relation is an embedded one. In this case
# always true.
#
# @example Is this relation embedded?
# Embedded::In.embedded?
#
# @return [ true ] true.
#
# @since 2.0.0.rc.1
def embedded?
true
end
# Returns the suffix of the foreign key field, either "_id" or "_ids".
#
# @example Get the suffix for the foreign key.
# Referenced::Many.foreign_key_suffix
#
# @return [ nil ] nil.
#
# @since 3.0.0
def foreign_key_suffix
nil
end
# Returns the macro for this relation. Used mostly as a helper in
# reflection.
#
# @example Get the macro.
# Mongoid::Relations::Embedded::In.macro
#
# @return [ Symbol ] :embedded_in.
#
# @since 2.0.0.rc.1
def macro
:embedded_in
end
# Return the nested builder that is responsible for generating
# the documents that will be used by this relation.
#
# @example Get the builder.
# NestedAttributes::One.builder(attributes, options)
#
# @param [ Metadata ] metadata The relation metadata.
# @param [ Hash ] attributes The attributes to build with.
# @param [ Hash ] options The options for the builder.
#
# @option options [ true, false ] :allow_destroy Can documents be
# deleted?
# @option options [ Integer ] :limit Max number of documents to
# create at once.
# @option options [ Proc, Symbol ] :reject_if If documents match this
# option then they are ignored.
# @option options [ true, false ] :update_only Only existing documents
# can be modified.
#
# @return [ Builder ] A newly instantiated nested builder object.
#
# @since 2.0.0.rc.1
def nested_builder(metadata, attributes, options)
Builders::NestedAttributes::One.new(metadata, attributes, options)
end
# Get the path calculator for the supplied document.
#
# @example Get the path calculator.
# Proxy.path(document)
#
# @param [ Document ] document The document to calculate on.
#
# @return [ Root ] The root atomic path calculator.
#
# @since 2.1.0
def path(document)
Mongoid::Atomic::Paths::Root.new(document)
end
# Tells the caller if this relation is one that stores the foreign
# key on its own objects.
#
# @example Does this relation store a foreign key?
# Embedded::In.stores_foreign_key?
#
# @return [ false ] false.
#
# @since 2.0.0.rc.1
def stores_foreign_key?
false
end
# Get the valid options allowed with this relation.
#
# @example Get the valid options.
# Relation.valid_options
#
# @return [ Array<Symbol> ] The valid options.
#
# @since 2.1.0
def valid_options
[ :autobuild, :cyclic, :polymorphic, :touch ]
end
# Get the default validation setting for the relation. Determines if
# by default a validates associated will occur.
#
# @example Get the validation default.
# Proxy.validation_default
#
# @return [ true, false ] The validation default.
#
# @since 2.1.9
def validation_default
false
end
end
end
end
end
end