mongoid 6.4.2 → 7.0.3
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/config/locales/en.yml +17 -0
- data/lib/mongoid/association/accessors.rb +339 -0
- data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
- data/lib/mongoid/association/builders.rb +92 -0
- data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
- data/lib/mongoid/association/depending.rb +137 -0
- data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
- data/lib/mongoid/{relations → association}/embedded/batchable.rb +19 -19
- data/lib/mongoid/association/embedded/cyclic.rb +109 -0
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
- data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
- data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
- data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
- data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +552 -0
- data/lib/mongoid/association/embedded/embeds_many.rb +210 -0
- data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
- data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
- data/lib/mongoid/association/embedded/embeds_one.rb +173 -0
- data/lib/mongoid/association/embedded.rb +4 -0
- data/lib/mongoid/association/macros.rb +204 -0
- data/lib/mongoid/{relations → association}/many.rb +19 -49
- data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
- data/lib/mongoid/association/nested/many.rb +200 -0
- data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
- data/lib/mongoid/association/nested/one.rb +127 -0
- data/lib/mongoid/association/nested.rb +15 -0
- data/lib/mongoid/{relations → association}/one.rb +6 -6
- data/lib/mongoid/association/options.rb +152 -0
- data/lib/mongoid/{relations → association}/proxy.rb +31 -58
- data/lib/mongoid/association/referenced/auto_save.rb +79 -0
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
- data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
- data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
- data/lib/mongoid/association/referenced/eager.rb +162 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +312 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
- data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
- data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
- data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +510 -0
- data/lib/mongoid/association/referenced/has_many/proxy.rb +578 -0
- data/lib/mongoid/association/referenced/has_many.rb +275 -0
- data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
- data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
- data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
- data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
- data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
- data/lib/mongoid/association/referenced/has_one.rb +204 -0
- data/lib/mongoid/association/referenced/syncable.rb +170 -0
- data/lib/mongoid/association/referenced.rb +7 -0
- data/lib/mongoid/{relations → association}/reflections.rb +21 -17
- data/lib/mongoid/association/relatable.rb +509 -0
- data/lib/mongoid/{relations.rb → association.rb} +57 -56
- data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
- data/lib/mongoid/atomic.rb +4 -4
- data/lib/mongoid/attributes/dynamic.rb +2 -2
- data/lib/mongoid/attributes/nested.rb +22 -11
- data/lib/mongoid/attributes/processing.rb +2 -2
- data/lib/mongoid/attributes/readonly.rb +2 -4
- data/lib/mongoid/attributes.rb +22 -13
- data/lib/mongoid/changeable.rb +1 -1
- data/lib/mongoid/clients/options.rb +7 -5
- data/lib/mongoid/composable.rb +4 -4
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +21 -3
- data/lib/mongoid/contextual/mongo.rb +10 -8
- data/lib/mongoid/copyable.rb +7 -6
- data/lib/mongoid/criteria/includable.rb +14 -14
- data/lib/mongoid/criteria/modifiable.rb +8 -14
- data/lib/mongoid/criteria/options.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
- data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
- data/lib/mongoid/criteria/queryable/selectable.rb +37 -7
- data/lib/mongoid/criteria.rb +2 -2
- data/lib/mongoid/document.rb +15 -6
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
- data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
- data/lib/mongoid/errors/unknown_model.rb +25 -0
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/extensions/array.rb +5 -5
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/hash.rb +5 -2
- data/lib/mongoid/extensions/object.rb +4 -4
- data/lib/mongoid/extensions/range.rb +1 -0
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/factory.rb +13 -3
- data/lib/mongoid/fields/foreign_key.rb +5 -5
- data/lib/mongoid/fields/standard.rb +2 -14
- data/lib/mongoid/fields/validators/macro.rb +1 -1
- data/lib/mongoid/fields.rb +3 -3
- data/lib/mongoid/indexable.rb +4 -1
- data/lib/mongoid/interceptable.rb +5 -5
- data/lib/mongoid/matchable/and.rb +1 -1
- data/lib/mongoid/matchable/elem_match.rb +9 -3
- data/lib/mongoid/matchable/eq.rb +22 -0
- data/lib/mongoid/matchable/ne.rb +1 -1
- data/lib/mongoid/matchable.rb +3 -1
- data/lib/mongoid/persistable/deletable.rb +7 -6
- data/lib/mongoid/persistable/incrementable.rb +1 -1
- data/lib/mongoid/persistable/logical.rb +1 -1
- data/lib/mongoid/persistable/settable.rb +57 -12
- data/lib/mongoid/persistable.rb +4 -5
- data/lib/mongoid/persistence_context.rb +20 -5
- data/lib/mongoid/query_cache.rb +8 -4
- data/lib/mongoid/railtie.rb +17 -0
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +4 -4
- data/lib/mongoid/shardable.rb +1 -1
- data/lib/mongoid/threaded.rb +36 -0
- data/lib/mongoid/touchable.rb +102 -0
- data/lib/mongoid/traversable.rb +3 -3
- data/lib/mongoid/validatable/presence.rb +2 -2
- data/lib/mongoid/validatable/uniqueness.rb +4 -4
- data/lib/mongoid/validatable.rb +8 -8
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -0
- data/spec/app/models/animal.rb +2 -1
- data/spec/app/models/bomb.rb +1 -1
- data/spec/app/models/message.rb +1 -1
- data/spec/app/models/minim.rb +7 -0
- data/spec/app/models/person.rb +5 -2
- data/spec/app/models/shipment_address.rb +1 -0
- data/spec/app/models/store_as_dup_test3.rb +7 -0
- data/spec/app/models/store_as_dup_test4.rb +7 -0
- data/spec/app/models/updatable.rb +7 -0
- data/spec/app/models/vertex.rb +6 -0
- data/spec/app/models/wiki_page.rb +1 -1
- data/spec/config/mongoid.yml +13 -3
- data/spec/integration/associations/belongs_to_spec.rb +13 -0
- data/spec/lite_spec_helper.rb +56 -0
- data/spec/mongoid/{relations → association}/accessors_spec.rb +40 -1
- data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
- data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
- data/spec/mongoid/association/constrainable_spec.rb +115 -0
- data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
- data/spec/mongoid/association/depending_spec.rb +866 -0
- data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
- data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
- data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
- data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
- data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +5 -77
- data/spec/mongoid/association/embedded/embedded_in_spec.rb +843 -0
- data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
- data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
- data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +124 -182
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +852 -0
- data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
- data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
- data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +908 -0
- data/spec/mongoid/{relations → association}/macros_spec.rb +148 -73
- data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
- data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
- data/spec/mongoid/association/options_spec.rb +1321 -0
- data/spec/mongoid/{relations → association}/polymorphic_spec.rb +66 -34
- data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
- data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
- data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +33 -14
- data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2006 -0
- data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
- data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +26 -7
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +56 -0
- data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +107 -98
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1027 -0
- data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
- data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +26 -11
- data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +122 -1
- data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
- data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +28 -93
- data/spec/mongoid/association/referenced/has_many_models.rb +37 -0
- data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
- data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
- data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
- data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
- data/spec/mongoid/association/referenced/has_one_models.rb +48 -0
- data/spec/mongoid/association/referenced/has_one_spec.rb +1350 -0
- data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
- data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
- data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
- data/spec/mongoid/atomic/modifiers_spec.rb +2 -2
- data/spec/mongoid/atomic_spec.rb +4 -4
- data/spec/mongoid/attributes/nested_spec.rb +29 -11
- data/spec/mongoid/attributes/readonly_spec.rb +80 -125
- data/spec/mongoid/attributes_spec.rb +38 -2
- data/spec/mongoid/clients/factory_spec.rb +24 -18
- data/spec/mongoid/clients/options_spec.rb +58 -44
- data/spec/mongoid/clients/sessions_spec.rb +1 -1
- data/spec/mongoid/clients/transactions_spec.rb +369 -0
- data/spec/mongoid/clients_spec.rb +68 -8
- data/spec/mongoid/config_spec.rb +27 -1
- data/spec/mongoid/contextual/memory_spec.rb +19 -0
- data/spec/mongoid/contextual/mongo_spec.rb +33 -5
- data/spec/mongoid/copyable_spec.rb +90 -6
- data/spec/mongoid/copyable_spec_models.rb +17 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +183 -60
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +43 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +42 -3
- data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +33 -18
- data/spec/mongoid/document_spec.rb +83 -4
- data/spec/mongoid/extensions/array_spec.rb +11 -15
- data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
- data/spec/mongoid/extensions/hash_spec.rb +18 -1
- data/spec/mongoid/extensions/object_spec.rb +7 -11
- data/spec/mongoid/extensions/range_spec.rb +7 -0
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/factory_spec.rb +19 -1
- data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
- data/spec/mongoid/fields_spec.rb +2 -2
- data/spec/mongoid/findable_spec.rb +1 -1
- data/spec/mongoid/indexable_spec.rb +18 -8
- data/spec/mongoid/interceptable_spec.rb +22 -1
- data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
- data/spec/mongoid/matchable/eq_spec.rb +48 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/savable_spec.rb +2 -2
- data/spec/mongoid/persistable/settable_spec.rb +95 -10
- data/spec/mongoid/persistable_spec.rb +21 -6
- data/spec/mongoid/persistence_context_spec.rb +1 -1
- data/spec/mongoid/query_cache_spec.rb +61 -22
- data/spec/mongoid/relations/proxy_spec.rb +124 -124
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/shardable_spec.rb +32 -12
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/mongoid/{relations/touchable_spec.rb → touchable_spec.rb} +40 -1
- data/spec/mongoid/validatable/associated_spec.rb +1 -1
- data/spec/mongoid/validatable/presence_spec.rb +7 -6
- data/spec/mongoid/validatable_spec.rb +1 -1
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +51 -25
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/spec_config.rb +39 -0
- metadata +602 -582
- checksums.yaml.gz.sig +0 -2
- data/lib/mongoid/relations/accessors.rb +0 -267
- data/lib/mongoid/relations/auto_save.rb +0 -94
- data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
- data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
- data/lib/mongoid/relations/bindings.rb +0 -9
- data/lib/mongoid/relations/builder.rb +0 -57
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
- data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
- data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
- data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
- data/lib/mongoid/relations/builders.rb +0 -106
- data/lib/mongoid/relations/cascading/delete.rb +0 -44
- data/lib/mongoid/relations/cascading/destroy.rb +0 -43
- data/lib/mongoid/relations/cascading/nullify.rb +0 -35
- data/lib/mongoid/relations/cascading/restrict.rb +0 -39
- data/lib/mongoid/relations/cascading.rb +0 -56
- data/lib/mongoid/relations/conversions.rb +0 -34
- data/lib/mongoid/relations/counter_cache.rb +0 -160
- data/lib/mongoid/relations/cyclic.rb +0 -107
- data/lib/mongoid/relations/eager/base.rb +0 -153
- data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
- data/lib/mongoid/relations/eager/has_many.rb +0 -38
- data/lib/mongoid/relations/eager/has_one.rb +0 -30
- data/lib/mongoid/relations/embedded/in.rb +0 -241
- data/lib/mongoid/relations/embedded/many.rb +0 -683
- data/lib/mongoid/relations/embedded/one.rb +0 -235
- data/lib/mongoid/relations/macros.rb +0 -367
- data/lib/mongoid/relations/metadata.rb +0 -1179
- data/lib/mongoid/relations/nested_builder.rb +0 -74
- data/lib/mongoid/relations/options.rb +0 -49
- data/lib/mongoid/relations/polymorphic.rb +0 -39
- data/lib/mongoid/relations/referenced/in.rb +0 -304
- data/lib/mongoid/relations/referenced/many.rb +0 -812
- data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
- data/lib/mongoid/relations/referenced/one.rb +0 -290
- data/lib/mongoid/relations/synchronization.rb +0 -169
- data/lib/mongoid/relations/targets/enumerable.rb +0 -493
- data/lib/mongoid/relations/targets.rb +0 -2
- data/lib/mongoid/relations/touchable.rb +0 -97
- data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
- data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
- data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
- data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
- data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
- data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
- data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
- data/spec/mongoid/relations/cascading_spec.rb +0 -355
- data/spec/mongoid/relations/constraint_spec.rb +0 -75
- data/spec/mongoid/relations/conversions_spec.rb +0 -128
- data/spec/mongoid/relations/metadata_spec.rb +0 -1985
- data/spec/mongoid/relations/options_spec.rb +0 -35
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
- /data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Association
|
|
4
|
+
|
|
5
|
+
# This module contains the core macros for defining relations between
|
|
6
|
+
# documents. They can be either embedded or referenced (relational).
|
|
7
|
+
module Macros
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
class_attribute :embedded, instance_reader: false
|
|
12
|
+
class_attribute :embedded_relations
|
|
13
|
+
class_attribute :relations
|
|
14
|
+
self.embedded = false
|
|
15
|
+
self.embedded_relations = BSON::Document.new
|
|
16
|
+
self.relations = BSON::Document.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# This is convenience for libraries still on the old API.
|
|
20
|
+
#
|
|
21
|
+
# @example Get the associations.
|
|
22
|
+
# person.associations
|
|
23
|
+
#
|
|
24
|
+
# @return [ Hash ] The relations.
|
|
25
|
+
#
|
|
26
|
+
# @since 2.3.1
|
|
27
|
+
def associations
|
|
28
|
+
self.relations
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module ClassMethods
|
|
32
|
+
|
|
33
|
+
# Adds the relation back to the parent document. This macro is
|
|
34
|
+
# necessary to set the references from the child back to the parent
|
|
35
|
+
# document. If a child does not define this relation calling
|
|
36
|
+
# persistence methods on the child object will cause a save to fail.
|
|
37
|
+
#
|
|
38
|
+
# @example Define the relation.
|
|
39
|
+
#
|
|
40
|
+
# class Person
|
|
41
|
+
# include Mongoid::Document
|
|
42
|
+
# embeds_many :addresses
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# class Address
|
|
46
|
+
# include Mongoid::Document
|
|
47
|
+
# embedded_in :person
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# @param [ Symbol ] name The name of the relation.
|
|
51
|
+
# @param [ Hash ] options The relation options.
|
|
52
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
53
|
+
def embedded_in(name, options = {}, &block)
|
|
54
|
+
define_association!(__method__, name, options, &block)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Adds the relation from a parent document to its children. The name
|
|
58
|
+
# of the relation needs to be a pluralized form of the child class
|
|
59
|
+
# name.
|
|
60
|
+
#
|
|
61
|
+
# @example Define the relation.
|
|
62
|
+
#
|
|
63
|
+
# class Person
|
|
64
|
+
# include Mongoid::Document
|
|
65
|
+
# embeds_many :addresses
|
|
66
|
+
# end
|
|
67
|
+
#
|
|
68
|
+
# class Address
|
|
69
|
+
# include Mongoid::Document
|
|
70
|
+
# embedded_in :person
|
|
71
|
+
# end
|
|
72
|
+
#
|
|
73
|
+
# @param [ Symbol ] name The name of the relation.
|
|
74
|
+
# @param [ Hash ] options The relation options.
|
|
75
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
76
|
+
def embeds_many(name, options = {}, &block)
|
|
77
|
+
define_association!(__method__, name, options, &block)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Adds the relation from a parent document to its child. The name
|
|
81
|
+
# of the relation needs to be a singular form of the child class
|
|
82
|
+
# name.
|
|
83
|
+
#
|
|
84
|
+
# @example Define the relation.
|
|
85
|
+
#
|
|
86
|
+
# class Person
|
|
87
|
+
# include Mongoid::Document
|
|
88
|
+
# embeds_one :name
|
|
89
|
+
# end
|
|
90
|
+
#
|
|
91
|
+
# class Name
|
|
92
|
+
# include Mongoid::Document
|
|
93
|
+
# embedded_in :person
|
|
94
|
+
# end
|
|
95
|
+
#
|
|
96
|
+
# @param [ Symbol ] name The name of the relation.
|
|
97
|
+
# @param [ Hash ] options The relation options.
|
|
98
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
99
|
+
def embeds_one(name, options = {}, &block)
|
|
100
|
+
define_association!(__method__, name, options, &block)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Adds a relational association from the child Document to a Document in
|
|
104
|
+
# another database or collection.
|
|
105
|
+
#
|
|
106
|
+
# @example Define the relation.
|
|
107
|
+
#
|
|
108
|
+
# class Game
|
|
109
|
+
# include Mongoid::Document
|
|
110
|
+
# belongs_to :person
|
|
111
|
+
# end
|
|
112
|
+
#
|
|
113
|
+
# class Person
|
|
114
|
+
# include Mongoid::Document
|
|
115
|
+
# has_one :game
|
|
116
|
+
# end
|
|
117
|
+
#
|
|
118
|
+
# @param [ Symbol ] name The name of the relation.
|
|
119
|
+
# @param [ Hash ] options The relation options.
|
|
120
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
121
|
+
def belongs_to(name, options = {}, &block)
|
|
122
|
+
define_association!(__method__, name, options, &block)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Adds a relational association from a parent Document to many
|
|
126
|
+
# Documents in another database or collection.
|
|
127
|
+
#
|
|
128
|
+
# @example Define the relation.
|
|
129
|
+
#
|
|
130
|
+
# class Person
|
|
131
|
+
# include Mongoid::Document
|
|
132
|
+
# has_many :posts
|
|
133
|
+
# end
|
|
134
|
+
#
|
|
135
|
+
# class Game
|
|
136
|
+
# include Mongoid::Document
|
|
137
|
+
# belongs_to :person
|
|
138
|
+
# end
|
|
139
|
+
#
|
|
140
|
+
# @param [ Symbol ] name The name of the relation.
|
|
141
|
+
# @param [ Hash ] options The relation options.
|
|
142
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
143
|
+
def has_many(name, options = {}, &block)
|
|
144
|
+
define_association!(__method__, name, options, &block)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Adds a relational many-to-many association between many of this
|
|
148
|
+
# Document and many of another Document.
|
|
149
|
+
#
|
|
150
|
+
# @example Define the relation.
|
|
151
|
+
#
|
|
152
|
+
# class Person
|
|
153
|
+
# include Mongoid::Document
|
|
154
|
+
# has_and_belongs_to_many :preferences
|
|
155
|
+
# end
|
|
156
|
+
#
|
|
157
|
+
# class Preference
|
|
158
|
+
# include Mongoid::Document
|
|
159
|
+
# has_and_belongs_to_many :people
|
|
160
|
+
# end
|
|
161
|
+
#
|
|
162
|
+
# @param [ Symbol ] name The name of the relation.
|
|
163
|
+
# @param [ Hash ] options The relation options.
|
|
164
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
165
|
+
#
|
|
166
|
+
# @since 2.0.0.rc.1
|
|
167
|
+
def has_and_belongs_to_many(name, options = {}, &block)
|
|
168
|
+
define_association!(__method__, name, options, &block)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Adds a relational association from the child Document to a Document in
|
|
172
|
+
# another database or collection.
|
|
173
|
+
#
|
|
174
|
+
# @example Define the relation.
|
|
175
|
+
#
|
|
176
|
+
# class Game
|
|
177
|
+
# include Mongoid::Document
|
|
178
|
+
# belongs_to :person
|
|
179
|
+
# end
|
|
180
|
+
#
|
|
181
|
+
# class Person
|
|
182
|
+
# include Mongoid::Document
|
|
183
|
+
# has_one :game
|
|
184
|
+
# end
|
|
185
|
+
#
|
|
186
|
+
# @param [ Symbol ] name The name of the relation.
|
|
187
|
+
# @param [ Hash ] options The relation options.
|
|
188
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
189
|
+
def has_one(name, options = {}, &block)
|
|
190
|
+
define_association!(__method__, name, options, &block)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
|
|
195
|
+
def define_association!(macro_name, name, options = {}, &block)
|
|
196
|
+
Association::MACRO_MAPPING[macro_name].new(self, name, options, &block).tap do |assoc|
|
|
197
|
+
assoc.setup!
|
|
198
|
+
self.relations = self.relations.merge(name => assoc)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
module Mongoid
|
|
3
|
-
module
|
|
3
|
+
module Association
|
|
4
4
|
|
|
5
5
|
# This is the superclass for all many to one and many to many relation
|
|
6
6
|
# proxies.
|
|
7
|
-
class Many < Proxy
|
|
7
|
+
class Many < Association::Proxy
|
|
8
8
|
include ::Enumerable
|
|
9
9
|
|
|
10
10
|
delegate :avg, :max, :min, :sum, to: :criteria
|
|
11
|
-
delegate :length, :size, to: :
|
|
11
|
+
delegate :length, :size, to: :_target
|
|
12
12
|
|
|
13
13
|
# Is the relation empty?
|
|
14
14
|
#
|
|
@@ -28,14 +28,9 @@ module Mongoid
|
|
|
28
28
|
# @example Create and save the new document.
|
|
29
29
|
# person.posts.create(:text => "Testing")
|
|
30
30
|
#
|
|
31
|
-
# @overload create(attributes = nil, options = {}, type = nil)
|
|
32
|
-
# @param [ Hash ] attributes The attributes to create with.
|
|
33
|
-
# @param [ Hash ] options The scoped assignment options.
|
|
34
|
-
# @param [ Class ] type The optional type of document to create.
|
|
35
31
|
#
|
|
36
|
-
# @
|
|
37
|
-
#
|
|
38
|
-
# @param [ Class ] type The optional type of document to create.
|
|
32
|
+
# @param [ Hash ] attributes The attributes to create with.
|
|
33
|
+
# @param [ Class ] type The optional type of document to create.
|
|
39
34
|
#
|
|
40
35
|
# @return [ Document ] The newly created document.
|
|
41
36
|
#
|
|
@@ -45,7 +40,7 @@ module Mongoid
|
|
|
45
40
|
attributes.map { |attrs| create(attrs, type, &block) }
|
|
46
41
|
else
|
|
47
42
|
doc = build(attributes, type, &block)
|
|
48
|
-
|
|
43
|
+
_base.persisted? ? doc.save : raise_unsaved(doc)
|
|
49
44
|
doc
|
|
50
45
|
end
|
|
51
46
|
end
|
|
@@ -57,13 +52,8 @@ module Mongoid
|
|
|
57
52
|
# @example Create and save the new document.
|
|
58
53
|
# person.posts.create!(:text => "Testing")
|
|
59
54
|
#
|
|
60
|
-
# @
|
|
61
|
-
#
|
|
62
|
-
# @param [ Class ] type The optional type of document to create.
|
|
63
|
-
#
|
|
64
|
-
# @overload create!(attributes = nil, type = nil)
|
|
65
|
-
# @param [ Hash ] attributes The attributes to create with.
|
|
66
|
-
# @param [ Class ] type The optional type of document to create.
|
|
55
|
+
# @param [ Hash ] attributes The attributes to create with.
|
|
56
|
+
# @param [ Class ] type The optional type of document to create.
|
|
67
57
|
#
|
|
68
58
|
# @raise [ Errors::Validations ] If validation failed.
|
|
69
59
|
#
|
|
@@ -75,7 +65,7 @@ module Mongoid
|
|
|
75
65
|
attributes.map { |attrs| create!(attrs, type, &block) }
|
|
76
66
|
else
|
|
77
67
|
doc = build(attributes, type, &block)
|
|
78
|
-
|
|
68
|
+
_base.persisted? ? doc.save! : raise_unsaved(doc)
|
|
79
69
|
doc
|
|
80
70
|
end
|
|
81
71
|
end
|
|
@@ -86,13 +76,8 @@ module Mongoid
|
|
|
86
76
|
# @example Find or create.
|
|
87
77
|
# person.posts.find_or_create_by(:title => "Testing")
|
|
88
78
|
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
# @param [ Class ] type The optional type of document to create.
|
|
92
|
-
#
|
|
93
|
-
# @overload find_or_create_by(attributes = nil, type = nil)
|
|
94
|
-
# @param [ Hash ] attributes The attributes to search or create with.
|
|
95
|
-
# @param [ Class ] type The optional type of document to create.
|
|
79
|
+
# @param [ Hash ] attrs The attributes to search or create with.
|
|
80
|
+
# @param [ Class ] type The optional type of document to create.
|
|
96
81
|
#
|
|
97
82
|
# @return [ Document ] An existing document or newly created one.
|
|
98
83
|
def find_or_create_by(attrs = {}, type = nil, &block)
|
|
@@ -105,13 +90,8 @@ module Mongoid
|
|
|
105
90
|
# @example Find or create.
|
|
106
91
|
# person.posts.find_or_create_by!(:title => "Testing")
|
|
107
92
|
#
|
|
108
|
-
# @
|
|
109
|
-
#
|
|
110
|
-
# @param [ Class ] type The optional type of document to create.
|
|
111
|
-
#
|
|
112
|
-
# @overload find_or_create_by!(attributes = nil, type = nil)
|
|
113
|
-
# @param [ Hash ] attributes The attributes to search or create with.
|
|
114
|
-
# @param [ Class ] type The optional type of document to create.
|
|
93
|
+
# @param [ Hash ] attrs The attributes to search or create with.
|
|
94
|
+
# @param [ Class ] type The optional type of document to create.
|
|
115
95
|
#
|
|
116
96
|
# @raise [ Errors::Validations ] If validation failed.
|
|
117
97
|
#
|
|
@@ -126,13 +106,8 @@ module Mongoid
|
|
|
126
106
|
# @example Find or initialize.
|
|
127
107
|
# person.posts.find_or_initialize_by(:title => "Test")
|
|
128
108
|
#
|
|
129
|
-
# @
|
|
130
|
-
#
|
|
131
|
-
# @param [ Class ] type The optional subclass to build.
|
|
132
|
-
#
|
|
133
|
-
# @overload find_or_initialize_by(attributes = {}, type = nil)
|
|
134
|
-
# @param [ Hash ] attributes The attributes to search or initialize with.
|
|
135
|
-
# @param [ Class ] type The optional subclass to build.
|
|
109
|
+
# @param [ Hash ] attrs The attributes to search or initialize with.
|
|
110
|
+
# @param [ Class ] type The optional subclass to build.
|
|
136
111
|
#
|
|
137
112
|
# @return [ Document ] An existing document or newly instantiated one.
|
|
138
113
|
def find_or_initialize_by(attrs = {}, type = nil, &block)
|
|
@@ -157,6 +132,7 @@ module Mongoid
|
|
|
157
132
|
# relation.respond_to?(:name)
|
|
158
133
|
#
|
|
159
134
|
# @param [ Symbol ] name The method name.
|
|
135
|
+
# @param [ true, false ] include_private Whether to include private methods.
|
|
160
136
|
#
|
|
161
137
|
# @return [ true, false ] If the proxy responds to the method.
|
|
162
138
|
#
|
|
@@ -195,7 +171,7 @@ module Mongoid
|
|
|
195
171
|
#
|
|
196
172
|
# @since 2.0.0.rc.6
|
|
197
173
|
def serializable_hash(options = {})
|
|
198
|
-
|
|
174
|
+
_target.map { |document| document.serializable_hash(options) }
|
|
199
175
|
end
|
|
200
176
|
|
|
201
177
|
# Get a criteria for the embedded documents without the default scoping
|
|
@@ -214,7 +190,7 @@ module Mongoid
|
|
|
214
190
|
private
|
|
215
191
|
|
|
216
192
|
def _session
|
|
217
|
-
|
|
193
|
+
_base.send(:_session)
|
|
218
194
|
end
|
|
219
195
|
|
|
220
196
|
# Find the first object given the supplied attributes or create/initialize it.
|
|
@@ -222,14 +198,8 @@ module Mongoid
|
|
|
222
198
|
# @example Find or create|initialize.
|
|
223
199
|
# person.addresses.find_or(:create, :street => "Bond")
|
|
224
200
|
#
|
|
225
|
-
# @overload find_or(method, attributes = {}, type = nil)
|
|
226
|
-
# @param [ Symbol ] method The method name, create or new.
|
|
227
|
-
# @param [ Hash ] attributes The attributes to search or build with.
|
|
228
|
-
# @param [ Class ] type The optional subclass to build.
|
|
229
|
-
#
|
|
230
|
-
# @overload find_or(attributes = {}, type = nil)
|
|
231
201
|
# @param [ Symbol ] method The method name, create or new.
|
|
232
|
-
# @param [ Hash ]
|
|
202
|
+
# @param [ Hash ] attrs The attributes to search or build with.
|
|
233
203
|
# @param [ Class ] type The optional subclass to build.
|
|
234
204
|
#
|
|
235
205
|
# @return [ Document ] A matching document or a new/created one.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
module Mongoid
|
|
3
|
-
module
|
|
3
|
+
module Association
|
|
4
4
|
module Marshalable
|
|
5
5
|
|
|
6
6
|
# Provides the data needed to Marshal.dump a relation proxy.
|
|
@@ -12,7 +12,7 @@ module Mongoid
|
|
|
12
12
|
#
|
|
13
13
|
# @since 3.0.15
|
|
14
14
|
def marshal_dump
|
|
15
|
-
[
|
|
15
|
+
[ _base, _target, _association ]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# Takes the provided data and sets it back on the proxy.
|
|
@@ -20,12 +20,14 @@ module Mongoid
|
|
|
20
20
|
# @example Load the proxy.
|
|
21
21
|
# Marshal.load(proxy)
|
|
22
22
|
#
|
|
23
|
+
# @param [ Array<Object> ] data The data to set on the proxy.
|
|
24
|
+
#
|
|
23
25
|
# @return [ Array<Object> ] The loaded data.
|
|
24
26
|
#
|
|
25
27
|
# @since 3.0.15
|
|
26
28
|
def marshal_load(data)
|
|
27
|
-
@
|
|
28
|
-
extend_proxy(
|
|
29
|
+
@_base, @_target, @_association = data
|
|
30
|
+
extend_proxy(_association.extension) if _association.extension
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Association
|
|
4
|
+
module Nested
|
|
5
|
+
class Many
|
|
6
|
+
include Buildable
|
|
7
|
+
|
|
8
|
+
# Builds the relation depending on the attributes and the options
|
|
9
|
+
# passed to the macro.
|
|
10
|
+
#
|
|
11
|
+
# This attempts to perform 3 operations, either one of an update of
|
|
12
|
+
# the existing relation, a replacement of the relation with a new
|
|
13
|
+
# document, or a removal of the relation.
|
|
14
|
+
#
|
|
15
|
+
# @example Build the nested attrs.
|
|
16
|
+
# many.build(person)
|
|
17
|
+
#
|
|
18
|
+
# @param [ Document ] parent The parent document of the relation.
|
|
19
|
+
# @param [ Hash ] options The options.
|
|
20
|
+
#
|
|
21
|
+
# @return [ Array ] The attributes.
|
|
22
|
+
def build(parent, options = {})
|
|
23
|
+
@existing = parent.send(association.name)
|
|
24
|
+
if over_limit?(attributes)
|
|
25
|
+
raise Errors::TooManyNestedAttributeRecords.new(existing, options[:limit])
|
|
26
|
+
end
|
|
27
|
+
attributes.each do |attrs|
|
|
28
|
+
if attrs.is_a?(::Hash)
|
|
29
|
+
process_attributes(parent, attrs.with_indifferent_access)
|
|
30
|
+
else
|
|
31
|
+
process_attributes(parent, attrs[1].with_indifferent_access)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Create the new builder for nested attributes on one-to-many
|
|
37
|
+
# relations.
|
|
38
|
+
#
|
|
39
|
+
# @example Initialize the builder.
|
|
40
|
+
# Many.new(association, attributes, options)
|
|
41
|
+
#
|
|
42
|
+
# @param [ Association ] association The association metadata.
|
|
43
|
+
# @param [ Hash ] attributes The attributes hash to attempt to set.
|
|
44
|
+
# @param [ Hash ] options The options defined.
|
|
45
|
+
def initialize(association, attributes, options = {})
|
|
46
|
+
if attributes.respond_to?(:with_indifferent_access)
|
|
47
|
+
@attributes = attributes.with_indifferent_access.sort do |a, b|
|
|
48
|
+
a[0].to_i <=> b[0].to_i
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
@attributes = attributes
|
|
52
|
+
end
|
|
53
|
+
@association = association
|
|
54
|
+
@options = options
|
|
55
|
+
@class_name = options[:class_name] ? options[:class_name].constantize : association.klass
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# Can the existing relation potentially be deleted?
|
|
61
|
+
#
|
|
62
|
+
# @example Is the document destroyable?
|
|
63
|
+
# destroyable?({ :_destroy => "1" })
|
|
64
|
+
#
|
|
65
|
+
# @param [ Hash ] attributes The attributes to pull the flag from.
|
|
66
|
+
#
|
|
67
|
+
# @return [ true, false ] If the relation can potentially be deleted.
|
|
68
|
+
def destroyable?(attributes)
|
|
69
|
+
destroy = attributes.delete(:_destroy)
|
|
70
|
+
Nested::DESTROY_FLAGS.include?(destroy) && allow_destroy?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Are the supplied attributes of greater number than the supplied
|
|
74
|
+
# limit?
|
|
75
|
+
#
|
|
76
|
+
# @example Are we over the set limit?
|
|
77
|
+
# builder.over_limit?({ "street" => "Bond" })
|
|
78
|
+
#
|
|
79
|
+
# @param [ Hash ] attributes The attributes being set.
|
|
80
|
+
#
|
|
81
|
+
# @return [ true, false ] If the attributes exceed the limit.
|
|
82
|
+
def over_limit?(attributes)
|
|
83
|
+
limit = options[:limit]
|
|
84
|
+
limit ? attributes.size > limit : false
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Process each set of attributes one at a time for each potential
|
|
88
|
+
# new, existing, or ignored document.
|
|
89
|
+
#
|
|
90
|
+
# @api private
|
|
91
|
+
#
|
|
92
|
+
# @example Process the attributes
|
|
93
|
+
# builder.process_attributes({ "id" => 1, "street" => "Bond" })
|
|
94
|
+
#
|
|
95
|
+
# @param [ Document ] parent The parent document.
|
|
96
|
+
# @param [ Hash ] attrs The single document attributes to process.
|
|
97
|
+
#
|
|
98
|
+
# @since 2.0.0
|
|
99
|
+
def process_attributes(parent, attrs)
|
|
100
|
+
return if reject?(parent, attrs)
|
|
101
|
+
if id = attrs.extract_id
|
|
102
|
+
update_nested_relation(parent, id, attrs)
|
|
103
|
+
else
|
|
104
|
+
existing.push(Factory.build(@class_name, attrs)) unless destroyable?(attrs)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Destroy the child document, needs to do some checking for embedded
|
|
109
|
+
# relations and delay the destroy in case parent validation fails.
|
|
110
|
+
#
|
|
111
|
+
# @api private
|
|
112
|
+
#
|
|
113
|
+
# @example Destroy the child.
|
|
114
|
+
# builder.destroy(parent, relation, doc)
|
|
115
|
+
#
|
|
116
|
+
# @param [ Document ] parent The parent document.
|
|
117
|
+
# @param [ Proxy ] relation The relation proxy.
|
|
118
|
+
# @param [ Document ] doc The doc to destroy.
|
|
119
|
+
#
|
|
120
|
+
# @since 3.0.10
|
|
121
|
+
def destroy(parent, relation, doc)
|
|
122
|
+
doc.flagged_for_destroy = true
|
|
123
|
+
if !doc.embedded? || parent.new_record?
|
|
124
|
+
destroy_document(relation, doc)
|
|
125
|
+
else
|
|
126
|
+
parent.flagged_destroys.push(-> { destroy_document(relation, doc) })
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Destroy the document.
|
|
131
|
+
#
|
|
132
|
+
# @api private
|
|
133
|
+
#
|
|
134
|
+
# @example Destroy the document.
|
|
135
|
+
# builder.destroy_document(relation, doc)
|
|
136
|
+
#
|
|
137
|
+
# @param [ Proxy ] relation The relation proxy.
|
|
138
|
+
# @param [ Document ] doc The document to delete.
|
|
139
|
+
#
|
|
140
|
+
# @since 3.0.10
|
|
141
|
+
def destroy_document(relation, doc)
|
|
142
|
+
relation.delete(doc)
|
|
143
|
+
doc.destroy unless doc.embedded? || doc.destroyed?
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Update the document.
|
|
147
|
+
#
|
|
148
|
+
# @api private
|
|
149
|
+
#
|
|
150
|
+
# @example Update the document.
|
|
151
|
+
# builder.update_document(doc, {}, options)
|
|
152
|
+
#
|
|
153
|
+
# @param [ Document ] doc The document to update.
|
|
154
|
+
# @param [ Hash ] attrs The attributes.
|
|
155
|
+
#
|
|
156
|
+
# @since 3.0.10
|
|
157
|
+
def update_document(doc, attrs)
|
|
158
|
+
attrs.delete_id
|
|
159
|
+
if association.embedded?
|
|
160
|
+
doc.assign_attributes(attrs)
|
|
161
|
+
else
|
|
162
|
+
doc.update_attributes(attrs)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Update nested relation.
|
|
167
|
+
#
|
|
168
|
+
# @api private
|
|
169
|
+
#
|
|
170
|
+
# @example Update nested relation.
|
|
171
|
+
# builder.update_nested_relation(parent, id, attrs)
|
|
172
|
+
#
|
|
173
|
+
# @param [ Document ] parent The parent document.
|
|
174
|
+
# @param [ String, BSON::ObjectId ] id of the related document.
|
|
175
|
+
# @param [ Hash ] attrs The single document attributes to process.
|
|
176
|
+
#
|
|
177
|
+
# @since 6.0.0
|
|
178
|
+
def update_nested_relation(parent, id, attrs)
|
|
179
|
+
first = existing.first
|
|
180
|
+
converted = first ? convert_id(first.class, id) : id
|
|
181
|
+
|
|
182
|
+
if existing.where(id: converted).exists?
|
|
183
|
+
# document exists in relation
|
|
184
|
+
doc = existing.find(converted)
|
|
185
|
+
if destroyable?(attrs)
|
|
186
|
+
destroy(parent, existing, doc)
|
|
187
|
+
else
|
|
188
|
+
update_document(doc, attrs)
|
|
189
|
+
end
|
|
190
|
+
else
|
|
191
|
+
# push existing document to relation
|
|
192
|
+
doc = existing.unscoped.find(converted)
|
|
193
|
+
update_document(doc, attrs)
|
|
194
|
+
existing.push(doc) unless destroyable?(attrs)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Mongoid
|
|
2
|
+
module Association
|
|
3
|
+
module Nested
|
|
4
|
+
module Buildable
|
|
5
|
+
|
|
6
|
+
attr_accessor :attributes, :existing, :association, :options
|
|
7
|
+
|
|
8
|
+
# Determines if destroys are allowed for this document.
|
|
9
|
+
#
|
|
10
|
+
# @example Do we allow a destroy?
|
|
11
|
+
# builder.allow_destroy?
|
|
12
|
+
#
|
|
13
|
+
# @return [ true, false ] True if the allow destroy option was set.
|
|
14
|
+
#
|
|
15
|
+
# @since 2.0.0.rc.1
|
|
16
|
+
def allow_destroy?
|
|
17
|
+
options[:allow_destroy] || false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the reject if option defined with the macro.
|
|
21
|
+
#
|
|
22
|
+
# @example Is there a reject proc?
|
|
23
|
+
# builder.reject?
|
|
24
|
+
#
|
|
25
|
+
# @param [ Document ] document The parent document of the relation
|
|
26
|
+
# @param [ Hash ] attrs The attributes to check for rejection.
|
|
27
|
+
#
|
|
28
|
+
# @return [ true, false ] True and call proc or method if rejectable, false if not.
|
|
29
|
+
#
|
|
30
|
+
# @since 2.0.0.rc.1
|
|
31
|
+
def reject?(document, attrs)
|
|
32
|
+
case callback = options[:reject_if]
|
|
33
|
+
when Symbol
|
|
34
|
+
document.method(callback).arity == 0 ? document.send(callback) : document.send(callback, attrs)
|
|
35
|
+
when Proc
|
|
36
|
+
callback.call(attrs)
|
|
37
|
+
else
|
|
38
|
+
false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Determines if only updates can occur. Only valid for one-to-one
|
|
43
|
+
# relations.
|
|
44
|
+
#
|
|
45
|
+
# @example Is this update only?
|
|
46
|
+
# builder.update_only?
|
|
47
|
+
#
|
|
48
|
+
# @return [ true, false ] True if the update_only option was set.
|
|
49
|
+
#
|
|
50
|
+
# @since 2.0.0.rc.1
|
|
51
|
+
def update_only?
|
|
52
|
+
options[:update_only] || false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Convert an id to its appropriate type.
|
|
56
|
+
#
|
|
57
|
+
# @example Convert the id.
|
|
58
|
+
# builder.convert_id(Person, "4d371b444835d98b8b000010")
|
|
59
|
+
#
|
|
60
|
+
# @param [ Class ] klass The class we're trying to convert for.
|
|
61
|
+
# @param [ String ] id The id, usually coming from the form.
|
|
62
|
+
#
|
|
63
|
+
# @return [ BSON::ObjectId, String, Object ] The converted id.
|
|
64
|
+
#
|
|
65
|
+
# @since 2.0.0.rc.6
|
|
66
|
+
def convert_id(klass, id)
|
|
67
|
+
klass.using_object_ids? ? BSON::ObjectId.mongoize(id) : id
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|