mongoid 2.0.0.rc.7 → 2.0.0.rc.8
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/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
|