mongoid 2.0.0.rc.7 → 2.0.0.rc.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/config/locales/en.yml +3 -0
- data/lib/config/locales/id.yml +46 -0
- data/lib/config/locales/ja.yml +40 -0
- data/lib/config/locales/vi.yml +45 -0
- data/lib/mongoid.rb +5 -3
- data/lib/mongoid/attributes.rb +24 -63
- data/lib/mongoid/attributes/processing.rb +5 -2
- data/lib/mongoid/callbacks.rb +10 -0
- data/lib/mongoid/collection.rb +24 -0
- data/lib/mongoid/collections/master.rb +14 -6
- data/lib/mongoid/collections/operations.rb +1 -1
- data/lib/mongoid/collections/retry.rb +39 -0
- data/lib/mongoid/collections/slaves.rb +26 -10
- data/lib/mongoid/components.rb +4 -4
- data/lib/mongoid/config.rb +6 -3
- data/lib/mongoid/contexts.rb +0 -1
- data/lib/mongoid/contexts/enumerable.rb +19 -7
- data/lib/mongoid/contexts/mongo.rb +9 -5
- data/lib/mongoid/copyable.rb +10 -8
- data/lib/mongoid/criteria.rb +83 -61
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +2 -2
- data/lib/mongoid/criterion/exclusion.rb +58 -32
- data/lib/mongoid/criterion/inclusion.rb +49 -10
- data/lib/mongoid/criterion/optional.rb +1 -1
- data/lib/mongoid/criterion/selector.rb +80 -11
- data/lib/mongoid/cursor.rb +6 -1
- data/lib/mongoid/default_scope.rb +27 -19
- data/lib/mongoid/document.rb +26 -1
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +7 -4
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/field.rb +47 -30
- data/lib/mongoid/fields.rb +9 -2
- data/lib/mongoid/finders.rb +15 -49
- data/lib/mongoid/identity.rb +6 -4
- data/lib/mongoid/keys.rb +85 -31
- data/lib/mongoid/multi_parameter_attributes.rb +2 -2
- data/lib/mongoid/named_scope.rb +129 -28
- data/lib/mongoid/observer.rb +36 -0
- data/lib/mongoid/paranoia.rb +3 -3
- data/lib/mongoid/paths.rb +1 -1
- data/lib/mongoid/persistence.rb +2 -0
- data/lib/mongoid/persistence/atomic.rb +88 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +30 -0
- data/lib/mongoid/persistence/atomic/inc.rb +28 -0
- data/lib/mongoid/persistence/atomic/operation.rb +44 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
- data/lib/mongoid/persistence/atomic/push.rb +28 -0
- data/lib/mongoid/railtie.rb +13 -1
- data/lib/mongoid/relations.rb +1 -0
- data/lib/mongoid/relations/accessors.rb +20 -2
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +17 -6
- data/lib/mongoid/relations/builders/referenced/many.rb +2 -1
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -0
- data/lib/mongoid/relations/embedded/atomic.rb +86 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/many.rb +57 -25
- data/lib/mongoid/relations/macros.rb +6 -4
- data/lib/mongoid/relations/many.rb +51 -10
- data/lib/mongoid/relations/metadata.rb +4 -2
- data/lib/mongoid/relations/proxy.rb +39 -24
- data/lib/mongoid/relations/referenced/many.rb +47 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +47 -14
- data/lib/mongoid/relations/referenced/one.rb +14 -0
- data/lib/mongoid/sharding.rb +51 -0
- data/lib/mongoid/state.rb +3 -2
- data/lib/mongoid/timestamps.rb +5 -29
- data/lib/mongoid/timestamps/created.rb +31 -0
- data/lib/mongoid/timestamps/updated.rb +33 -0
- data/lib/mongoid/validations.rb +10 -3
- data/lib/mongoid/validations/referenced.rb +58 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +67 -5
- data/lib/rails/generators/mongoid/model/templates/model.rb +2 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +10 -1
- data/lib/rails/mongoid.rb +1 -0
- metadata +29 -8
- data/lib/mongoid/contexts/ids.rb +0 -25
- data/lib/mongoid/modifiers.rb +0 -24
- data/lib/mongoid/modifiers/command.rb +0 -18
- data/lib/mongoid/modifiers/inc.rb +0 -24
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Pull < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The pull operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$pull" =>
|
19
|
+
{ path =>
|
20
|
+
{ "_id" =>
|
21
|
+
{ "$in" => documents.map { |doc| doc["_id"] } }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Parses the incoming operations to get the documents to set.
|
30
|
+
#
|
31
|
+
# @example Parse the operations.
|
32
|
+
# set.parse(
|
33
|
+
# { "$pull" => { "addresses" => { "_id" => "street" } } }
|
34
|
+
# )
|
35
|
+
#
|
36
|
+
# @param [ Hash ] operations The ops to parse.
|
37
|
+
#
|
38
|
+
# @since 2.0.0
|
39
|
+
def parse(operations)
|
40
|
+
modifier = operations.keys.first
|
41
|
+
extract(modifier, operations[modifier])
|
42
|
+
end
|
43
|
+
|
44
|
+
# Extract a document from the operation.
|
45
|
+
#
|
46
|
+
# @example Extract the document.
|
47
|
+
# set.extract({ "$pull" => [{ "_id" => "street" }] })
|
48
|
+
#
|
49
|
+
# @param [ Hash ] operation The op to extract from.
|
50
|
+
#
|
51
|
+
# @since 2.0.0
|
52
|
+
def extract(modifier, operations)
|
53
|
+
@path = operations.keys.first
|
54
|
+
case modifier
|
55
|
+
when "$pull"
|
56
|
+
documents.push(operations[path])
|
57
|
+
when "$pullAll"
|
58
|
+
documents.concat(operations[path])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class PushAll < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The set operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$pushAll" => { path => documents } }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Parses the incoming operations to get the documents to set.
|
24
|
+
#
|
25
|
+
# @example Parse the operations.
|
26
|
+
# set.parse(
|
27
|
+
# { "$push" => { "addresses" => { "_id" => "street" } } }
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @param [ Hash ] operations The ops to parse.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def parse(operations)
|
34
|
+
modifier = operations.keys.first
|
35
|
+
extract(modifier, operations[modifier])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Extract a document from the operation.
|
39
|
+
#
|
40
|
+
# @example Extract the document.
|
41
|
+
# set.extract({ "$pushAll" => [{ "_id" => "street" }] })
|
42
|
+
#
|
43
|
+
# @param [ Hash ] operation The op to extract from.
|
44
|
+
#
|
45
|
+
# @since 2.0.0
|
46
|
+
def extract(modifier, operations)
|
47
|
+
@path = operations.keys.first
|
48
|
+
case modifier
|
49
|
+
when "$push"
|
50
|
+
documents.push(operations[path])
|
51
|
+
when "$pushAll"
|
52
|
+
documents.concat(operations[path])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Set < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The set operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$set" => { path => documents } }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Parses the incoming operations to get the documents to set.
|
24
|
+
#
|
25
|
+
# @example Parse the operations.
|
26
|
+
# set.parse(
|
27
|
+
# { "addresses" => { "$pushAll" => [{ "_id" => "street" }] } }
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @param [ Hash ] operations The ops to parse.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def parse(operations)
|
34
|
+
modifier = operations.keys.first
|
35
|
+
extract(modifier, operations[modifier])
|
36
|
+
end
|
37
|
+
|
38
|
+
# Extract a document from the operation.
|
39
|
+
#
|
40
|
+
# @example Extract the document.
|
41
|
+
# set.extract({ "$pushAll" => [{ "_id" => "street" }] })
|
42
|
+
#
|
43
|
+
# @param [ Hash ] operation The op to extract from.
|
44
|
+
#
|
45
|
+
# @since 2.0.0
|
46
|
+
def extract(modifier, operations)
|
47
|
+
@path = operations.keys.first
|
48
|
+
case modifier
|
49
|
+
when "$push"
|
50
|
+
documents.push(operations[path])
|
51
|
+
when "$pushAll"
|
52
|
+
documents.push(operations[path].first)
|
53
|
+
when "$set"
|
54
|
+
@documents = operations[path]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Relations #:nodoc:
|
4
|
+
module Embedded #:nodoc:
|
5
|
+
module Atomic #:nodoc:
|
6
|
+
|
7
|
+
class Unset < Operation
|
8
|
+
|
9
|
+
# Get the merged operations for the single atomic set.
|
10
|
+
#
|
11
|
+
# @example Get the operations
|
12
|
+
# set.operations
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The set operations.
|
15
|
+
#
|
16
|
+
# @since 2.0.0
|
17
|
+
def operations
|
18
|
+
{ "$unset" => { path => true } }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Parses the incoming operations to get the documents to set.
|
24
|
+
#
|
25
|
+
# @example Parse the operations.
|
26
|
+
# set.parse(
|
27
|
+
# { "addresses" => { "$pushAll" => [{ "_id" => "street" }] } }
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @param [ Hash ] operations The ops to parse.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def parse(operations)
|
34
|
+
modifier = operations.keys.first
|
35
|
+
@path ||= operations[modifier].keys.first
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -6,6 +6,31 @@ module Mongoid # :nodoc:
|
|
6
6
|
# This class handles the behaviour for a document that embeds many other
|
7
7
|
# documents within in it as an array.
|
8
8
|
class Many < Relations::Many
|
9
|
+
include Atomic
|
10
|
+
|
11
|
+
# Appends a document or array of documents to the relation. Will set
|
12
|
+
# the parent and update the index in the process.
|
13
|
+
#
|
14
|
+
# @example Append a document.
|
15
|
+
# person.addresses << address
|
16
|
+
#
|
17
|
+
# @example Push a document.
|
18
|
+
# person.addresses.push(address)
|
19
|
+
#
|
20
|
+
# @example Concat with other documents.
|
21
|
+
# person.addresses.concat([ address_one, address_two ])
|
22
|
+
#
|
23
|
+
# @param [ Document, Array<Document> ] *args Any number of documents.
|
24
|
+
def <<(*args)
|
25
|
+
options = default_options(args)
|
26
|
+
atomically(:$pushAll) do
|
27
|
+
args.flatten.each do |doc|
|
28
|
+
return doc unless doc
|
29
|
+
append(doc, options)
|
30
|
+
doc.save if base.persisted? && !options[:binding]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
9
34
|
|
10
35
|
# Binds the base object to the inverse of the relation. This is so we
|
11
36
|
# are referenced to the actual objects themselves and dont hit the
|
@@ -26,7 +51,9 @@ module Mongoid # :nodoc:
|
|
26
51
|
# @since 2.0.0.rc.1
|
27
52
|
def bind(options = {})
|
28
53
|
binding.bind(options)
|
29
|
-
|
54
|
+
if base.persisted? && !options[:binding]
|
55
|
+
atomically(:$set) { target.each(&:save) }
|
56
|
+
end
|
30
57
|
end
|
31
58
|
|
32
59
|
# Bind the inverse relation between a single document in this proxy
|
@@ -80,8 +107,8 @@ module Mongoid # :nodoc:
|
|
80
107
|
# @param [ Class ] type Optional class to create the document with.
|
81
108
|
#
|
82
109
|
# @return [ Document ] The newly created document.
|
83
|
-
def create(attributes = {}, type = nil)
|
84
|
-
build(attributes, type).tap(&:save)
|
110
|
+
def create(attributes = {}, type = nil, &block)
|
111
|
+
build(attributes, type, &block).tap(&:save)
|
85
112
|
end
|
86
113
|
|
87
114
|
# Create a new document in the relation. This is essentially the same
|
@@ -97,15 +124,15 @@ module Mongoid # :nodoc:
|
|
97
124
|
# @raise [ Errors::Validations ] If a validation error occured.
|
98
125
|
#
|
99
126
|
# @return [ Document ] The newly created document.
|
100
|
-
def create!(attributes = {}, type = nil)
|
101
|
-
build(attributes, type).tap(&:save!)
|
127
|
+
def create!(attributes = {}, type = nil, &block)
|
128
|
+
build(attributes, type, &block).tap(&:save!)
|
102
129
|
end
|
103
130
|
|
104
131
|
# Delete the supplied document from the target. This method is proxied
|
105
132
|
# in order to reindex the array after the operation occurs.
|
106
133
|
#
|
107
134
|
# @example Delete the document from the relation.
|
108
|
-
#
|
135
|
+
# person.addresses.delete(address)
|
109
136
|
#
|
110
137
|
# @param [ Document ] document The document to be deleted.
|
111
138
|
#
|
@@ -128,7 +155,7 @@ module Mongoid # :nodoc:
|
|
128
155
|
#
|
129
156
|
# @return [ Integer ] The number of documents deleted.
|
130
157
|
def delete_all(conditions = {})
|
131
|
-
remove_all(conditions,
|
158
|
+
atomically(:$pull) { remove_all(conditions, :delete) }
|
132
159
|
end
|
133
160
|
|
134
161
|
# Destroy all the documents in the association whilst running callbacks.
|
@@ -143,7 +170,7 @@ module Mongoid # :nodoc:
|
|
143
170
|
#
|
144
171
|
# @return [ Integer ] The number of documents destroyed.
|
145
172
|
def destroy_all(conditions = {})
|
146
|
-
remove_all(conditions,
|
173
|
+
atomically(:$pull) { remove_all(conditions, :destroy) }
|
147
174
|
end
|
148
175
|
|
149
176
|
# Finds a document in this association through several different
|
@@ -164,15 +191,7 @@ module Mongoid # :nodoc:
|
|
164
191
|
#
|
165
192
|
# @return [ Array<Document>, Document ] A single or multiple documents.
|
166
193
|
def find(*args)
|
167
|
-
|
168
|
-
case type
|
169
|
-
when :first then return criteria.one
|
170
|
-
when :last then return criteria.last
|
171
|
-
else
|
172
|
-
criteria.tap do |crit|
|
173
|
-
crit.documents = target if crit.is_a?(Criteria)
|
174
|
-
end
|
175
|
-
end
|
194
|
+
criteria.find(*args)
|
176
195
|
end
|
177
196
|
|
178
197
|
# Instantiate a new embeds_many relation.
|
@@ -226,8 +245,6 @@ module Mongoid # :nodoc:
|
|
226
245
|
#
|
227
246
|
# @return [ WillPaginate::Collection ] The paginated documents.
|
228
247
|
def paginate(options)
|
229
|
-
criteria = Mongoid::Criteria.translate(metadata.klass, true, options)
|
230
|
-
criteria.documents = target
|
231
248
|
criteria.paginate(options)
|
232
249
|
end
|
233
250
|
|
@@ -248,10 +265,9 @@ module Mongoid # :nodoc:
|
|
248
265
|
tap do |relation|
|
249
266
|
relation.target = new_target || []
|
250
267
|
if !new_target.blank?
|
251
|
-
|
252
|
-
bind(options)
|
268
|
+
atomically(:$set) { rebind(old_target, options) }
|
253
269
|
else
|
254
|
-
unbind(old_target, options)
|
270
|
+
atomically(:$unset) { unbind(old_target, options) }
|
255
271
|
end
|
256
272
|
end
|
257
273
|
end
|
@@ -382,17 +398,33 @@ module Mongoid # :nodoc:
|
|
382
398
|
# @param [ true, false ] destroy If true then destroy, else delete.
|
383
399
|
#
|
384
400
|
# @return [ Integer ] The number of documents removed.
|
385
|
-
def remove_all(conditions = {},
|
386
|
-
criteria = find(conditions || {})
|
401
|
+
def remove_all(conditions = {}, method = :delete)
|
402
|
+
criteria = find(:all, conditions || {})
|
387
403
|
criteria.size.tap do
|
388
404
|
criteria.each do |doc|
|
389
405
|
target.delete(doc)
|
390
|
-
|
406
|
+
doc.send(method)
|
391
407
|
end
|
392
408
|
reindex
|
393
409
|
end
|
394
410
|
end
|
395
411
|
|
412
|
+
# Convenience method to clean up the substitute code. Unbinds the old
|
413
|
+
# target and reindexes.
|
414
|
+
#
|
415
|
+
# @example Rebind the relation.
|
416
|
+
# relation.rebind([])
|
417
|
+
#
|
418
|
+
# @param [ Array<Document> ] old_target The old target.
|
419
|
+
# @param [ Hash ] options The options passed to substitute.
|
420
|
+
#
|
421
|
+
# @since 2.0.0
|
422
|
+
def rebind(old_target, options)
|
423
|
+
reindex
|
424
|
+
unbind(old_target, options)
|
425
|
+
bind(options)
|
426
|
+
end
|
427
|
+
|
396
428
|
class << self
|
397
429
|
|
398
430
|
# Return the builder that is responsible for generating the documents
|
@@ -78,7 +78,7 @@ module Mongoid # :nodoc:
|
|
78
78
|
def embeds_many(name, options = {}, &block)
|
79
79
|
characterize(name, Embedded::Many, options, &block).tap do |meta|
|
80
80
|
relate(name, meta)
|
81
|
-
|
81
|
+
validates_relation(meta)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -105,7 +105,7 @@ module Mongoid # :nodoc:
|
|
105
105
|
characterize(name, Embedded::One, options, &block).tap do |meta|
|
106
106
|
relate(name, meta)
|
107
107
|
builder(name).creator(name)
|
108
|
-
|
108
|
+
validates_relation(meta)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
@@ -131,6 +131,7 @@ module Mongoid # :nodoc:
|
|
131
131
|
characterize(name, Referenced::In, options, &block).tap do |meta|
|
132
132
|
relate(name, meta)
|
133
133
|
reference(meta)
|
134
|
+
validates_relation(meta)
|
134
135
|
end
|
135
136
|
end
|
136
137
|
alias :belongs_to_related :referenced_in
|
@@ -160,7 +161,7 @@ module Mongoid # :nodoc:
|
|
160
161
|
relate(name, meta)
|
161
162
|
reference(meta)
|
162
163
|
autosave(meta)
|
163
|
-
|
164
|
+
validates_relation(meta)
|
164
165
|
end
|
165
166
|
end
|
166
167
|
alias :has_many_related :references_many
|
@@ -190,6 +191,7 @@ module Mongoid # :nodoc:
|
|
190
191
|
characterize(name, Referenced::ManyToMany, options, &block).tap do |meta|
|
191
192
|
relate(name, meta)
|
192
193
|
reference(meta)
|
194
|
+
validates_relation(meta)
|
193
195
|
end
|
194
196
|
end
|
195
197
|
alias :has_and_belongs_to_many :references_and_referenced_in_many
|
@@ -217,7 +219,7 @@ module Mongoid # :nodoc:
|
|
217
219
|
relate(name, meta)
|
218
220
|
reference(meta)
|
219
221
|
builder(name).creator(name).autosave(meta)
|
220
|
-
|
222
|
+
validates_relation(meta)
|
221
223
|
end
|
222
224
|
end
|
223
225
|
alias :has_one_related :references_one
|
@@ -16,7 +16,7 @@ module Mongoid #:nodoc:
|
|
16
16
|
# person.addresses.push(address)
|
17
17
|
#
|
18
18
|
# @example Concat with other documents.
|
19
|
-
#
|
19
|
+
# person.addresses.concat([ address_one, address_two ])
|
20
20
|
#
|
21
21
|
# @param [ Document, Array<Document> ] *args Any number of documents.
|
22
22
|
def <<(*args)
|
@@ -40,11 +40,12 @@ module Mongoid #:nodoc:
|
|
40
40
|
# @param [ Class ] type Optional class to build the document with.
|
41
41
|
#
|
42
42
|
# @return [ Document ] The new document.
|
43
|
-
def build(attributes = {}, type = nil)
|
43
|
+
def build(attributes = {}, type = nil, &block)
|
44
44
|
instantiated(type).tap do |doc|
|
45
|
-
append(doc, default_options(:binding => true))
|
46
45
|
doc.write_attributes(attributes)
|
47
46
|
doc.identify
|
47
|
+
append(doc, default_options(:binding => true))
|
48
|
+
block.call(doc) if block
|
48
49
|
end
|
49
50
|
end
|
50
51
|
alias :new :build
|
@@ -59,8 +60,9 @@ module Mongoid #:nodoc:
|
|
59
60
|
# @param [ Class ] type The optional type of document to create.
|
60
61
|
#
|
61
62
|
# @return [ Document ] The newly created document.
|
62
|
-
def create(attributes = nil, type = nil)
|
63
|
+
def create(attributes = nil, type = nil, &block)
|
63
64
|
build(attributes, type).tap do |doc|
|
65
|
+
block.call(doc) if block
|
64
66
|
doc.save if base.persisted?
|
65
67
|
end
|
66
68
|
end
|
@@ -103,8 +105,8 @@ module Mongoid #:nodoc:
|
|
103
105
|
# @param [ Hash ] attrs The attributes to search or create with.
|
104
106
|
#
|
105
107
|
# @return [ Document ] An existing document or newly created one.
|
106
|
-
def find_or_create_by(attrs = {})
|
107
|
-
find_or(:create, attrs)
|
108
|
+
def find_or_create_by(attrs = {}, &block)
|
109
|
+
find_or(:create, attrs, &block)
|
108
110
|
end
|
109
111
|
|
110
112
|
# Find the first +Document+ given the conditions, or instantiates a new document
|
@@ -116,8 +118,34 @@ module Mongoid #:nodoc:
|
|
116
118
|
# @param [ Hash ] attrs The attributes to search or initialize with.
|
117
119
|
#
|
118
120
|
# @return [ Document ] An existing document or newly instantiated one.
|
119
|
-
def find_or_initialize_by(attrs = {})
|
120
|
-
find_or(:build, attrs)
|
121
|
+
def find_or_initialize_by(attrs = {}, &block)
|
122
|
+
find_or(:build, attrs, &block)
|
123
|
+
end
|
124
|
+
|
125
|
+
# This proxy can never be nil.
|
126
|
+
#
|
127
|
+
# @example Is the proxy nil?
|
128
|
+
# relation.nil?
|
129
|
+
#
|
130
|
+
# @return [ false ] Always false.
|
131
|
+
#
|
132
|
+
# @since 2.0.0
|
133
|
+
def nil?
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
137
|
+
# Since method_missing is overridden we should override this as well.
|
138
|
+
#
|
139
|
+
# @example Does the proxy respond to the method?
|
140
|
+
# relation.respond_to?(:name)
|
141
|
+
#
|
142
|
+
# @param [ Symbol ] name The method name.
|
143
|
+
#
|
144
|
+
# @return [ true, false ] If the proxy responds to the method.
|
145
|
+
#
|
146
|
+
# @since 2.0.0
|
147
|
+
def respond_to?(name)
|
148
|
+
[].respond_to?(name) || methods.include?(name)
|
121
149
|
end
|
122
150
|
|
123
151
|
# Gets the document as a serializable hash, used by ActiveModel's JSON and
|
@@ -140,6 +168,19 @@ module Mongoid #:nodoc:
|
|
140
168
|
target.map { |document| document.serializable_hash(options) }
|
141
169
|
end
|
142
170
|
|
171
|
+
# Always returns the number of documents that are in memory.
|
172
|
+
#
|
173
|
+
# @example Get the number of loaded documents.
|
174
|
+
# relation.size
|
175
|
+
#
|
176
|
+
# @return [ Integer ] The number of documents in memory.
|
177
|
+
#
|
178
|
+
# @since 2.0.0
|
179
|
+
def size
|
180
|
+
target.size
|
181
|
+
end
|
182
|
+
alias :length :size
|
183
|
+
|
143
184
|
private
|
144
185
|
|
145
186
|
# Get the default options used in binding functions.
|
@@ -164,8 +205,8 @@ module Mongoid #:nodoc:
|
|
164
205
|
# @param [ Hash ] attrs The attributes to build with.
|
165
206
|
#
|
166
207
|
# @return [ Document ] A matching document or a new/created one.
|
167
|
-
def find_or(method, attrs = {})
|
168
|
-
find(:first, :conditions => attrs) || send(method, attrs)
|
208
|
+
def find_or(method, attrs = {}, &block)
|
209
|
+
find(:first, :conditions => attrs) || send(method, attrs, &block)
|
169
210
|
end
|
170
211
|
end
|
171
212
|
end
|