mongoid 2.0.2 → 2.1.0
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/README.rdoc +3 -1
- data/Rakefile +3 -2
- data/lib/config/locales/bg.yml +6 -0
- data/lib/config/locales/de.yml +6 -0
- data/lib/config/locales/en-GB.yml +48 -0
- data/lib/config/locales/en.yml +6 -3
- data/lib/config/locales/es.yml +6 -0
- data/lib/config/locales/fr.yml +6 -0
- data/lib/config/locales/hi.yml +39 -0
- data/lib/config/locales/hu.yml +13 -7
- data/lib/config/locales/id.yml +3 -0
- data/lib/config/locales/it.yml +7 -1
- data/lib/config/locales/ja.yml +4 -1
- data/lib/config/locales/kr.yml +9 -34
- data/lib/config/locales/nl.yml +6 -0
- data/lib/config/locales/pl.yml +6 -0
- data/lib/config/locales/pt-BR.yml +6 -0
- data/lib/config/locales/pt.yml +6 -0
- data/lib/config/locales/ro.yml +6 -0
- data/lib/config/locales/ru.yml +6 -0
- data/lib/config/locales/sv.yml +6 -0
- data/lib/config/locales/vi.yml +3 -0
- data/lib/config/locales/zh-CN.yml +6 -0
- data/lib/mongoid.rb +51 -45
- data/lib/mongoid/atomic.rb +145 -0
- data/lib/mongoid/atomic/modifiers.rb +109 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +43 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
- data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
- data/lib/mongoid/atomic/paths/root.rb +40 -0
- data/lib/mongoid/attributes.rb +12 -23
- data/lib/mongoid/attributes/processing.rb +5 -5
- data/lib/mongoid/callbacks.rb +2 -0
- data/lib/mongoid/collection.rb +12 -59
- data/lib/mongoid/collections.rb +23 -20
- data/lib/mongoid/collections/master.rb +6 -4
- data/lib/mongoid/collections/operations.rb +1 -0
- data/lib/mongoid/collections/retry.rb +7 -0
- data/lib/mongoid/components.rb +2 -2
- data/lib/mongoid/config.rb +42 -55
- data/lib/mongoid/config/database.rb +6 -2
- data/lib/mongoid/config/replset_database.rb +7 -3
- data/lib/mongoid/contexts.rb +9 -3
- data/lib/mongoid/contexts/enumerable.rb +7 -3
- data/lib/mongoid/contexts/mongo.rb +139 -101
- data/lib/mongoid/criteria.rb +86 -69
- data/lib/mongoid/criterion/complex.rb +32 -5
- data/lib/mongoid/criterion/inclusion.rb +4 -2
- data/lib/mongoid/criterion/optional.rb +111 -86
- data/lib/mongoid/criterion/selector.rb +8 -4
- data/lib/mongoid/cursor.rb +27 -27
- data/lib/mongoid/dirty.rb +54 -214
- data/lib/mongoid/document.rb +37 -39
- data/lib/mongoid/errors/document_not_found.rb +3 -4
- data/lib/mongoid/errors/invalid_collection.rb +2 -3
- data/lib/mongoid/errors/invalid_database.rb +2 -3
- data/lib/mongoid/errors/invalid_field.rb +2 -3
- data/lib/mongoid/errors/invalid_options.rb +19 -7
- data/lib/mongoid/errors/invalid_type.rb +2 -3
- data/lib/mongoid/errors/mongoid_error.rb +5 -6
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -3
- data/lib/mongoid/errors/unsupported_version.rb +2 -3
- data/lib/mongoid/errors/validations.rb +2 -3
- data/lib/mongoid/extensions.rb +8 -62
- data/lib/mongoid/extensions/array/deletion.rb +29 -0
- data/lib/mongoid/extensions/false_class/equality.rb +14 -1
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +21 -10
- data/lib/mongoid/extensions/hash/scoping.rb +14 -1
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -1
- data/lib/mongoid/extensions/object/reflections.rb +33 -2
- data/lib/mongoid/extensions/object_id/conversions.rb +2 -36
- data/lib/mongoid/extensions/proc/scoping.rb +14 -1
- data/lib/mongoid/extensions/string/conversions.rb +4 -16
- data/lib/mongoid/extensions/string/inflections.rb +35 -14
- data/lib/mongoid/extensions/symbol/inflections.rb +38 -12
- data/lib/mongoid/extensions/true_class/equality.rb +14 -1
- data/lib/mongoid/extras.rb +11 -30
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields.rb +121 -29
- data/lib/mongoid/fields/mappings.rb +36 -0
- data/lib/mongoid/fields/serializable.rb +131 -0
- data/lib/mongoid/fields/serializable/array.rb +64 -0
- data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
- data/lib/mongoid/fields/serializable/bignum.rb +10 -0
- data/lib/mongoid/fields/serializable/binary.rb +11 -0
- data/lib/mongoid/fields/serializable/boolean.rb +44 -0
- data/lib/mongoid/fields/serializable/date.rb +51 -0
- data/lib/mongoid/fields/serializable/date_time.rb +28 -0
- data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
- data/lib/mongoid/fields/serializable/float.rb +33 -0
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +56 -0
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +43 -0
- data/lib/mongoid/fields/serializable/hash.rb +25 -0
- data/lib/mongoid/fields/serializable/integer.rb +33 -0
- data/lib/mongoid/fields/serializable/object.rb +11 -0
- data/lib/mongoid/fields/serializable/object_id.rb +32 -0
- data/lib/mongoid/fields/serializable/range.rb +42 -0
- data/lib/mongoid/fields/serializable/set.rb +42 -0
- data/lib/mongoid/fields/serializable/string.rb +28 -0
- data/lib/mongoid/fields/serializable/symbol.rb +28 -0
- data/lib/mongoid/fields/serializable/time.rb +12 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +12 -0
- data/lib/mongoid/fields/serializable/timekeeping.rb +102 -0
- data/lib/mongoid/finders.rb +61 -37
- data/lib/mongoid/hierarchy.rb +43 -8
- data/lib/mongoid/identity_map.rb +106 -0
- data/lib/mongoid/indexes.rb +17 -1
- data/lib/mongoid/javascript.rb +2 -3
- data/lib/mongoid/keys.rb +10 -21
- data/lib/mongoid/logger.rb +22 -1
- data/lib/mongoid/matchers/all.rb +10 -0
- data/lib/mongoid/matchers/default.rb +1 -1
- data/lib/mongoid/matchers/exists.rb +10 -0
- data/lib/mongoid/matchers/gt.rb +10 -0
- data/lib/mongoid/matchers/gte.rb +10 -0
- data/lib/mongoid/matchers/in.rb +10 -0
- data/lib/mongoid/matchers/lt.rb +10 -0
- data/lib/mongoid/matchers/lte.rb +10 -0
- data/lib/mongoid/matchers/ne.rb +10 -0
- data/lib/mongoid/matchers/nin.rb +10 -0
- data/lib/mongoid/matchers/or.rb +7 -4
- data/lib/mongoid/matchers/size.rb +10 -0
- data/lib/mongoid/multi_database.rb +26 -6
- data/lib/mongoid/multi_parameter_attributes.rb +40 -17
- data/lib/mongoid/named_scope.rb +1 -2
- data/lib/mongoid/nested_attributes.rb +4 -1
- data/lib/mongoid/observer.rb +108 -5
- data/lib/mongoid/paranoia.rb +26 -26
- data/lib/mongoid/persistence.rb +15 -21
- data/lib/mongoid/persistence/atomic.rb +135 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +11 -8
- data/lib/mongoid/persistence/atomic/bit.rb +37 -0
- data/lib/mongoid/persistence/atomic/inc.rb +9 -6
- data/lib/mongoid/persistence/atomic/operation.rb +48 -7
- data/lib/mongoid/persistence/atomic/pop.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +10 -9
- data/lib/mongoid/persistence/atomic/push.rb +8 -5
- data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
- data/lib/mongoid/persistence/atomic/rename.rb +31 -0
- data/lib/mongoid/persistence/atomic/set.rb +30 -0
- data/lib/mongoid/persistence/atomic/unset.rb +28 -0
- data/lib/mongoid/persistence/deletion.rb +32 -0
- data/lib/mongoid/persistence/insertion.rb +41 -0
- data/lib/mongoid/persistence/modification.rb +37 -0
- data/lib/mongoid/persistence/operations.rb +214 -0
- data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
- data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
- data/lib/mongoid/persistence/operations/insert.rb +34 -0
- data/lib/mongoid/persistence/operations/remove.rb +33 -0
- data/lib/mongoid/persistence/operations/update.rb +53 -0
- data/lib/mongoid/railtie.rb +21 -33
- data/lib/mongoid/railties/database.rake +12 -12
- data/lib/mongoid/relations.rb +9 -5
- data/lib/mongoid/relations/accessors.rb +15 -36
- data/lib/mongoid/relations/auto_save.rb +2 -2
- data/lib/mongoid/relations/binding.rb +28 -1
- data/lib/mongoid/relations/bindings/embedded/in.rb +17 -30
- data/lib/mongoid/relations/bindings/embedded/many.rb +16 -21
- data/lib/mongoid/relations/bindings/embedded/one.rb +11 -16
- data/lib/mongoid/relations/bindings/referenced/in.rb +31 -32
- data/lib/mongoid/relations/bindings/referenced/many.rb +19 -61
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -63
- data/lib/mongoid/relations/bindings/referenced/one.rb +18 -26
- data/lib/mongoid/relations/builder.rb +4 -2
- data/lib/mongoid/relations/builders.rb +21 -2
- data/lib/mongoid/relations/builders/embedded/in.rb +5 -1
- data/lib/mongoid/relations/builders/embedded/many.rb +12 -4
- data/lib/mongoid/relations/builders/embedded/one.rb +5 -1
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +2 -2
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/in.rb +2 -5
- data/lib/mongoid/relations/builders/referenced/many.rb +2 -3
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +14 -5
- data/lib/mongoid/relations/builders/referenced/one.rb +2 -3
- data/lib/mongoid/relations/embedded/atomic.rb +2 -2
- data/lib/mongoid/relations/embedded/in.rb +72 -41
- data/lib/mongoid/relations/embedded/many.rb +116 -120
- data/lib/mongoid/relations/embedded/one.rb +59 -41
- data/lib/mongoid/relations/embedded/sort.rb +31 -0
- data/lib/mongoid/relations/macros.rb +28 -24
- data/lib/mongoid/relations/many.rb +10 -103
- data/lib/mongoid/relations/metadata.rb +335 -38
- data/lib/mongoid/relations/one.rb +7 -32
- data/lib/mongoid/relations/options.rb +47 -0
- data/lib/mongoid/relations/proxy.rb +29 -28
- data/lib/mongoid/relations/referenced/batch.rb +2 -3
- data/lib/mongoid/relations/referenced/in.rb +66 -53
- data/lib/mongoid/relations/referenced/many.rb +216 -143
- data/lib/mongoid/relations/referenced/many_to_many.rb +132 -163
- data/lib/mongoid/relations/referenced/one.rb +76 -58
- data/lib/mongoid/relations/synchronization.rb +113 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +329 -0
- data/lib/mongoid/safety.rb +24 -156
- data/lib/mongoid/serialization.rb +21 -0
- data/lib/mongoid/state.rb +34 -0
- data/lib/mongoid/threaded.rb +175 -0
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/validations.rb +3 -7
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +61 -7
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +1 -1
- data/lib/rails/generators/mongoid/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +1 -1
- data/lib/rails/generators/mongoid/observer/templates/{observer.rb → observer.rb.tt} +0 -0
- data/lib/rails/mongoid.rb +17 -17
- metadata +136 -102
- data/lib/mongoid/atomicity.rb +0 -111
- data/lib/mongoid/collections/cyclic_iterator.rb +0 -34
- data/lib/mongoid/collections/slaves.rb +0 -61
- data/lib/mongoid/extensions/array/conversions.rb +0 -23
- data/lib/mongoid/extensions/array/parentization.rb +0 -13
- data/lib/mongoid/extensions/big_decimal/conversions.rb +0 -19
- data/lib/mongoid/extensions/binary/conversions.rb +0 -17
- data/lib/mongoid/extensions/boolean/conversions.rb +0 -27
- data/lib/mongoid/extensions/date/conversions.rb +0 -25
- data/lib/mongoid/extensions/datetime/conversions.rb +0 -12
- data/lib/mongoid/extensions/float/conversions.rb +0 -20
- data/lib/mongoid/extensions/hash/conversions.rb +0 -19
- data/lib/mongoid/extensions/integer/conversions.rb +0 -20
- data/lib/mongoid/extensions/object/conversions.rb +0 -25
- data/lib/mongoid/extensions/range/conversions.rb +0 -25
- data/lib/mongoid/extensions/set/conversions.rb +0 -20
- data/lib/mongoid/extensions/symbol/conversions.rb +0 -21
- data/lib/mongoid/extensions/time_conversions.rb +0 -38
- data/lib/mongoid/field.rb +0 -162
- data/lib/mongoid/paths.rb +0 -61
- data/lib/mongoid/persistence/command.rb +0 -71
- data/lib/mongoid/persistence/insert.rb +0 -53
- data/lib/mongoid/persistence/insert_embedded.rb +0 -43
- data/lib/mongoid/persistence/remove.rb +0 -44
- data/lib/mongoid/persistence/remove_all.rb +0 -40
- data/lib/mongoid/persistence/remove_embedded.rb +0 -48
- data/lib/mongoid/persistence/update.rb +0 -77
- data/lib/mongoid/safe.rb +0 -23
- data/lib/mongoid/validations/referenced.rb +0 -58
|
@@ -17,7 +17,11 @@ 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
|
-
|
|
20
|
+
if loading
|
|
21
|
+
Mongoid::Factory.from_db(metadata.klass, object)
|
|
22
|
+
else
|
|
23
|
+
Mongoid::Factory.build(metadata.klass, object)
|
|
24
|
+
end
|
|
21
25
|
end
|
|
22
26
|
end
|
|
23
27
|
end
|
|
@@ -114,9 +114,9 @@ module Mongoid # :nodoc:
|
|
|
114
114
|
return if reject?(attrs)
|
|
115
115
|
if id = attrs[:id] || attrs["id"] || attrs["_id"]
|
|
116
116
|
document = existing.find(convert_id(id))
|
|
117
|
-
destroyable?(attrs) ? document
|
|
117
|
+
destroyable?(attrs) ? existing.delete(document) : document.update_attributes(attrs)
|
|
118
118
|
else
|
|
119
|
-
existing.push(metadata.klass
|
|
119
|
+
existing.push(Mongoid::Factory.build(metadata.klass, attrs)) unless destroyable?(attrs)
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
end
|
|
@@ -27,7 +27,7 @@ module Mongoid # :nodoc:
|
|
|
27
27
|
if update?
|
|
28
28
|
existing.attributes = attributes
|
|
29
29
|
elsif replace?
|
|
30
|
-
parent.send(metadata.setter, metadata.klass
|
|
30
|
+
parent.send(metadata.setter, Mongoid::Factory.build(metadata.klass, attributes))
|
|
31
31
|
elsif delete?
|
|
32
32
|
parent.send(metadata.setter, nil)
|
|
33
33
|
end
|
|
@@ -16,11 +16,8 @@ module Mongoid # :nodoc:
|
|
|
16
16
|
# @return [ Document ] A single document.
|
|
17
17
|
def build(type = nil)
|
|
18
18
|
return object unless query?
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
rescue Errors::DocumentNotFound
|
|
22
|
-
return nil
|
|
23
|
-
end
|
|
19
|
+
model = type ? type.constantize : metadata.klass
|
|
20
|
+
IdentityMap.get(model, object) || metadata.criteria(object, model).first
|
|
24
21
|
end
|
|
25
22
|
end
|
|
26
23
|
end
|
|
@@ -17,8 +17,7 @@ module Mongoid # :nodoc:
|
|
|
17
17
|
def build(type = nil)
|
|
18
18
|
return object unless query?
|
|
19
19
|
return [] if object.is_a?(Array)
|
|
20
|
-
|
|
21
|
-
metadata.klass.where(key => convertable(metadata, object))
|
|
20
|
+
metadata.criteria(convertable(metadata, object))
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
private
|
|
@@ -37,7 +36,7 @@ module Mongoid # :nodoc:
|
|
|
37
36
|
if inverse.using_object_ids? || object.is_a?(BSON::ObjectId)
|
|
38
37
|
object
|
|
39
38
|
else
|
|
40
|
-
|
|
39
|
+
Criterion::Unconvertable.new(object)
|
|
41
40
|
end
|
|
42
41
|
end
|
|
43
42
|
end
|
|
@@ -16,11 +16,20 @@ module Mongoid # :nodoc:
|
|
|
16
16
|
# @return [ Array<Document> ] The documents.
|
|
17
17
|
def build(type = nil)
|
|
18
18
|
return object.try(:dup) unless query?
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
metadata.criteria(object)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Do we need to perform a database query? It will be so if the object we
|
|
23
|
+
# have is not a document.
|
|
24
|
+
#
|
|
25
|
+
# @example Should we query the database?
|
|
26
|
+
# builder.query?
|
|
27
|
+
#
|
|
28
|
+
# @return [ true, false ] Whether a database query should happen.
|
|
29
|
+
#
|
|
30
|
+
# @since 2.0.0.rc.1
|
|
31
|
+
def query?
|
|
32
|
+
object.nil? || !object.first.is_a?(Mongoid::Document)
|
|
24
33
|
end
|
|
25
34
|
end
|
|
26
35
|
end
|
|
@@ -16,9 +16,8 @@ module Mongoid # :nodoc:
|
|
|
16
16
|
# @return [ Document ] A single document.
|
|
17
17
|
def build(type = nil)
|
|
18
18
|
return object unless query?
|
|
19
|
-
metadata.
|
|
20
|
-
|
|
21
|
-
)
|
|
19
|
+
criteria = metadata.criteria(object)
|
|
20
|
+
IdentityMap.match(criteria) || criteria.first
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
end
|
|
@@ -53,12 +53,12 @@ module Mongoid #:nodoc:
|
|
|
53
53
|
#
|
|
54
54
|
# @since 2.0.0
|
|
55
55
|
def atomically(modifier, &block)
|
|
56
|
-
updater =
|
|
56
|
+
updater = Threaded.update ||= MODIFIERS[modifier].new
|
|
57
57
|
count_executions do
|
|
58
58
|
block.call if block
|
|
59
59
|
end.tap do
|
|
60
60
|
if @executions.zero?
|
|
61
|
-
|
|
61
|
+
Threaded.update = nil
|
|
62
62
|
updater.execute(collection)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -8,28 +8,6 @@ module Mongoid # :nodoc:
|
|
|
8
8
|
# multiple documents.
|
|
9
9
|
class In < Relations::One
|
|
10
10
|
|
|
11
|
-
# Binds the base object to the inverse of the relation. This is so we
|
|
12
|
-
# are referenced to the actual objects themselves and dont hit the
|
|
13
|
-
# database twice when setting the relations up.
|
|
14
|
-
#
|
|
15
|
-
# This is called after first creating the relation, or if a new object
|
|
16
|
-
# is set on the relation.
|
|
17
|
-
#
|
|
18
|
-
# @example Bind the relation.
|
|
19
|
-
# name.person.bind(:continue => true)
|
|
20
|
-
#
|
|
21
|
-
# @param [ Hash ] options The options to bind with.
|
|
22
|
-
#
|
|
23
|
-
# @option options [ true, false ] :binding Are we in build mode?
|
|
24
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
25
|
-
# inverse?
|
|
26
|
-
#
|
|
27
|
-
# @since 2.0.0.rc.1
|
|
28
|
-
def bind(options = {})
|
|
29
|
-
binding.bind(options)
|
|
30
|
-
base.save if target.persisted? && !options[:binding]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
11
|
# Instantiate a new embedded_in relation.
|
|
34
12
|
#
|
|
35
13
|
# @example Create the new relation.
|
|
@@ -43,29 +21,32 @@ module Mongoid # :nodoc:
|
|
|
43
21
|
def initialize(base, target, metadata)
|
|
44
22
|
init(base, target, metadata) do
|
|
45
23
|
characterize_one(target)
|
|
46
|
-
|
|
24
|
+
bind_one
|
|
25
|
+
base.save if persistable?
|
|
47
26
|
end
|
|
48
27
|
end
|
|
49
28
|
|
|
50
|
-
#
|
|
51
|
-
#
|
|
29
|
+
# Substitutes the supplied target documents for the existing document
|
|
30
|
+
# in the relation.
|
|
52
31
|
#
|
|
53
|
-
#
|
|
32
|
+
# @example Substitute the new document.
|
|
33
|
+
# person.name.substitute(new_name)
|
|
54
34
|
#
|
|
55
|
-
# @
|
|
56
|
-
# name.person.unbind(:continue => false)
|
|
35
|
+
# @param [ Document ] other A document to replace the target.
|
|
57
36
|
#
|
|
58
|
-
# @
|
|
59
|
-
# @param [ Hash ] options The options to bind with.
|
|
60
|
-
#
|
|
61
|
-
# @option options [ true, false ] :binding Are we in build mode?
|
|
62
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
63
|
-
# inverse?
|
|
37
|
+
# @return [ Document, nil ] The relation or nil.
|
|
64
38
|
#
|
|
65
39
|
# @since 2.0.0.rc.1
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
|
|
40
|
+
def substitute(replacement)
|
|
41
|
+
tap do |proxy|
|
|
42
|
+
proxy.unbind_one
|
|
43
|
+
unless replacement
|
|
44
|
+
base.delete unless binding?
|
|
45
|
+
return nil
|
|
46
|
+
end
|
|
47
|
+
proxy.target = replacement
|
|
48
|
+
proxy.bind_one
|
|
49
|
+
end
|
|
69
50
|
end
|
|
70
51
|
|
|
71
52
|
private
|
|
@@ -80,8 +61,32 @@ module Mongoid # :nodoc:
|
|
|
80
61
|
# @return [ Binding ] A binding object.
|
|
81
62
|
#
|
|
82
63
|
# @since 2.0.0.rc.1
|
|
83
|
-
def binding
|
|
84
|
-
Bindings::Embedded::In.new(base,
|
|
64
|
+
def binding
|
|
65
|
+
Bindings::Embedded::In.new(base, target, metadata)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Characterize the document.
|
|
69
|
+
#
|
|
70
|
+
# @example Set the base metadata.
|
|
71
|
+
# relation.characterize_one(document)
|
|
72
|
+
#
|
|
73
|
+
# @param [ Document ] document The document to set the metadata on.
|
|
74
|
+
#
|
|
75
|
+
# @since 2.1.0
|
|
76
|
+
def characterize_one(document)
|
|
77
|
+
base.metadata = metadata.inverse_metadata(document)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Are we able to persist this relation?
|
|
81
|
+
#
|
|
82
|
+
# @example Can we persist the relation?
|
|
83
|
+
# relation.persistable?
|
|
84
|
+
#
|
|
85
|
+
# @return [ true, false ] If the relation is persistable.
|
|
86
|
+
#
|
|
87
|
+
# @since 2.1.0
|
|
88
|
+
def persistable?
|
|
89
|
+
target.persisted? && !binding? && !building?
|
|
85
90
|
end
|
|
86
91
|
|
|
87
92
|
class << self
|
|
@@ -98,8 +103,8 @@ module Mongoid # :nodoc:
|
|
|
98
103
|
# @return [ Builder ] A newly instantiated builder object.
|
|
99
104
|
#
|
|
100
105
|
# @since 2.0.0.rc.1
|
|
101
|
-
def builder(meta, object)
|
|
102
|
-
Builders::Embedded::In.new(meta, object)
|
|
106
|
+
def builder(meta, object, loading = false)
|
|
107
|
+
Builders::Embedded::In.new(meta, object, loading)
|
|
103
108
|
end
|
|
104
109
|
|
|
105
110
|
# Returns true if the relation is an embedded one. In this case
|
|
@@ -154,6 +159,20 @@ module Mongoid # :nodoc:
|
|
|
154
159
|
Builders::NestedAttributes::One.new(metadata, attributes, options)
|
|
155
160
|
end
|
|
156
161
|
|
|
162
|
+
# Get the path calculator for the supplied document.
|
|
163
|
+
#
|
|
164
|
+
# @example Get the path calculator.
|
|
165
|
+
# Proxy.path(document)
|
|
166
|
+
#
|
|
167
|
+
# @param [ Document ] document The document to calculate on.
|
|
168
|
+
#
|
|
169
|
+
# @return [ Root ] The root atomic path calculator.
|
|
170
|
+
#
|
|
171
|
+
# @since 2.1.0
|
|
172
|
+
def path(document)
|
|
173
|
+
Mongoid::Atomic::Paths::Root.new(document)
|
|
174
|
+
end
|
|
175
|
+
|
|
157
176
|
# Tells the caller if this relation is one that stores the foreign
|
|
158
177
|
# key on its own objects.
|
|
159
178
|
#
|
|
@@ -166,6 +185,18 @@ module Mongoid # :nodoc:
|
|
|
166
185
|
def stores_foreign_key?
|
|
167
186
|
false
|
|
168
187
|
end
|
|
188
|
+
|
|
189
|
+
# Get the valid options allowed with this relation.
|
|
190
|
+
#
|
|
191
|
+
# @example Get the valid options.
|
|
192
|
+
# Relation.valid_options
|
|
193
|
+
#
|
|
194
|
+
# @return [ Array<Symbol> ] The valid options.
|
|
195
|
+
#
|
|
196
|
+
# @since 2.1.0
|
|
197
|
+
def valid_options
|
|
198
|
+
[ :cyclic, :polymorphic ]
|
|
199
|
+
end
|
|
169
200
|
end
|
|
170
201
|
end
|
|
171
202
|
end
|
|
@@ -22,55 +22,35 @@ module Mongoid # :nodoc:
|
|
|
22
22
|
#
|
|
23
23
|
# @param [ Document, Array<Document> ] *args Any number of documents.
|
|
24
24
|
def <<(*args)
|
|
25
|
-
options = default_options(args)
|
|
26
25
|
atomically(:$pushAll) do
|
|
27
26
|
args.flatten.each do |doc|
|
|
28
|
-
|
|
29
|
-
append(doc
|
|
30
|
-
doc.save if
|
|
27
|
+
next unless doc
|
|
28
|
+
append(doc)
|
|
29
|
+
doc.save if persistable?
|
|
31
30
|
end
|
|
32
31
|
end
|
|
33
32
|
end
|
|
33
|
+
alias :concat :<<
|
|
34
|
+
alias :push :<<
|
|
34
35
|
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# database twice when setting the relations up.
|
|
36
|
+
# Builds a new document in the relation and appends it to the target.
|
|
37
|
+
# Takes an optional type if you want to specify a subclass.
|
|
38
38
|
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
39
|
+
# @example Build a new document on the relation.
|
|
40
|
+
# person.people.build(:name => "Bozo")
|
|
41
41
|
#
|
|
42
|
-
# @
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# @
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
# @since 2.0.0.rc.1
|
|
52
|
-
def bind(options = {})
|
|
53
|
-
binding.bind(options)
|
|
54
|
-
if base.persisted? && !options[:binding]
|
|
55
|
-
atomically(:$set) { target.each(&:save) }
|
|
42
|
+
# @param [ Hash ] attributes The attributes to build the document with.
|
|
43
|
+
# @param [ Class ] type Optional class to build the document with.
|
|
44
|
+
#
|
|
45
|
+
# @return [ Document ] The new document.
|
|
46
|
+
def build(attributes = {}, type = nil)
|
|
47
|
+
Factory.build(type || metadata.klass, attributes).tap do |doc|
|
|
48
|
+
doc.identify
|
|
49
|
+
append(doc)
|
|
50
|
+
yield(doc) if block_given?
|
|
56
51
|
end
|
|
57
52
|
end
|
|
58
|
-
|
|
59
|
-
# Bind the inverse relation between a single document in this proxy
|
|
60
|
-
# instead of the entire target.
|
|
61
|
-
#
|
|
62
|
-
# Used when appending to the target instead of setting the entire
|
|
63
|
-
# thing.
|
|
64
|
-
#
|
|
65
|
-
# @example Bind a single document.
|
|
66
|
-
# person.addressses.bind_one(address)
|
|
67
|
-
#
|
|
68
|
-
# @param [ Document ] document The document to bind.
|
|
69
|
-
#
|
|
70
|
-
# @since 2.0.0.rc.1
|
|
71
|
-
def bind_one(document, options = {})
|
|
72
|
-
binding.bind_one(document, options)
|
|
73
|
-
end
|
|
53
|
+
alias :new :build
|
|
74
54
|
|
|
75
55
|
# Clear the relation. Will delete the documents from the db if they are
|
|
76
56
|
# already persisted.
|
|
@@ -80,7 +60,9 @@ module Mongoid # :nodoc:
|
|
|
80
60
|
#
|
|
81
61
|
# @return [ Many ] The empty relation.
|
|
82
62
|
def clear
|
|
83
|
-
|
|
63
|
+
tap do |proxy|
|
|
64
|
+
atomically(:$unset) { proxy.delete_all }
|
|
65
|
+
end
|
|
84
66
|
end
|
|
85
67
|
|
|
86
68
|
# Returns a count of the number of documents in the association that have
|
|
@@ -94,7 +76,7 @@ module Mongoid # :nodoc:
|
|
|
94
76
|
# @return [ Integer ] The total number of persisted embedded docs, as
|
|
95
77
|
# flagged by the #persisted? method.
|
|
96
78
|
def count
|
|
97
|
-
target.select
|
|
79
|
+
target.select { |doc| doc.persisted? }.size
|
|
98
80
|
end
|
|
99
81
|
|
|
100
82
|
# Create a new document in the relation. This is essentially the same
|
|
@@ -108,7 +90,7 @@ module Mongoid # :nodoc:
|
|
|
108
90
|
#
|
|
109
91
|
# @return [ Document ] The newly created document.
|
|
110
92
|
def create(attributes = {}, type = nil, &block)
|
|
111
|
-
build(attributes, type, &block).tap
|
|
93
|
+
build(attributes, type, &block).tap { |doc| doc.save }
|
|
112
94
|
end
|
|
113
95
|
|
|
114
96
|
# Create a new document in the relation. This is essentially the same
|
|
@@ -125,7 +107,7 @@ module Mongoid # :nodoc:
|
|
|
125
107
|
#
|
|
126
108
|
# @return [ Document ] The newly created document.
|
|
127
109
|
def create!(attributes = {}, type = nil, &block)
|
|
128
|
-
build(attributes, type, &block).tap
|
|
110
|
+
build(attributes, type, &block).tap { |doc| doc.save! }
|
|
129
111
|
end
|
|
130
112
|
|
|
131
113
|
# Delete the supplied document from the target. This method is proxied
|
|
@@ -140,7 +122,10 @@ module Mongoid # :nodoc:
|
|
|
140
122
|
#
|
|
141
123
|
# @since 2.0.0.rc.1
|
|
142
124
|
def delete(document)
|
|
143
|
-
target.
|
|
125
|
+
target.delete_one(document).tap do |doc|
|
|
126
|
+
unbind_one(doc) if doc && !binding?
|
|
127
|
+
reindex
|
|
128
|
+
end
|
|
144
129
|
end
|
|
145
130
|
|
|
146
131
|
# Delete all the documents in the association without running callbacks.
|
|
@@ -207,29 +192,22 @@ module Mongoid # :nodoc:
|
|
|
207
192
|
def initialize(base, target, metadata)
|
|
208
193
|
init(base, target, metadata) do
|
|
209
194
|
target.each_with_index do |doc, index|
|
|
210
|
-
|
|
211
|
-
doc.parentize(base)
|
|
195
|
+
integrate(doc)
|
|
212
196
|
doc._index = index
|
|
213
197
|
end
|
|
214
198
|
end
|
|
215
199
|
end
|
|
216
200
|
|
|
217
|
-
#
|
|
218
|
-
# loaded.
|
|
201
|
+
# Get all the documents in the relation that are loaded into memory.
|
|
219
202
|
#
|
|
220
|
-
# @example
|
|
221
|
-
# relation.
|
|
203
|
+
# @example Get the in memory documents.
|
|
204
|
+
# relation.in_memory
|
|
222
205
|
#
|
|
223
|
-
# @return [
|
|
206
|
+
# @return [ Array<Document> ] The documents in memory.
|
|
224
207
|
#
|
|
225
|
-
# @since 2.
|
|
226
|
-
def
|
|
227
|
-
|
|
228
|
-
unless relation.loaded?
|
|
229
|
-
relation.bind(options)
|
|
230
|
-
relation.loaded = true
|
|
231
|
-
end
|
|
232
|
-
end
|
|
208
|
+
# @since 2.1.0
|
|
209
|
+
def in_memory
|
|
210
|
+
target
|
|
233
211
|
end
|
|
234
212
|
|
|
235
213
|
# Substitutes the supplied target documents for the existing documents
|
|
@@ -244,14 +222,19 @@ module Mongoid # :nodoc:
|
|
|
244
222
|
# @return [ Many ] The proxied relation.
|
|
245
223
|
#
|
|
246
224
|
# @since 2.0.0.rc.1
|
|
247
|
-
def substitute(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if !new_target.blank?
|
|
252
|
-
atomically(:$set) { rebind(old_target, options) }
|
|
225
|
+
def substitute(replacement)
|
|
226
|
+
tap do |proxy|
|
|
227
|
+
if replacement.blank?
|
|
228
|
+
proxy.clear
|
|
253
229
|
else
|
|
254
|
-
atomically(:$
|
|
230
|
+
atomically(:$set) do
|
|
231
|
+
proxy.target = replacement
|
|
232
|
+
proxy.target.each_with_index do |doc, index|
|
|
233
|
+
integrate(doc)
|
|
234
|
+
doc._index = index
|
|
235
|
+
doc.save if base.persisted?
|
|
236
|
+
end
|
|
237
|
+
end
|
|
255
238
|
end
|
|
256
239
|
end
|
|
257
240
|
end
|
|
@@ -265,32 +248,9 @@ module Mongoid # :nodoc:
|
|
|
265
248
|
#
|
|
266
249
|
# @since 2.0.0.rc.1
|
|
267
250
|
def as_document
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
# Unbind the inverse relation from this set of documents. Used when the
|
|
276
|
-
# entire proxy has been cleared, set to nil or empty, or replaced.
|
|
277
|
-
#
|
|
278
|
-
# @example Unbind the relation.
|
|
279
|
-
# person.addresses.unbind(target, :continue => false)
|
|
280
|
-
#
|
|
281
|
-
# @param [ Array<Document> ] old_target The relations previous target.
|
|
282
|
-
# @param [ Hash ] options The options to bind with.
|
|
283
|
-
#
|
|
284
|
-
# @option options [ true, false ] :binding Are we in build mode?
|
|
285
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
286
|
-
# inverse?
|
|
287
|
-
#
|
|
288
|
-
# @since 2.0.0.rc.1
|
|
289
|
-
def unbind(old_target, options = {})
|
|
290
|
-
binding(old_target).unbind(options)
|
|
291
|
-
if base.persisted?
|
|
292
|
-
old_target.each do |doc|
|
|
293
|
-
doc.delete unless doc.destroyed?
|
|
251
|
+
[].tap do |attributes|
|
|
252
|
+
target.each do |doc|
|
|
253
|
+
attributes << doc.as_document
|
|
294
254
|
end
|
|
295
255
|
end
|
|
296
256
|
end
|
|
@@ -306,10 +266,9 @@ module Mongoid # :nodoc:
|
|
|
306
266
|
# @param [ Document ] document The document to append to the target.
|
|
307
267
|
#
|
|
308
268
|
# @since 2.0.0.rc.1
|
|
309
|
-
def append(document
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
bind_one(document, options)
|
|
269
|
+
def append(document)
|
|
270
|
+
target.push(document)
|
|
271
|
+
integrate(document)
|
|
313
272
|
document._index = target.size - 1
|
|
314
273
|
end
|
|
315
274
|
|
|
@@ -323,8 +282,8 @@ module Mongoid # :nodoc:
|
|
|
323
282
|
# @return [ Binding ] The many binding.
|
|
324
283
|
#
|
|
325
284
|
# @since 2.0.0.rc.1
|
|
326
|
-
def binding
|
|
327
|
-
Bindings::Embedded::Many.new(base,
|
|
285
|
+
def binding
|
|
286
|
+
Bindings::Embedded::Many.new(base, target, metadata)
|
|
328
287
|
end
|
|
329
288
|
|
|
330
289
|
# Returns the criteria object for the target class with its documents set
|
|
@@ -335,11 +294,25 @@ module Mongoid # :nodoc:
|
|
|
335
294
|
#
|
|
336
295
|
# @return [ Criteria ] A new criteria.
|
|
337
296
|
def criteria
|
|
338
|
-
|
|
297
|
+
klass.criteria(true).tap do |criterion|
|
|
339
298
|
criterion.documents = target
|
|
340
299
|
end
|
|
341
300
|
end
|
|
342
301
|
|
|
302
|
+
# Integrate the document into the relation. will set its metadata and
|
|
303
|
+
# attempt to bind the inverse.
|
|
304
|
+
#
|
|
305
|
+
# @example Integrate the document.
|
|
306
|
+
# relation.integrate(document)
|
|
307
|
+
#
|
|
308
|
+
# @param [ Document ] document The document to integrate.
|
|
309
|
+
#
|
|
310
|
+
# @since 2.1.0
|
|
311
|
+
def integrate(document)
|
|
312
|
+
characterize_one(document)
|
|
313
|
+
bind_one(document)
|
|
314
|
+
end
|
|
315
|
+
|
|
343
316
|
# If the target array does not respond to the supplied method then try to
|
|
344
317
|
# find a named scope or criteria on the class and send the call there.
|
|
345
318
|
#
|
|
@@ -351,13 +324,24 @@ module Mongoid # :nodoc:
|
|
|
351
324
|
#
|
|
352
325
|
# @return [ Criteria, Object ] A Criteria or return value from the target.
|
|
353
326
|
def method_missing(name, *args, &block)
|
|
354
|
-
|
|
355
|
-
klass = metadata.klass
|
|
327
|
+
return super if target.respond_to?(name)
|
|
356
328
|
klass.send(:with_scope, criteria) do
|
|
357
329
|
criteria.send(name, *args, &block)
|
|
358
330
|
end
|
|
359
331
|
end
|
|
360
332
|
|
|
333
|
+
# Are we able to persist this relation?
|
|
334
|
+
#
|
|
335
|
+
# @example Can we persist the relation?
|
|
336
|
+
# relation.persistable?
|
|
337
|
+
#
|
|
338
|
+
# @return [ true, false ] If the relation is persistable.
|
|
339
|
+
#
|
|
340
|
+
# @since 2.1.0
|
|
341
|
+
def persistable?
|
|
342
|
+
base.persisted? && !binding?
|
|
343
|
+
end
|
|
344
|
+
|
|
361
345
|
# Reindex all the target elements. This is useful when performing
|
|
362
346
|
# operations on the proxied target directly and the indices need to
|
|
363
347
|
# match that on the database side.
|
|
@@ -386,29 +370,14 @@ module Mongoid # :nodoc:
|
|
|
386
370
|
criteria = find(:all, conditions || {})
|
|
387
371
|
criteria.size.tap do
|
|
388
372
|
criteria.each do |doc|
|
|
389
|
-
target.
|
|
373
|
+
target.delete_one(doc)
|
|
374
|
+
unbind_one(doc)
|
|
390
375
|
doc.send(method, :suppress => true)
|
|
391
376
|
end
|
|
392
377
|
reindex
|
|
393
378
|
end
|
|
394
379
|
end
|
|
395
380
|
|
|
396
|
-
# Convenience method to clean up the substitute code. Unbinds the old
|
|
397
|
-
# target and reindexes.
|
|
398
|
-
#
|
|
399
|
-
# @example Rebind the relation.
|
|
400
|
-
# relation.rebind([])
|
|
401
|
-
#
|
|
402
|
-
# @param [ Array<Document> ] old_target The old target.
|
|
403
|
-
# @param [ Hash ] options The options passed to substitute.
|
|
404
|
-
#
|
|
405
|
-
# @since 2.0.0
|
|
406
|
-
def rebind(old_target, options)
|
|
407
|
-
reindex
|
|
408
|
-
unbind(old_target, options)
|
|
409
|
-
bind(options)
|
|
410
|
-
end
|
|
411
|
-
|
|
412
381
|
class << self
|
|
413
382
|
|
|
414
383
|
# Return the builder that is responsible for generating the documents
|
|
@@ -424,8 +393,8 @@ module Mongoid # :nodoc:
|
|
|
424
393
|
# @return [ Builder ] A newly instantiated builder object.
|
|
425
394
|
#
|
|
426
395
|
# @since 2.0.0.rc.1
|
|
427
|
-
def builder(meta, object)
|
|
428
|
-
Builders::Embedded::Many.new(meta, object)
|
|
396
|
+
def builder(meta, object, loading = false)
|
|
397
|
+
Builders::Embedded::Many.new(meta, object, loading)
|
|
429
398
|
end
|
|
430
399
|
|
|
431
400
|
# Returns true if the relation is an embedded one. In this case
|
|
@@ -480,6 +449,21 @@ module Mongoid # :nodoc:
|
|
|
480
449
|
Builders::NestedAttributes::Many.new(metadata, attributes, options)
|
|
481
450
|
end
|
|
482
451
|
|
|
452
|
+
# Get the path calculator for the supplied document.
|
|
453
|
+
#
|
|
454
|
+
# @example Get the path calculator.
|
|
455
|
+
# Proxy.path(document)
|
|
456
|
+
#
|
|
457
|
+
# @param [ Document ] document The document to calculate on.
|
|
458
|
+
#
|
|
459
|
+
# @return [ Mongoid::Atomic::Paths::Embedded::Many ]
|
|
460
|
+
# The embedded many atomic path calculator.
|
|
461
|
+
#
|
|
462
|
+
# @since 2.1.0
|
|
463
|
+
def path(document)
|
|
464
|
+
Mongoid::Atomic::Paths::Embedded::Many.new(document)
|
|
465
|
+
end
|
|
466
|
+
|
|
483
467
|
# Tells the caller if this relation is one that stores the foreign
|
|
484
468
|
# key on its own objects.
|
|
485
469
|
#
|
|
@@ -492,6 +476,18 @@ module Mongoid # :nodoc:
|
|
|
492
476
|
def stores_foreign_key?
|
|
493
477
|
false
|
|
494
478
|
end
|
|
479
|
+
|
|
480
|
+
# Get the valid options allowed with this relation.
|
|
481
|
+
#
|
|
482
|
+
# @example Get the valid options.
|
|
483
|
+
# Relation.valid_options
|
|
484
|
+
#
|
|
485
|
+
# @return [ Array<Symbol> ] The valid options.
|
|
486
|
+
#
|
|
487
|
+
# @since 2.1.0
|
|
488
|
+
def valid_options
|
|
489
|
+
[ :as, :cyclic, :order, :versioned ]
|
|
490
|
+
end
|
|
495
491
|
end
|
|
496
492
|
end
|
|
497
493
|
end
|