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
|
@@ -5,46 +5,65 @@ module Mongoid # :nodoc:
|
|
|
5
5
|
|
|
6
6
|
# This class defines the behaviour for all relations that are a
|
|
7
7
|
# many-to-many between documents in different collections.
|
|
8
|
-
class ManyToMany <
|
|
8
|
+
class ManyToMany < Many
|
|
9
9
|
|
|
10
10
|
# Appends a document or array of documents to the relation. Will set
|
|
11
11
|
# the parent and update the index in the process.
|
|
12
12
|
#
|
|
13
13
|
# @example Append a document.
|
|
14
|
-
# person.
|
|
14
|
+
# person.posts << post
|
|
15
15
|
#
|
|
16
16
|
# @example Push a document.
|
|
17
|
-
# person.
|
|
17
|
+
# person.posts.push(post)
|
|
18
18
|
#
|
|
19
19
|
# @example Concat with other documents.
|
|
20
|
-
# person.
|
|
20
|
+
# person.posts.concat([ post_one, post_two ])
|
|
21
21
|
#
|
|
22
22
|
# @param [ Document, Array<Document> ] *args Any number of documents.
|
|
23
|
+
#
|
|
24
|
+
# @return [ Array<Document> ] The loaded docs.
|
|
25
|
+
#
|
|
26
|
+
# @since 2.0.0.beta.1
|
|
23
27
|
def <<(*args)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
batched do
|
|
29
|
+
[].tap do |ids|
|
|
30
|
+
args.flatten.each do |doc|
|
|
31
|
+
next unless doc
|
|
32
|
+
append(doc)
|
|
33
|
+
if persistable?
|
|
34
|
+
ids.push(doc.id)
|
|
35
|
+
doc.save
|
|
36
|
+
else
|
|
37
|
+
base.send(metadata.foreign_key).push(doc.id)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
if persistable?
|
|
41
|
+
base.push_all(metadata.foreign_key, ids)
|
|
42
|
+
base.synced[metadata.foreign_key] = false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
30
45
|
end
|
|
31
46
|
end
|
|
32
47
|
alias :concat :<<
|
|
33
48
|
alias :push :<<
|
|
34
49
|
|
|
35
|
-
#
|
|
36
|
-
#
|
|
50
|
+
# Build a new document from the attributes and append it to this
|
|
51
|
+
# relation without saving.
|
|
37
52
|
#
|
|
38
53
|
# @example Build a new document on the relation.
|
|
39
|
-
# person.
|
|
54
|
+
# person.posts.build(:title => "A new post")
|
|
40
55
|
#
|
|
41
|
-
# @param [ Hash ] attributes The attributes
|
|
42
|
-
# @param [ Class ] type
|
|
56
|
+
# @param [ Hash ] attributes The attributes of the new document.
|
|
57
|
+
# @param [ Class ] type The optional subclass to build.
|
|
43
58
|
#
|
|
44
59
|
# @return [ Document ] The new document.
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
#
|
|
61
|
+
# @since 2.0.0.beta.1
|
|
62
|
+
def build(attributes = {}, type = nil)
|
|
63
|
+
Factory.build(type || klass, attributes).tap do |doc|
|
|
47
64
|
base.send(metadata.foreign_key).push(doc.id)
|
|
65
|
+
append(doc)
|
|
66
|
+
yield(doc) if block_given?
|
|
48
67
|
end
|
|
49
68
|
end
|
|
50
69
|
alias :new :build
|
|
@@ -53,16 +72,19 @@ module Mongoid # :nodoc:
|
|
|
53
72
|
# save the document if the parent has been persisted.
|
|
54
73
|
#
|
|
55
74
|
# @example Create and save the new document.
|
|
56
|
-
# person.
|
|
75
|
+
# person.posts.create(:text => "Testing")
|
|
57
76
|
#
|
|
58
77
|
# @param [ Hash ] attributes The attributes to create with.
|
|
59
78
|
# @param [ Class ] type The optional type of document to create.
|
|
60
79
|
#
|
|
61
80
|
# @return [ Document ] The newly created document.
|
|
81
|
+
#
|
|
82
|
+
# @since 2.0.0.beta.1
|
|
62
83
|
def create(attributes = nil, type = nil, &block)
|
|
63
|
-
|
|
64
|
-
base.
|
|
65
|
-
|
|
84
|
+
super.tap do |doc|
|
|
85
|
+
base.send(metadata.foreign_key).delete_one(doc.id)
|
|
86
|
+
base.push(metadata.foreign_key, doc.id)
|
|
87
|
+
base.synced[metadata.foreign_key] = false
|
|
66
88
|
end
|
|
67
89
|
end
|
|
68
90
|
|
|
@@ -71,7 +93,7 @@ module Mongoid # :nodoc:
|
|
|
71
93
|
# error if validation fails.
|
|
72
94
|
#
|
|
73
95
|
# @example Create and save the new document.
|
|
74
|
-
# person.
|
|
96
|
+
# person.posts.create!(:text => "Testing")
|
|
75
97
|
#
|
|
76
98
|
# @param [ Hash ] attributes The attributes to create with.
|
|
77
99
|
# @param [ Class ] type The optional type of document to create.
|
|
@@ -79,72 +101,63 @@ module Mongoid # :nodoc:
|
|
|
79
101
|
# @raise [ Errors::Validations ] If validation failed.
|
|
80
102
|
#
|
|
81
103
|
# @return [ Document ] The newly created document.
|
|
82
|
-
def create!(attributes = nil, type = nil, &block)
|
|
83
|
-
build(attributes, type, &block).tap do |doc|
|
|
84
|
-
base.add_to_set(metadata.foreign_key, doc.id)
|
|
85
|
-
doc.save! if base.persisted?
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Delete a single document from the relation.
|
|
90
|
-
#
|
|
91
|
-
# @example Delete a document.
|
|
92
|
-
# person.preferences.delete(preference)
|
|
93
|
-
#
|
|
94
|
-
# @param [ Document ] document The document to delete.
|
|
95
104
|
#
|
|
96
|
-
# @since 2.0.0.
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
# @since 2.0.0.beta.1
|
|
106
|
+
def create!(attributes = nil, type = nil, &block)
|
|
107
|
+
super.tap do |doc|
|
|
108
|
+
base.send(metadata.foreign_key).delete_one(doc.id)
|
|
109
|
+
base.push(metadata.foreign_key, doc.id)
|
|
110
|
+
base.synced[metadata.foreign_key] = false
|
|
100
111
|
end
|
|
101
112
|
end
|
|
102
113
|
|
|
103
|
-
#
|
|
104
|
-
#
|
|
114
|
+
# Delete the document from the relation. This will set the foreign key
|
|
115
|
+
# on the document to nil. If the dependent options on the relation are
|
|
116
|
+
# :delete or :destroy the appropriate removal will occur.
|
|
105
117
|
#
|
|
106
|
-
# @example Delete
|
|
107
|
-
# person.
|
|
118
|
+
# @example Delete the document.
|
|
119
|
+
# person.posts.delete(post)
|
|
108
120
|
#
|
|
109
|
-
# @
|
|
110
|
-
# person.preferences.delete_all(:conditions => { :title => "Testing" })
|
|
121
|
+
# @param [ Document ] document The document to remove.
|
|
111
122
|
#
|
|
112
|
-
# @
|
|
123
|
+
# @return [ Document ] The matching document.
|
|
113
124
|
#
|
|
114
|
-
# @
|
|
115
|
-
def
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# @example Destroy all documents in the relation.
|
|
123
|
-
# person.preferences.destroy_all
|
|
124
|
-
#
|
|
125
|
-
# @example Conditonally destroy all documents in the relation.
|
|
126
|
-
# person.preferences.destroy_all(:conditions => { :title => "Testing" })
|
|
127
|
-
#
|
|
128
|
-
# @param [ Hash ] conditions Optional conditions to destroy with.
|
|
129
|
-
#
|
|
130
|
-
# @return [ Integer ] The number of documents destroyd.
|
|
131
|
-
def destroy_all(conditions = nil)
|
|
132
|
-
remove_all(conditions, :destroy_all)
|
|
125
|
+
# @since 2.1.0
|
|
126
|
+
def delete(document)
|
|
127
|
+
super.tap do |doc|
|
|
128
|
+
if doc && persistable?
|
|
129
|
+
base.pull(metadata.foreign_key, doc.id)
|
|
130
|
+
base.synced[metadata.foreign_key] = false
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
# Instantiate a new references_many relation. Will set the foreign key
|
|
136
136
|
# and the base on the inverse object.
|
|
137
137
|
#
|
|
138
138
|
# @example Create the new relation.
|
|
139
|
-
# Referenced::
|
|
139
|
+
# Referenced::Many.new(base, target, metadata)
|
|
140
140
|
#
|
|
141
141
|
# @param [ Document ] base The document this relation hangs off of.
|
|
142
142
|
# @param [ Array<Document> ] target The target of the relation.
|
|
143
143
|
# @param [ Metadata ] metadata The relation's metadata.
|
|
144
|
+
#
|
|
145
|
+
# @since 2.0.0.beta.1
|
|
144
146
|
def initialize(base, target, metadata)
|
|
145
|
-
init(base, target, metadata) do
|
|
146
|
-
|
|
147
|
-
|
|
147
|
+
init(base, Targets::Enumerable.new(target), metadata) do |proxy|
|
|
148
|
+
raise_mixed if klass.embedded?
|
|
149
|
+
batched do
|
|
150
|
+
proxy.in_memory do |doc|
|
|
151
|
+
characterize_one(doc)
|
|
152
|
+
bind_one(doc)
|
|
153
|
+
if persistable?
|
|
154
|
+
base.push(metadata.foreign_key, doc.id)
|
|
155
|
+
base.synced[metadata.foreign_key] = false
|
|
156
|
+
doc.save
|
|
157
|
+
else
|
|
158
|
+
base.send(metadata.foreign_key).push(doc.id)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
148
161
|
end
|
|
149
162
|
end
|
|
150
163
|
end
|
|
@@ -158,79 +171,42 @@ module Mongoid # :nodoc:
|
|
|
158
171
|
#
|
|
159
172
|
# @since 2.0.0.rc.1
|
|
160
173
|
def nullify
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
174
|
+
# @todo: Durran: This is wrong.
|
|
175
|
+
criteria.update(metadata.inverse_foreign_key => [])
|
|
176
|
+
# We need to update the inverse as well.
|
|
177
|
+
target.clear do |doc|
|
|
178
|
+
unbind_one(doc)
|
|
164
179
|
end
|
|
165
|
-
target.clear
|
|
166
180
|
end
|
|
167
181
|
alias :nullify_all :nullify
|
|
168
182
|
|
|
169
|
-
|
|
170
|
-
# in the relation. If the new target is nil, perform the necessary
|
|
171
|
-
# deletion.
|
|
172
|
-
#
|
|
173
|
-
# @example Replace the relation.
|
|
174
|
-
# person.posts.substitute(new_name)
|
|
175
|
-
#
|
|
176
|
-
# @param [ Array<Document> ] target The replacement target.
|
|
177
|
-
# @param [ Hash ] options The options to bind with.
|
|
178
|
-
#
|
|
179
|
-
# @option options [ true, false ] :binding Are we in build mode?
|
|
180
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
181
|
-
# inverse?
|
|
182
|
-
#
|
|
183
|
-
# @return [ Many ] The relation.
|
|
184
|
-
#
|
|
185
|
-
# @since 2.0.0.rc.1
|
|
186
|
-
def substitute(new_target, options = {})
|
|
187
|
-
tap do |relation|
|
|
188
|
-
if new_target
|
|
189
|
-
binding.unbind(options)
|
|
190
|
-
relation.target = new_target.to_a
|
|
191
|
-
base.send(metadata.foreign_key_setter, new_target.map(&:id))
|
|
192
|
-
bind(options)
|
|
193
|
-
else
|
|
194
|
-
relation.target = unbind(options)
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
end
|
|
183
|
+
private
|
|
198
184
|
|
|
199
|
-
#
|
|
200
|
-
#
|
|
201
|
-
#
|
|
202
|
-
# Will delete the object if necessary.
|
|
203
|
-
#
|
|
204
|
-
# @example Unbind the target.
|
|
205
|
-
# person.posts.unbind
|
|
185
|
+
# Appends the document to the target array, updating the index on the
|
|
186
|
+
# document at the same time.
|
|
206
187
|
#
|
|
207
|
-
# @
|
|
188
|
+
# @example Append the document to the relation.
|
|
189
|
+
# relation.append(document)
|
|
208
190
|
#
|
|
209
|
-
# @
|
|
210
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
211
|
-
# inverse?
|
|
191
|
+
# @param [ Document ] document The document to append to the target.
|
|
212
192
|
#
|
|
213
193
|
# @since 2.0.0.rc.1
|
|
214
|
-
def
|
|
215
|
-
target.
|
|
216
|
-
|
|
217
|
-
|
|
194
|
+
def append(document)
|
|
195
|
+
target.push(document)
|
|
196
|
+
characterize_one(document)
|
|
197
|
+
bind_one(document)
|
|
218
198
|
end
|
|
219
199
|
|
|
220
|
-
private
|
|
221
|
-
|
|
222
200
|
# Instantiate the binding associated with this relation.
|
|
223
201
|
#
|
|
224
202
|
# @example Get the binding.
|
|
225
203
|
# relation.binding([ address ])
|
|
226
204
|
#
|
|
227
|
-
# @param [ Array<Document> ] new_target The new documents to bind with.
|
|
228
|
-
#
|
|
229
205
|
# @return [ Binding ] The binding.
|
|
230
206
|
#
|
|
231
207
|
# @since 2.0.0.rc.1
|
|
232
|
-
def binding
|
|
233
|
-
Bindings::Referenced::ManyToMany.new(base,
|
|
208
|
+
def binding
|
|
209
|
+
Bindings::Referenced::ManyToMany.new(base, target, metadata)
|
|
234
210
|
end
|
|
235
211
|
|
|
236
212
|
# Returns the criteria object for the target class with its documents set
|
|
@@ -241,44 +217,7 @@ module Mongoid # :nodoc:
|
|
|
241
217
|
#
|
|
242
218
|
# @return [ Criteria ] A new criteria.
|
|
243
219
|
def criteria
|
|
244
|
-
|
|
245
|
-
metadata.klass.any_in(metadata.inverse_foreign_key => [ base.id ])
|
|
246
|
-
else
|
|
247
|
-
metadata.klass.where(:_id => { "$in" => base.send(metadata.foreign_key) })
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# Dereferences the supplied document from the base of the relation.
|
|
252
|
-
#
|
|
253
|
-
# @example Dereference the document.
|
|
254
|
-
# person.preferences.dereference(preference)
|
|
255
|
-
#
|
|
256
|
-
# @param [ Document ] document The document to dereference.
|
|
257
|
-
def dereference(document)
|
|
258
|
-
document.send(metadata.inverse_foreign_key).delete(base.id)
|
|
259
|
-
document.send(metadata.inverse(document)).target.delete(base)
|
|
260
|
-
document.save
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
# Remove all documents from the relation, either with a delete or a
|
|
264
|
-
# destroy depending on what this was called through.
|
|
265
|
-
#
|
|
266
|
-
# @example Destroy documents from the relation.
|
|
267
|
-
# relation.remove_all(:conditions => { :num => 1 }, true)
|
|
268
|
-
#
|
|
269
|
-
# @param [ Hash ] conditions Conditions to filter by.
|
|
270
|
-
# @param [ true, false ] destroy If true then destroy, else delete.
|
|
271
|
-
#
|
|
272
|
-
# @return [ Integer ] The number of documents removed.
|
|
273
|
-
def remove_all(conditions = {}, method = :destroy)
|
|
274
|
-
cond = conditions || {}
|
|
275
|
-
target.delete_if do |doc|
|
|
276
|
-
doc.matches?(cond[:conditions] || {})
|
|
277
|
-
end
|
|
278
|
-
ids = criteria.merge(cond).only(:_id).map(&:_id)
|
|
279
|
-
criteria.merge(cond).send(method).tap do
|
|
280
|
-
base.pull_all(metadata.foreign_key, ids)
|
|
281
|
-
end
|
|
220
|
+
ManyToMany.criteria(metadata, base.send(metadata.foreign_key))
|
|
282
221
|
end
|
|
283
222
|
|
|
284
223
|
class << self
|
|
@@ -296,8 +235,12 @@ module Mongoid # :nodoc:
|
|
|
296
235
|
# @return [ Builder ] A new builder object.
|
|
297
236
|
#
|
|
298
237
|
# @since 2.0.0.rc.1
|
|
299
|
-
def builder(meta, object)
|
|
300
|
-
Builders::Referenced::ManyToMany.new(meta, object)
|
|
238
|
+
def builder(meta, object, loading = false)
|
|
239
|
+
Builders::Referenced::ManyToMany.new(meta, object, loading)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def criteria(metadata, object, type = nil)
|
|
243
|
+
metadata.klass.any_in(:_id => object)
|
|
301
244
|
end
|
|
302
245
|
|
|
303
246
|
# Returns true if the relation is an embedded one. In this case
|
|
@@ -374,6 +317,20 @@ module Mongoid # :nodoc:
|
|
|
374
317
|
Builders::NestedAttributes::Many.new(metadata, attributes, options)
|
|
375
318
|
end
|
|
376
319
|
|
|
320
|
+
# Get the path calculator for the supplied document.
|
|
321
|
+
#
|
|
322
|
+
# @example Get the path calculator.
|
|
323
|
+
# Proxy.path(document)
|
|
324
|
+
#
|
|
325
|
+
# @param [ Document ] document The document to calculate on.
|
|
326
|
+
#
|
|
327
|
+
# @return [ Root ] The root atomic path calculator.
|
|
328
|
+
#
|
|
329
|
+
# @since 2.1.0
|
|
330
|
+
def path(document)
|
|
331
|
+
Mongoid::Atomic::Paths::Root.new(document)
|
|
332
|
+
end
|
|
333
|
+
|
|
377
334
|
# Tells the caller if this relation is one that stores the foreign
|
|
378
335
|
# key on its own objects.
|
|
379
336
|
#
|
|
@@ -386,6 +343,18 @@ module Mongoid # :nodoc:
|
|
|
386
343
|
def stores_foreign_key?
|
|
387
344
|
true
|
|
388
345
|
end
|
|
346
|
+
|
|
347
|
+
# Get the valid options allowed with this relation.
|
|
348
|
+
#
|
|
349
|
+
# @example Get the valid options.
|
|
350
|
+
# Relation.valid_options
|
|
351
|
+
#
|
|
352
|
+
# @return [ Array<Symbol> ] The valid options.
|
|
353
|
+
#
|
|
354
|
+
# @since 2.1.0
|
|
355
|
+
def valid_options
|
|
356
|
+
[ :autosave, :dependent, :foreign_key, :index, :order ]
|
|
357
|
+
end
|
|
389
358
|
end
|
|
390
359
|
end
|
|
391
360
|
end
|
|
@@ -7,28 +7,6 @@ module Mongoid # :nodoc:
|
|
|
7
7
|
# one-to-one between documents in different collections.
|
|
8
8
|
class One < Relations::One
|
|
9
9
|
|
|
10
|
-
# Binds the base object to the inverse of the relation. This is so we
|
|
11
|
-
# are referenced to the actual objects themselves and dont hit the
|
|
12
|
-
# database twice when setting the relations up.
|
|
13
|
-
#
|
|
14
|
-
# This is called after first creating the relation, or if a new object
|
|
15
|
-
# is set on the relation.
|
|
16
|
-
#
|
|
17
|
-
# @example Bind the relation.
|
|
18
|
-
# person.game.bind(:continue => false)
|
|
19
|
-
#
|
|
20
|
-
# @param [ Hash ] options The options to bind with.
|
|
21
|
-
#
|
|
22
|
-
# @option options [ true, false ] :binding Are we in build mode?
|
|
23
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
24
|
-
# inverse?
|
|
25
|
-
#
|
|
26
|
-
# @since 2.0.0.rc.1
|
|
27
|
-
def bind(options = {})
|
|
28
|
-
binding.bind(options)
|
|
29
|
-
target.save if base.persisted? && !options[:binding]
|
|
30
|
-
end
|
|
31
|
-
|
|
32
10
|
# Instantiate a new references_one relation. Will set the foreign key
|
|
33
11
|
# and the base on the inverse object.
|
|
34
12
|
#
|
|
@@ -40,24 +18,13 @@ module Mongoid # :nodoc:
|
|
|
40
18
|
# @param [ Metadata ] metadata The relation's metadata.
|
|
41
19
|
def initialize(base, target, metadata)
|
|
42
20
|
init(base, target, metadata) do
|
|
21
|
+
raise_mixed if klass.embedded?
|
|
43
22
|
characterize_one(target)
|
|
23
|
+
bind_one
|
|
24
|
+
target.save if persistable?
|
|
44
25
|
end
|
|
45
26
|
end
|
|
46
27
|
|
|
47
|
-
# Will load the target into an array if the target had not already been
|
|
48
|
-
# loaded.
|
|
49
|
-
#
|
|
50
|
-
# @example Load the relation into memory.
|
|
51
|
-
# relation.load!
|
|
52
|
-
#
|
|
53
|
-
# @return [ One ] The relation.
|
|
54
|
-
#
|
|
55
|
-
# @since 2.0.0.rc.5
|
|
56
|
-
def load!(options = {})
|
|
57
|
-
raise_mixed if klass.embedded?
|
|
58
|
-
super(options)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
28
|
# Removes the association between the base document and the target
|
|
62
29
|
# document by deleting the foreign key and the reference, orphaning
|
|
63
30
|
# the target document in the process.
|
|
@@ -67,32 +34,29 @@ module Mongoid # :nodoc:
|
|
|
67
34
|
#
|
|
68
35
|
# @since 2.0.0.rc.1
|
|
69
36
|
def nullify
|
|
70
|
-
|
|
71
|
-
target.send(:remove_instance_variable, "@#{metadata.inverse(target)}")
|
|
72
|
-
base.send(:remove_instance_variable, "@#{metadata.name}")
|
|
37
|
+
unbind_one
|
|
73
38
|
target.save
|
|
74
39
|
end
|
|
75
40
|
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
# Will delete the object if necessary.
|
|
41
|
+
# Substitutes the supplied target document for the existing document
|
|
42
|
+
# in the relation. If the new target is nil, perform the necessary
|
|
43
|
+
# deletion.
|
|
80
44
|
#
|
|
81
|
-
# @example
|
|
82
|
-
# person.game.
|
|
45
|
+
# @example Replace the relation.
|
|
46
|
+
# person.game.substitute(new_game)
|
|
83
47
|
#
|
|
84
|
-
# @param [ Document ]
|
|
85
|
-
# @param [ Hash ] options The options to bind with.
|
|
48
|
+
# @param [ Array<Document> ] replacement The replacement target.
|
|
86
49
|
#
|
|
87
|
-
# @
|
|
88
|
-
# @option options [ true, false ] :continue Continue binding the
|
|
89
|
-
# inverse?
|
|
50
|
+
# @return [ One ] The relation.
|
|
90
51
|
#
|
|
91
52
|
# @since 2.0.0.rc.1
|
|
92
|
-
def
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
53
|
+
def substitute(replacement)
|
|
54
|
+
tap do |proxy|
|
|
55
|
+
proxy.unbind_one
|
|
56
|
+
proxy.target.delete if persistable?
|
|
57
|
+
return nil unless replacement
|
|
58
|
+
proxy.target = replacement
|
|
59
|
+
proxy.bind_one
|
|
96
60
|
end
|
|
97
61
|
end
|
|
98
62
|
|
|
@@ -106,8 +70,20 @@ module Mongoid # :nodoc:
|
|
|
106
70
|
# @param [ Document ] new_target The new target of the relation.
|
|
107
71
|
#
|
|
108
72
|
# @return [ Binding ] The binding object.
|
|
109
|
-
def binding
|
|
110
|
-
Bindings::Referenced::One.new(base,
|
|
73
|
+
def binding
|
|
74
|
+
Bindings::Referenced::One.new(base, target, metadata)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Are we able to persist this relation?
|
|
78
|
+
#
|
|
79
|
+
# @example Can we persist the relation?
|
|
80
|
+
# relation.persistable?
|
|
81
|
+
#
|
|
82
|
+
# @return [ true, false ] If the relation is persistable.
|
|
83
|
+
#
|
|
84
|
+
# @since 2.1.0
|
|
85
|
+
def persistable?
|
|
86
|
+
base.persisted? && !binding? && !building?
|
|
111
87
|
end
|
|
112
88
|
|
|
113
89
|
class << self
|
|
@@ -125,8 +101,24 @@ module Mongoid # :nodoc:
|
|
|
125
101
|
# @return [ Builder ] A new builder object.
|
|
126
102
|
#
|
|
127
103
|
# @since 2.0.0.rc.1
|
|
128
|
-
def builder(meta, object)
|
|
129
|
-
Builders::Referenced::One.new(meta, object)
|
|
104
|
+
def builder(meta, object, loading = false)
|
|
105
|
+
Builders::Referenced::One.new(meta, object, loading)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Get the standard criteria used for querying this relation.
|
|
109
|
+
#
|
|
110
|
+
# @example Get the criteria.
|
|
111
|
+
# Proxy.criteria(meta, id, Model)
|
|
112
|
+
#
|
|
113
|
+
# @param [ Metadata ] metadata The metadata.
|
|
114
|
+
# @param [ Object ] object The value of the foreign key.
|
|
115
|
+
# @param [ Class ] type The optional type.
|
|
116
|
+
#
|
|
117
|
+
# @return [ Criteria ] The criteria.
|
|
118
|
+
#
|
|
119
|
+
# @since 2.1.0
|
|
120
|
+
def criteria(metadata, object, type = nil)
|
|
121
|
+
metadata.klass.where(metadata.foreign_key => object)
|
|
130
122
|
end
|
|
131
123
|
|
|
132
124
|
# Returns true if the relation is an embedded one. In this case
|
|
@@ -203,6 +195,20 @@ module Mongoid # :nodoc:
|
|
|
203
195
|
Builders::NestedAttributes::One.new(metadata, attributes, options)
|
|
204
196
|
end
|
|
205
197
|
|
|
198
|
+
# Get the path calculator for the supplied document.
|
|
199
|
+
#
|
|
200
|
+
# @example Get the path calculator.
|
|
201
|
+
# Proxy.path(document)
|
|
202
|
+
#
|
|
203
|
+
# @param [ Document ] document The document to calculate on.
|
|
204
|
+
#
|
|
205
|
+
# @return [ Root ] The root atomic path calculator.
|
|
206
|
+
#
|
|
207
|
+
# @since 2.1.0
|
|
208
|
+
def path(document)
|
|
209
|
+
Mongoid::Atomic::Paths::Root.new(document)
|
|
210
|
+
end
|
|
211
|
+
|
|
206
212
|
# Tells the caller if this relation is one that stores the foreign
|
|
207
213
|
# key on its own objects.
|
|
208
214
|
#
|
|
@@ -215,6 +221,18 @@ module Mongoid # :nodoc:
|
|
|
215
221
|
def stores_foreign_key?
|
|
216
222
|
false
|
|
217
223
|
end
|
|
224
|
+
|
|
225
|
+
# Get the valid options allowed with this relation.
|
|
226
|
+
#
|
|
227
|
+
# @example Get the valid options.
|
|
228
|
+
# Relation.valid_options
|
|
229
|
+
#
|
|
230
|
+
# @return [ Array<Symbol> ] The valid options.
|
|
231
|
+
#
|
|
232
|
+
# @since 2.1.0
|
|
233
|
+
def valid_options
|
|
234
|
+
[ :as, :autosave, :dependent, :foreign_key ]
|
|
235
|
+
end
|
|
218
236
|
end
|
|
219
237
|
end
|
|
220
238
|
end
|