mongoid-multi-db 3.0.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/CHANGELOG.md +615 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +49 -0
- data/lib/config/locales/bg.yml +54 -0
- data/lib/config/locales/de.yml +54 -0
- data/lib/config/locales/en-GB.yml +55 -0
- data/lib/config/locales/en.yml +55 -0
- data/lib/config/locales/es.yml +52 -0
- data/lib/config/locales/fr.yml +55 -0
- data/lib/config/locales/hi.yml +46 -0
- data/lib/config/locales/hu.yml +57 -0
- data/lib/config/locales/id.yml +55 -0
- data/lib/config/locales/it.yml +52 -0
- data/lib/config/locales/ja.yml +50 -0
- data/lib/config/locales/kr.yml +47 -0
- data/lib/config/locales/nl.yml +52 -0
- data/lib/config/locales/pl.yml +52 -0
- data/lib/config/locales/pt-BR.yml +53 -0
- data/lib/config/locales/pt.yml +53 -0
- data/lib/config/locales/ro.yml +59 -0
- data/lib/config/locales/ru.yml +54 -0
- data/lib/config/locales/sv.yml +53 -0
- data/lib/config/locales/vi.yml +55 -0
- data/lib/config/locales/zh-CN.yml +46 -0
- data/lib/mongoid.rb +148 -0
- data/lib/mongoid/atomic.rb +230 -0
- data/lib/mongoid/atomic/modifiers.rb +243 -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 +234 -0
- data/lib/mongoid/attributes/processing.rb +146 -0
- data/lib/mongoid/callbacks.rb +135 -0
- data/lib/mongoid/collection.rb +153 -0
- data/lib/mongoid/collection_proxy.rb +59 -0
- data/lib/mongoid/collections.rb +120 -0
- data/lib/mongoid/collections/master.rb +45 -0
- data/lib/mongoid/collections/operations.rb +44 -0
- data/lib/mongoid/collections/retry.rb +46 -0
- data/lib/mongoid/components.rb +96 -0
- data/lib/mongoid/config.rb +347 -0
- data/lib/mongoid/config/database.rb +186 -0
- data/lib/mongoid/config/replset_database.rb +82 -0
- data/lib/mongoid/connection_proxy.rb +30 -0
- data/lib/mongoid/contexts.rb +25 -0
- data/lib/mongoid/contexts/enumerable.rb +288 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +409 -0
- data/lib/mongoid/copyable.rb +48 -0
- data/lib/mongoid/criteria.rb +418 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +84 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +305 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +232 -0
- data/lib/mongoid/criterion/selector.rb +153 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/database_proxy.rb +97 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +110 -0
- data/lib/mongoid/document.rb +280 -0
- data/lib/mongoid/errors.rb +17 -0
- data/lib/mongoid/errors/callback.rb +26 -0
- data/lib/mongoid/errors/document_not_found.rb +28 -0
- data/lib/mongoid/errors/eager_load.rb +25 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_database.rb +19 -0
- data/lib/mongoid/errors/invalid_field.rb +18 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_time.rb +25 -0
- data/lib/mongoid/errors/invalid_type.rb +25 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +26 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +20 -0
- data/lib/mongoid/errors/validations.rb +23 -0
- data/lib/mongoid/extensions.rb +82 -0
- data/lib/mongoid/extensions/array/deletion.rb +29 -0
- data/lib/mongoid/extensions/false_class/equality.rb +26 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
- data/lib/mongoid/extensions/hash/scoping.rb +25 -0
- data/lib/mongoid/extensions/integer/checks.rb +23 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
- data/lib/mongoid/extensions/object/checks.rb +29 -0
- data/lib/mongoid/extensions/object/reflections.rb +48 -0
- data/lib/mongoid/extensions/object/substitutable.rb +15 -0
- data/lib/mongoid/extensions/object/yoda.rb +44 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
- data/lib/mongoid/extensions/proc/scoping.rb +25 -0
- data/lib/mongoid/extensions/string/checks.rb +36 -0
- data/lib/mongoid/extensions/string/conversions.rb +22 -0
- data/lib/mongoid/extensions/string/inflections.rb +118 -0
- data/lib/mongoid/extensions/symbol/checks.rb +23 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
- data/lib/mongoid/extensions/true_class/equality.rb +26 -0
- data/lib/mongoid/extras.rb +31 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +332 -0
- data/lib/mongoid/fields/mappings.rb +41 -0
- data/lib/mongoid/fields/serializable.rb +201 -0
- data/lib/mongoid/fields/serializable/array.rb +49 -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 +43 -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 +32 -0
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
- data/lib/mongoid/fields/serializable/hash.rb +11 -0
- data/lib/mongoid/fields/serializable/integer.rb +44 -0
- data/lib/mongoid/fields/serializable/localized.rb +41 -0
- data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
- data/lib/mongoid/fields/serializable/object.rb +11 -0
- data/lib/mongoid/fields/serializable/object_id.rb +31 -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 +27 -0
- data/lib/mongoid/fields/serializable/symbol.rb +27 -0
- data/lib/mongoid/fields/serializable/time.rb +23 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
- data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
- data/lib/mongoid/finders.rb +152 -0
- data/lib/mongoid/hierarchy.rb +120 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/identity_map.rb +119 -0
- data/lib/mongoid/indexes.rb +54 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +20 -0
- data/lib/mongoid/javascript/functions.yml +63 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +144 -0
- data/lib/mongoid/logger.rb +39 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +21 -0
- data/lib/mongoid/matchers/and.rb +30 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +23 -0
- data/lib/mongoid/matchers/gt.rb +21 -0
- data/lib/mongoid/matchers/gte.rb +21 -0
- data/lib/mongoid/matchers/in.rb +21 -0
- data/lib/mongoid/matchers/lt.rb +21 -0
- data/lib/mongoid/matchers/lte.rb +21 -0
- data/lib/mongoid/matchers/ne.rb +21 -0
- data/lib/mongoid/matchers/nin.rb +21 -0
- data/lib/mongoid/matchers/or.rb +33 -0
- data/lib/mongoid/matchers/size.rb +21 -0
- data/lib/mongoid/matchers/strategies.rb +93 -0
- data/lib/mongoid/multi_database.rb +31 -0
- data/lib/mongoid/multi_parameter_attributes.rb +106 -0
- data/lib/mongoid/named_scope.rb +146 -0
- data/lib/mongoid/nested_attributes.rb +54 -0
- data/lib/mongoid/observer.rb +170 -0
- data/lib/mongoid/paranoia.rb +158 -0
- data/lib/mongoid/persistence.rb +264 -0
- data/lib/mongoid/persistence/atomic.rb +223 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
- data/lib/mongoid/persistence/atomic/bit.rb +37 -0
- data/lib/mongoid/persistence/atomic/inc.rb +31 -0
- data/lib/mongoid/persistence/atomic/operation.rb +85 -0
- 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 +34 -0
- data/lib/mongoid/persistence/atomic/push.rb +31 -0
- data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
- data/lib/mongoid/persistence/atomic/rename.rb +31 -0
- data/lib/mongoid/persistence/atomic/sets.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 +211 -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 +64 -0
- data/lib/mongoid/railtie.rb +126 -0
- data/lib/mongoid/railties/database.rake +182 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +144 -0
- data/lib/mongoid/relations/accessors.rb +138 -0
- data/lib/mongoid/relations/auto_save.rb +38 -0
- data/lib/mongoid/relations/binding.rb +26 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +83 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +56 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +26 -0
- data/lib/mongoid/relations/cascading/nullify.rb +18 -0
- data/lib/mongoid/relations/cascading/strategy.rb +26 -0
- data/lib/mongoid/relations/constraint.rb +42 -0
- data/lib/mongoid/relations/conversions.rb +35 -0
- data/lib/mongoid/relations/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +89 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/in.rb +220 -0
- data/lib/mongoid/relations/embedded/many.rb +560 -0
- data/lib/mongoid/relations/embedded/one.rb +206 -0
- data/lib/mongoid/relations/embedded/sort.rb +31 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +135 -0
- data/lib/mongoid/relations/metadata.rb +919 -0
- data/lib/mongoid/relations/nested_builder.rb +75 -0
- data/lib/mongoid/relations/one.rb +36 -0
- data/lib/mongoid/relations/options.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +40 -0
- data/lib/mongoid/relations/proxy.rb +145 -0
- data/lib/mongoid/relations/referenced/batch.rb +72 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +262 -0
- data/lib/mongoid/relations/referenced/many.rb +623 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +272 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +153 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +372 -0
- data/lib/mongoid/reloading.rb +91 -0
- data/lib/mongoid/safety.rb +105 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +134 -0
- data/lib/mongoid/sharding.rb +61 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +530 -0
- data/lib/mongoid/threaded/lifecycle.rb +192 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +24 -0
- data/lib/mongoid/timestamps/timeless.rb +50 -0
- data/lib/mongoid/timestamps/updated.rb +26 -0
- data/lib/mongoid/validations.rb +140 -0
- data/lib/mongoid/validations/associated.rb +46 -0
- data/lib/mongoid/validations/uniqueness.rb +145 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +185 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
- data/lib/rails/generators/mongoid_generator.rb +70 -0
- data/lib/rails/mongoid.rb +91 -0
- metadata +465 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/atomic/paths/embedded/one"
|
3
|
+
require "mongoid/atomic/paths/embedded/many"
|
4
|
+
|
5
|
+
module Mongoid #:nodoc:
|
6
|
+
module Atomic #:nodoc:
|
7
|
+
module Paths #:nodoc:
|
8
|
+
|
9
|
+
# Common functionality between the two different embedded paths.
|
10
|
+
module Embedded
|
11
|
+
|
12
|
+
attr_reader :delete_modifier, :document, :insert_modifier, :parent
|
13
|
+
|
14
|
+
# Get the path to the document in the hierarchy.
|
15
|
+
#
|
16
|
+
# @example Get the path.
|
17
|
+
# many.path
|
18
|
+
#
|
19
|
+
# @return [ String ] The path to the document.
|
20
|
+
#
|
21
|
+
# @since 2.1.0
|
22
|
+
def path
|
23
|
+
position.sub(/\.\d+$/, "")
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get the selector to use for the root document when performing atomic
|
27
|
+
# updates. When sharding this will include the shard key.
|
28
|
+
#
|
29
|
+
# @example Get the selector.
|
30
|
+
# many.selector
|
31
|
+
#
|
32
|
+
# @return [ Hash ] The selector to identify the document with.
|
33
|
+
#
|
34
|
+
# @since 2.1.0
|
35
|
+
def selector
|
36
|
+
parent.atomic_selector.
|
37
|
+
merge!({ "#{path}._id" => document.identifier || document._id }).
|
38
|
+
merge!(document.shard_key_selector)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Atomic #:nodoc:
|
4
|
+
module Paths #:nodoc:
|
5
|
+
module Embedded #:nodoc:
|
6
|
+
|
7
|
+
# This class encapsulates behaviour for locating and updating
|
8
|
+
# documents that are defined as an embedded 1-n.
|
9
|
+
class Many
|
10
|
+
include Embedded
|
11
|
+
|
12
|
+
# Create the new path utility.
|
13
|
+
#
|
14
|
+
# @example Create the path util.
|
15
|
+
# Many.new(document)
|
16
|
+
#
|
17
|
+
# @param [ Document ] document The document to generate the paths for.
|
18
|
+
#
|
19
|
+
# @since 2.1.0
|
20
|
+
def initialize(document)
|
21
|
+
@document, @parent = document, document._parent
|
22
|
+
@insert_modifier, @delete_modifier ="$push", "$pull"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get the position of the document in the hierarchy. This will
|
26
|
+
# include indexes of 1-n embedded relations that may sit above the
|
27
|
+
# embedded many.
|
28
|
+
#
|
29
|
+
# @example Get the position.
|
30
|
+
# many.position
|
31
|
+
#
|
32
|
+
# @return [ String ] The position of the document.
|
33
|
+
#
|
34
|
+
# @since 2.1.0
|
35
|
+
def position
|
36
|
+
pos = parent.atomic_position
|
37
|
+
locator = document.new? ? "" : ".#{document._index}"
|
38
|
+
"#{pos}#{"." unless pos.blank?}#{document.metadata.name}#{locator}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Atomic #:nodoc:
|
4
|
+
module Paths #:nodoc:
|
5
|
+
module Embedded #:nodoc:
|
6
|
+
|
7
|
+
# This class encapsulates behaviour for locating and updating
|
8
|
+
# documents that are defined as an embedded 1-1.
|
9
|
+
class One
|
10
|
+
include Embedded
|
11
|
+
|
12
|
+
# Create the new path utility.
|
13
|
+
#
|
14
|
+
# @example Create the path util.
|
15
|
+
# One.new(document)
|
16
|
+
#
|
17
|
+
# @param [ Document ] document The document to generate the paths for.
|
18
|
+
#
|
19
|
+
# @since 2.1.0
|
20
|
+
def initialize(document)
|
21
|
+
@document, @parent = document, document._parent
|
22
|
+
@insert_modifier, @delete_modifier ="$set", "$unset"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get the position of the document in the hierarchy. This will
|
26
|
+
# include indexes of 1-n embedded relations that may sit above the
|
27
|
+
# embedded one.
|
28
|
+
#
|
29
|
+
# @example Get the position.
|
30
|
+
# one.position
|
31
|
+
#
|
32
|
+
# @return [ String ] The position of the document.
|
33
|
+
#
|
34
|
+
# @since 2.1.0
|
35
|
+
def position
|
36
|
+
pos = parent.atomic_position
|
37
|
+
"#{pos}#{"." unless pos.blank?}#{document.metadata.name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Atomic #:nodoc:
|
4
|
+
module Paths #:nodoc:
|
5
|
+
|
6
|
+
# This class encapsulates behaviour for locating and updating root
|
7
|
+
# documents atomically.
|
8
|
+
class Root
|
9
|
+
|
10
|
+
attr_reader :document, :path, :position
|
11
|
+
|
12
|
+
# Create the new root path utility.
|
13
|
+
#
|
14
|
+
# @example Create the root path util.
|
15
|
+
# Root.new(document)
|
16
|
+
#
|
17
|
+
# @param [ Document ] document The document to generate the paths for.
|
18
|
+
#
|
19
|
+
# @since 2.1.0
|
20
|
+
def initialize(document)
|
21
|
+
@document, @path, @position = document, "", ""
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the selector to use for the root document when performing atomic
|
25
|
+
# updates. When sharding this will include the shard key.
|
26
|
+
#
|
27
|
+
# @example Get the selector.
|
28
|
+
# root.selector
|
29
|
+
#
|
30
|
+
# @return [ Hash ] The selector to identify the document with.
|
31
|
+
#
|
32
|
+
# @since 2.1.0
|
33
|
+
def selector
|
34
|
+
{ "_id" => document.identifier || document._id }.
|
35
|
+
merge!(document.shard_key_selector)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/attributes/processing"
|
3
|
+
|
4
|
+
module Mongoid #:nodoc:
|
5
|
+
|
6
|
+
# This module contains the logic for handling the internal attributes hash,
|
7
|
+
# and how to get and set values.
|
8
|
+
module Attributes
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
include Processing
|
11
|
+
|
12
|
+
attr_reader :attributes
|
13
|
+
alias :raw_attributes :attributes
|
14
|
+
|
15
|
+
# Determine if an attribute is present.
|
16
|
+
#
|
17
|
+
# @example Is the attribute present?
|
18
|
+
# person.attribute_present?("title")
|
19
|
+
#
|
20
|
+
# @param [ String, Symbol ] name The name of the attribute.
|
21
|
+
#
|
22
|
+
# @return [ true, false ] True if present, false if not.
|
23
|
+
#
|
24
|
+
# @since 1.0.0
|
25
|
+
def attribute_present?(name)
|
26
|
+
attribute = read_attribute(name)
|
27
|
+
! attribute.blank? || attribute == false
|
28
|
+
end
|
29
|
+
alias :has_attribute? :attribute_present?
|
30
|
+
|
31
|
+
# Read a value from the document attributes. If the value does not exist
|
32
|
+
# it will return nil.
|
33
|
+
#
|
34
|
+
# @example Read an attribute.
|
35
|
+
# person.read_attribute(:title)
|
36
|
+
#
|
37
|
+
# @example Read an attribute (alternate syntax.)
|
38
|
+
# person[:title]
|
39
|
+
#
|
40
|
+
# @param [ String, Symbol ] name The name of the attribute to get.
|
41
|
+
#
|
42
|
+
# @return [ Object ] The value of the attribute.
|
43
|
+
#
|
44
|
+
# @since 1.0.0
|
45
|
+
def read_attribute(name)
|
46
|
+
attributes[name.to_s]
|
47
|
+
end
|
48
|
+
alias :[] :read_attribute
|
49
|
+
|
50
|
+
# Remove a value from the +Document+ attributes. If the value does not exist
|
51
|
+
# it will fail gracefully.
|
52
|
+
#
|
53
|
+
# @example Remove the attribute.
|
54
|
+
# person.remove_attribute(:title)
|
55
|
+
#
|
56
|
+
# @param [ String, Symbol ] name The name of the attribute to remove.
|
57
|
+
#
|
58
|
+
# @since 1.0.0
|
59
|
+
def remove_attribute(name)
|
60
|
+
_assigning do
|
61
|
+
access = name.to_s
|
62
|
+
attribute_will_change!(access)
|
63
|
+
attributes.delete(access)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Override respond_to? so it responds properly for dynamic attributes.
|
68
|
+
#
|
69
|
+
# @example Does this object respond to the method?
|
70
|
+
# person.respond_to?(:title)
|
71
|
+
#
|
72
|
+
# @param [ Array ] *args The name of the method.
|
73
|
+
#
|
74
|
+
# @return [ true, false ] True if it does, false if not.
|
75
|
+
#
|
76
|
+
# @since 1.0.0
|
77
|
+
def respond_to?(*args)
|
78
|
+
(Mongoid.allow_dynamic_fields &&
|
79
|
+
attributes &&
|
80
|
+
attributes.has_key?(args.first.to_s)
|
81
|
+
) || super
|
82
|
+
end
|
83
|
+
|
84
|
+
# Write a single attribute to the document attribute hash. This will
|
85
|
+
# also fire the before and after update callbacks, and perform any
|
86
|
+
# necessary typecasting.
|
87
|
+
#
|
88
|
+
# @example Write the attribute.
|
89
|
+
# person.write_attribute(:title, "Mr.")
|
90
|
+
#
|
91
|
+
# @example Write the attribute (alternate syntax.)
|
92
|
+
# person[:title] = "Mr."
|
93
|
+
#
|
94
|
+
# @param [ String, Symbol ] name The name of the attribute to update.
|
95
|
+
# @param [ Object ] value The value to set for the attribute.
|
96
|
+
#
|
97
|
+
# @since 1.0.0
|
98
|
+
def write_attribute(name, value)
|
99
|
+
_assigning do
|
100
|
+
access = name.to_s
|
101
|
+
localized = fields[access].try(:localized?)
|
102
|
+
typed_value_for(access, value).tap do |value|
|
103
|
+
unless attributes[access] == value || attribute_changed?(access)
|
104
|
+
attribute_will_change!(access)
|
105
|
+
end
|
106
|
+
if localized
|
107
|
+
(attributes[access] ||= {}).merge!(value)
|
108
|
+
else
|
109
|
+
attributes[access] = value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
alias :[]= :write_attribute
|
115
|
+
|
116
|
+
# Allows you to set all the attributes for a particular mass-assignment security role
|
117
|
+
# by passing in a hash of attributes with keys matching the attribute names
|
118
|
+
# (which again matches the column names) and the role name using the :as option.
|
119
|
+
# To bypass mass-assignment security you can use the :without_protection => true option.
|
120
|
+
#
|
121
|
+
# @example Assign the attributes.
|
122
|
+
# person.assign_attributes(:title => "Mr.")
|
123
|
+
#
|
124
|
+
# @example Assign the attributes (with a role).
|
125
|
+
# person.assign_attributes({ :title => "Mr." }, :as => :admin)
|
126
|
+
#
|
127
|
+
# @param [ Hash ] attrs The new attributes to set.
|
128
|
+
# @param [ Hash ] options Supported options: :without_protection, :as
|
129
|
+
#
|
130
|
+
# @since 2.2.1
|
131
|
+
def assign_attributes(attrs = nil, options = {})
|
132
|
+
_assigning do
|
133
|
+
process(attrs, options[:as] || :default, !options[:without_protection]) do |document|
|
134
|
+
document.identify if new? && id.blank?
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Writes the supplied attributes hash to the document. This will only
|
140
|
+
# overwrite existing attributes if they are present in the new +Hash+, all
|
141
|
+
# others will be preserved.
|
142
|
+
#
|
143
|
+
# @example Write the attributes.
|
144
|
+
# person.write_attributes(:title => "Mr.")
|
145
|
+
#
|
146
|
+
# @example Write the attributes (alternate syntax.)
|
147
|
+
# person.attributes = { :title => "Mr." }
|
148
|
+
#
|
149
|
+
# @param [ Hash ] attrs The new attributes to set.
|
150
|
+
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
151
|
+
#
|
152
|
+
# @since 1.0.0
|
153
|
+
def write_attributes(attrs = nil, guard_protected_attributes = true)
|
154
|
+
assign_attributes(attrs, :without_protection => !guard_protected_attributes)
|
155
|
+
end
|
156
|
+
alias :attributes= :write_attributes
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
# Set any missing default values in the attributes.
|
161
|
+
#
|
162
|
+
# @example Get the raw attributes after defaults have been applied.
|
163
|
+
# person.apply_defaults
|
164
|
+
#
|
165
|
+
# @return [ Hash ] The raw attributes.
|
166
|
+
#
|
167
|
+
# @since 2.0.0.rc.8
|
168
|
+
def apply_defaults
|
169
|
+
defaults.each do |name|
|
170
|
+
unless attributes.has_key?(name)
|
171
|
+
if field = fields[name]
|
172
|
+
attributes[name] = field.eval_default(self)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Used for allowing accessor methods for dynamic attributes.
|
179
|
+
#
|
180
|
+
# @param [ String, Symbol ] name The name of the method.
|
181
|
+
# @param [ Array ] *args The arguments to the method.
|
182
|
+
def method_missing(name, *args)
|
183
|
+
attr = name.to_s
|
184
|
+
return super unless attributes.has_key?(attr.reader)
|
185
|
+
if attr.writer?
|
186
|
+
write_attribute(attr.reader, (args.size > 1) ? args : args.first)
|
187
|
+
else
|
188
|
+
read_attribute(attr.reader)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Return the typecasted value for a field.
|
193
|
+
#
|
194
|
+
# @example Get the value typecasted.
|
195
|
+
# person.typed_value_for(:title, :sir)
|
196
|
+
#
|
197
|
+
# @param [ String, Symbol ] key The field name.
|
198
|
+
# @param [ Object ] value The uncast value.
|
199
|
+
#
|
200
|
+
# @return [ Object ] The cast value.
|
201
|
+
#
|
202
|
+
# @since 1.0.0
|
203
|
+
def typed_value_for(key, value)
|
204
|
+
fields.has_key?(key) ? fields[key].serialize(value) : value
|
205
|
+
end
|
206
|
+
|
207
|
+
module ClassMethods #:nodoc:
|
208
|
+
|
209
|
+
# Alias the provided name to the original field. This will provide an
|
210
|
+
# aliased getter, setter, existance check, and all dirty attribute
|
211
|
+
# methods.
|
212
|
+
#
|
213
|
+
# @example Alias the attribute.
|
214
|
+
# class Product
|
215
|
+
# include Mongoid::Document
|
216
|
+
# field :price, :type => Float
|
217
|
+
# alias_attribute :cost, :price
|
218
|
+
# end
|
219
|
+
#
|
220
|
+
# @param [ Symbol ] name The new name.
|
221
|
+
# @param [ Symbol ] original The original name.
|
222
|
+
#
|
223
|
+
# @since 2.3.0
|
224
|
+
def alias_attribute(name, original)
|
225
|
+
class_eval <<-RUBY
|
226
|
+
alias :#{name} :#{original}
|
227
|
+
alias :#{name}= :#{original}=
|
228
|
+
alias :#{name}? :#{original}?
|
229
|
+
RUBY
|
230
|
+
super
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Attributes #:nodoc:
|
4
|
+
|
5
|
+
# This module contains the behavior for processing attributes.
|
6
|
+
module Processing
|
7
|
+
|
8
|
+
# Process the provided attributes casting them to their proper values if a
|
9
|
+
# field exists for them on the document. This will be limited to only the
|
10
|
+
# attributes provided in the suppied +Hash+ so that no extra nil values get
|
11
|
+
# put into the document's attributes.
|
12
|
+
#
|
13
|
+
# @example Process the attributes.
|
14
|
+
# person.process(:title => "sir", :age => 40)
|
15
|
+
#
|
16
|
+
# @param [ Hash ] attrs The attributes to set.
|
17
|
+
# @param [ Symbol ] role A role for scoped mass assignment.
|
18
|
+
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
19
|
+
#
|
20
|
+
# @since 2.0.0.rc.7
|
21
|
+
def process(attrs = nil, role = :default, guard_protected_attributes = true)
|
22
|
+
attrs ||= {}
|
23
|
+
attrs = sanitize_for_mass_assignment(attrs, role) if guard_protected_attributes
|
24
|
+
attrs.each_pair do |key, value|
|
25
|
+
next if pending_attribute?(key, value)
|
26
|
+
process_attribute(key, value)
|
27
|
+
end
|
28
|
+
yield self if block_given?
|
29
|
+
process_pending
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
# If the key provided is the name of a relation or a nested attribute, we
|
35
|
+
# need to wait until all other attributes are set before processing
|
36
|
+
# these.
|
37
|
+
#
|
38
|
+
# @example Is the attribute pending?
|
39
|
+
# document.pending_attribute?(:name, "Durran")
|
40
|
+
#
|
41
|
+
# @param [ Symbol ] key The name of the attribute.
|
42
|
+
# @param [ Object ] value The value of the attribute.
|
43
|
+
#
|
44
|
+
# @return [ true, false ] True if pending, false if not.
|
45
|
+
#
|
46
|
+
# @since 2.0.0.rc.7
|
47
|
+
def pending_attribute?(key, value)
|
48
|
+
name = key.to_s
|
49
|
+
if relations.has_key?(name)
|
50
|
+
pending_relations[name] = value
|
51
|
+
return true
|
52
|
+
end
|
53
|
+
if nested_attributes.include?("#{name}=")
|
54
|
+
pending_nested[name] = value
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get all the pending relations that need to be set.
|
61
|
+
#
|
62
|
+
# @example Get the pending relations.
|
63
|
+
# document.pending_relations
|
64
|
+
#
|
65
|
+
# @return [ Hash ] The pending relations in key/value pairs.
|
66
|
+
#
|
67
|
+
# @since 2.0.0.rc.7
|
68
|
+
def pending_relations
|
69
|
+
@pending_relations ||= {}
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get all the pending nested attributes that need to be set.
|
73
|
+
#
|
74
|
+
# @example Get the pending nested attributes.
|
75
|
+
# document.pending_nested
|
76
|
+
#
|
77
|
+
# @return [ Hash ] The pending nested attributes in key/value pairs.
|
78
|
+
#
|
79
|
+
# @since 2.0.0.rc.7
|
80
|
+
def pending_nested
|
81
|
+
@pending_nested ||= {}
|
82
|
+
end
|
83
|
+
|
84
|
+
# If the attribute is dynamic, add a field for it with a type of object
|
85
|
+
# and then either way set the value.
|
86
|
+
#
|
87
|
+
# @example Process the attribute.
|
88
|
+
# document.process_attribute(name, value)
|
89
|
+
#
|
90
|
+
# @param [ Symbol ] name The name of the field.
|
91
|
+
# @param [ Object ] value The value of the field.
|
92
|
+
#
|
93
|
+
# @since 2.0.0.rc.7
|
94
|
+
def process_attribute(name, value)
|
95
|
+
if Mongoid.allow_dynamic_fields && !respond_to?("#{name}=")
|
96
|
+
write_attribute(name, value)
|
97
|
+
else
|
98
|
+
send("#{name}=", value)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Process all the pending nested attributes that needed to wait until
|
103
|
+
# ids were set to fire off.
|
104
|
+
#
|
105
|
+
# @example Process the nested attributes.
|
106
|
+
# document.process_nested
|
107
|
+
#
|
108
|
+
# @since 2.0.0.rc.7
|
109
|
+
def process_nested
|
110
|
+
pending_nested.each_pair do |name, value|
|
111
|
+
send("#{name}=", value)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Process all the pending items, then clear them out.
|
116
|
+
#
|
117
|
+
# @example Process the pending items.
|
118
|
+
# document.process_pending
|
119
|
+
#
|
120
|
+
# @since 2.0.0.rc.7
|
121
|
+
def process_pending
|
122
|
+
process_nested and process_relations
|
123
|
+
pending_nested.clear and pending_relations.clear
|
124
|
+
end
|
125
|
+
|
126
|
+
# Process all the pending relations that needed to wait until ids were set
|
127
|
+
# to fire off.
|
128
|
+
#
|
129
|
+
# @example Process the relations.
|
130
|
+
# document.process_relations
|
131
|
+
#
|
132
|
+
# @since 2.0.0.rc.7
|
133
|
+
def process_relations
|
134
|
+
pending_relations.each_pair do |name, value|
|
135
|
+
metadata = relations[name]
|
136
|
+
if value.is_a?(Hash)
|
137
|
+
metadata.nested_builder(value, {}).build(self)
|
138
|
+
else
|
139
|
+
send("#{name}=", value)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|