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,97 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'mongoid/collection_proxy'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Proxy that enables runtime swapping of a MongoDB database, as it
|
6
|
+
# appears to be cached at several points within Mongoid.
|
7
|
+
#
|
8
|
+
# This proxy is generated by the ConnectionProxy when asked for a
|
9
|
+
# specific database.
|
10
|
+
#
|
11
|
+
class DatabaseProxy
|
12
|
+
#
|
13
|
+
# Semaphore for preventing badness when multithreading.
|
14
|
+
#
|
15
|
+
@mutex = Mutex.new
|
16
|
+
|
17
|
+
#
|
18
|
+
# All connections that we know about, and then the databases tied to
|
19
|
+
# them get stored in here.
|
20
|
+
#
|
21
|
+
@pool = Hash.new
|
22
|
+
|
23
|
+
#
|
24
|
+
# Accessor for class-level instance variable that holds all the
|
25
|
+
# connection-database pairs that we know about, so that we can
|
26
|
+
# switch all of them globally.
|
27
|
+
#
|
28
|
+
def DatabaseProxy.pool
|
29
|
+
@pool
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Global mutex... for great thread safety!
|
34
|
+
#
|
35
|
+
def DatabaseProxy.mutex
|
36
|
+
@mutex
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Set our default connection and name.
|
41
|
+
#
|
42
|
+
def initialize(connection, name)
|
43
|
+
@connection = connection
|
44
|
+
switch(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Convenience method for synchronizing threads.
|
49
|
+
#
|
50
|
+
def synchronize(&block)
|
51
|
+
DatabaseProxy.mutex.synchronize(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Switch to a different database on the same connection.
|
56
|
+
#
|
57
|
+
def switch(name)
|
58
|
+
synchronize do
|
59
|
+
# Connect to the cached database if available.
|
60
|
+
pool = (DatabaseProxy.pool[@connection] ||= {})
|
61
|
+
database = (pool[name] || (pool[name] = @connection.db(name)))
|
62
|
+
|
63
|
+
# Set the default if we haven't, and away we go (for this
|
64
|
+
# thread only).
|
65
|
+
@default ||= database
|
66
|
+
Thread.current[:mongo_database] = database
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Resets back to the default database connections.
|
72
|
+
#
|
73
|
+
def reset!
|
74
|
+
synchronize { Thread.current[:mongo_database] = nil }
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Returns the raw Mongo::DB object.
|
79
|
+
#
|
80
|
+
def target
|
81
|
+
synchronize { Thread.current[:mongo_database] || @default }
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Create a proxied collection.
|
86
|
+
#
|
87
|
+
def create_collection(name, opts)
|
88
|
+
CollectionProxy.new(self, name, opts)
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Proxy methods to the correct database.
|
93
|
+
#
|
94
|
+
def method_missing(*args, &block)
|
95
|
+
target.send(*args, &block)
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
|
4
|
+
# This module handles functionality for creating default scopes.
|
5
|
+
module DefaultScope
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class_attribute :default_scoping
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods #:nodoc:
|
13
|
+
|
14
|
+
# Creates a default_scope for the +Document+, similar to ActiveRecord's
|
15
|
+
# default_scope. +DefaultScopes+ are proxied +Criteria+ objects that are
|
16
|
+
# applied by default to all queries for the class.
|
17
|
+
#
|
18
|
+
# @example Create a default scope.
|
19
|
+
#
|
20
|
+
# class Person
|
21
|
+
# include Mongoid::Document
|
22
|
+
# field :active, :type => Boolean
|
23
|
+
# field :count, :type => Integer
|
24
|
+
#
|
25
|
+
# default_scope :where => { :active => true }
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @param [ Hash ] conditions The conditions to create with.
|
29
|
+
#
|
30
|
+
# @since 2.0.0.rc.1
|
31
|
+
def default_scope(conditions = {})
|
32
|
+
self.default_scoping = Scope.new(conditions).conditions.scoped
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Dirty #:nodoc:
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActiveModel::Dirty
|
6
|
+
|
7
|
+
# Call this method after save, so the changes can be properly switched.
|
8
|
+
#
|
9
|
+
# This will unset the memoized children array, set new record to
|
10
|
+
# false, set the document as validated, and move the dirty changes.
|
11
|
+
#
|
12
|
+
# @example Move the changes to previous.
|
13
|
+
# person.move_changes
|
14
|
+
#
|
15
|
+
# @since 2.1.0
|
16
|
+
def move_changes
|
17
|
+
@_children = nil
|
18
|
+
@previously_changed = changes
|
19
|
+
atomic_pulls.clear
|
20
|
+
atomic_unsets.clear
|
21
|
+
delayed_atomic_sets.clear
|
22
|
+
delayed_atomic_pulls.clear
|
23
|
+
changed_attributes.clear
|
24
|
+
end
|
25
|
+
|
26
|
+
# Remove a change from the dirty attributes hash. Used by the single field
|
27
|
+
# atomic updators.
|
28
|
+
#
|
29
|
+
# @example Remove a flagged change.
|
30
|
+
# model.remove_change(:field)
|
31
|
+
#
|
32
|
+
# @param [ Symbol, String ] name The name of the field.
|
33
|
+
#
|
34
|
+
# @since 2.1.0
|
35
|
+
def remove_change(name)
|
36
|
+
changed_attributes.delete(name.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Gets all the new values for each of the changed fields, to be passed to
|
40
|
+
# a MongoDB $set modifier.
|
41
|
+
#
|
42
|
+
# @example Get the setters for the atomic updates.
|
43
|
+
# person = Person.new(:title => "Sir")
|
44
|
+
# person.title = "Madam"
|
45
|
+
# person.setters # returns { "title" => "Madam" }
|
46
|
+
#
|
47
|
+
# @return [ Hash ] A +Hash+ of atomic setters.
|
48
|
+
def setters
|
49
|
+
{}.tap do |modifications|
|
50
|
+
changes.each_pair do |field, changes|
|
51
|
+
if changes
|
52
|
+
key = embedded? ? "#{atomic_position}.#{field}" : field
|
53
|
+
modifications[key] = changes[1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Get the current value for the specified attribute, if the attribute has changed.
|
62
|
+
#
|
63
|
+
# @note This is overriding the AM::Dirty implementation to read from the mongoid
|
64
|
+
# attributes hash, which may contain a serialized version of the attributes data. It is
|
65
|
+
# necessary to read the serialized version as the changed value, to allow updates to
|
66
|
+
# the MongoDB document to persist correctly. For example, if a DateTime field is updated
|
67
|
+
# it must be persisted as a UTC Time.
|
68
|
+
#
|
69
|
+
# @return [ Object ] The current value of the field, or nil if no change made.
|
70
|
+
#
|
71
|
+
# @since 2.1.0
|
72
|
+
def attribute_change(attr)
|
73
|
+
[changed_attributes[attr], attributes[attr]] if attribute_changed?(attr)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Determine if a specific attribute has changed.
|
77
|
+
#
|
78
|
+
# @note Overriding AM::Dirty once again since their implementation is not
|
79
|
+
# friendly to fields that can be changed in place.
|
80
|
+
#
|
81
|
+
# @param [ String ] attr The name of the attribute.
|
82
|
+
#
|
83
|
+
# @return [ true, false ] Whether the attribute has changed.
|
84
|
+
#
|
85
|
+
# @since 2.1.6
|
86
|
+
def attribute_changed?(attr)
|
87
|
+
return false unless changed_attributes.include?(attr)
|
88
|
+
changed_attributes[attr] != attributes[attr]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Override Active Model's behaviour here in order to stay away from
|
92
|
+
# infinite loops on getter/setter overrides.
|
93
|
+
#
|
94
|
+
# @example Flag an attribute as changing.
|
95
|
+
# document.attribute_will_change!(:name)
|
96
|
+
#
|
97
|
+
# @param [ Symbol ] attr The attribute.
|
98
|
+
#
|
99
|
+
# @return [ Object ] The value of the attribute.
|
100
|
+
#
|
101
|
+
# @since 2.3.0
|
102
|
+
def attribute_will_change!(attr)
|
103
|
+
unless changed_attributes.include?(attr)
|
104
|
+
value = read_attribute(attr)
|
105
|
+
value = value.duplicable? ? value.clone : value
|
106
|
+
changed_attributes[attr] = value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
|
4
|
+
# This is the base module for all domain objects that need to be persisted to
|
5
|
+
# the database as documents.
|
6
|
+
module Document
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include Mongoid::Components
|
9
|
+
|
10
|
+
attr_reader :new_record
|
11
|
+
|
12
|
+
# Default comparison is via the string version of the id.
|
13
|
+
#
|
14
|
+
# @example Compare two documents.
|
15
|
+
# person <=> other_person
|
16
|
+
#
|
17
|
+
# @param [ Document ] other The document to compare with.
|
18
|
+
#
|
19
|
+
# @return [ Integer ] -1, 0, 1.
|
20
|
+
def <=>(other)
|
21
|
+
attributes["_id"].to_s <=> other.attributes["_id"].to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
# Performs equality checking on the document ids. For more robust
|
25
|
+
# equality checking please override this method.
|
26
|
+
#
|
27
|
+
# @example Compare for equality.
|
28
|
+
# document == other
|
29
|
+
#
|
30
|
+
# @param [ Document, Object ] other The other object to compare with.
|
31
|
+
#
|
32
|
+
# @return [ true, false ] True if the ids are equal, false if not.
|
33
|
+
def ==(other)
|
34
|
+
self.class == other.class &&
|
35
|
+
attributes["_id"] == other.attributes["_id"]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Performs class equality checking.
|
39
|
+
#
|
40
|
+
# @example Compare the classes.
|
41
|
+
# document === other
|
42
|
+
#
|
43
|
+
# @param [ Document, Object ] other The other object to compare with.
|
44
|
+
#
|
45
|
+
# @return [ true, false ] True if the classes are equal, false if not.
|
46
|
+
def ===(other)
|
47
|
+
other.is_a?(self.class)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Delegates to ==. Used when needing checks in hashes.
|
51
|
+
#
|
52
|
+
# @example Perform equality checking.
|
53
|
+
# document.eql?(other)
|
54
|
+
#
|
55
|
+
# @param [ Document, Object ] other The object to check against.
|
56
|
+
#
|
57
|
+
# @return [ true, false ] True if equal, false if not.
|
58
|
+
def eql?(other)
|
59
|
+
self == (other)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Freezes the internal attributes of the document.
|
63
|
+
#
|
64
|
+
# @example Freeze the document
|
65
|
+
# document.freeze
|
66
|
+
#
|
67
|
+
# @return [ Document ] The document.
|
68
|
+
#
|
69
|
+
# @since 2.0.0
|
70
|
+
def freeze
|
71
|
+
attributes.freeze
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Checks if the document is frozen
|
76
|
+
#
|
77
|
+
# @example Check if frozen
|
78
|
+
# document.frozen?
|
79
|
+
#
|
80
|
+
# @return [ true, false ] True if frozen, else false.
|
81
|
+
#
|
82
|
+
# @since 2.0.0
|
83
|
+
def frozen?
|
84
|
+
raw_attributes.frozen?
|
85
|
+
end
|
86
|
+
|
87
|
+
# Delegates to id in order to allow two records of the same type and id to
|
88
|
+
# work with something like:
|
89
|
+
#
|
90
|
+
# [ Person.find(1), Person.find(2), Person.find(3) ] &
|
91
|
+
# [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
92
|
+
#
|
93
|
+
# @example Get the hash.
|
94
|
+
# document.hash
|
95
|
+
#
|
96
|
+
# @return [ Integer ] The hash of the document's id.
|
97
|
+
def hash
|
98
|
+
raw_attributes["_id"].hash
|
99
|
+
end
|
100
|
+
|
101
|
+
# Generate an id for this +Document+.
|
102
|
+
#
|
103
|
+
# @example Create the id.
|
104
|
+
# person.identify
|
105
|
+
#
|
106
|
+
# @return [ BSON::ObjectId, String ] A newly created id.
|
107
|
+
def identify
|
108
|
+
Identity.new(self).create
|
109
|
+
end
|
110
|
+
|
111
|
+
# Instantiate a new +Document+, setting the Document's attributes if
|
112
|
+
# given. If no attributes are provided, they will be initialized with
|
113
|
+
# an empty +Hash+.
|
114
|
+
#
|
115
|
+
# If a primary key is defined, the document's id will be set to that key,
|
116
|
+
# otherwise it will be set to a fresh +BSON::ObjectId+ string.
|
117
|
+
#
|
118
|
+
# @example Create a new document.
|
119
|
+
# Person.new(:title => "Sir")
|
120
|
+
#
|
121
|
+
# @param [ Hash ] attrs The attributes to set up the document with.
|
122
|
+
# @param [ Hash ] options A mass-assignment protection options. Supports
|
123
|
+
# :as and :without_protection
|
124
|
+
#
|
125
|
+
# @return [ Document ] A new document.
|
126
|
+
def initialize(attrs = nil, options = nil)
|
127
|
+
_building do
|
128
|
+
@new_record = true
|
129
|
+
@attributes ||= {}
|
130
|
+
options ||= {}
|
131
|
+
process(attrs, options[:as] || :default, !options[:without_protection]) do
|
132
|
+
identify
|
133
|
+
apply_defaults
|
134
|
+
yield(self) if block_given?
|
135
|
+
end
|
136
|
+
run_callbacks(:initialize) { self }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Return an array with this +Document+ only in it.
|
141
|
+
#
|
142
|
+
# @example Return the document in an array.
|
143
|
+
# document.to_a
|
144
|
+
#
|
145
|
+
# @return [ Array<Document> ] An array with the document as its only item.
|
146
|
+
def to_a
|
147
|
+
[ self ]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Return a hash of the entire document hierarchy from this document and
|
151
|
+
# below. Used when the attributes are needed for everything and not just
|
152
|
+
# the current document.
|
153
|
+
#
|
154
|
+
# @example Get the full hierarchy.
|
155
|
+
# person.as_document
|
156
|
+
#
|
157
|
+
# @return [ Hash ] A hash of all attributes in the hierarchy.
|
158
|
+
def as_document
|
159
|
+
attributes.tap do |attrs|
|
160
|
+
relations.each_pair do |name, meta|
|
161
|
+
if meta.embedded?
|
162
|
+
relation = send(name)
|
163
|
+
attrs[name] = relation.as_document unless relation.blank?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Returns an instance of the specified class with the attributes
|
170
|
+
# and errors of the current document.
|
171
|
+
#
|
172
|
+
# @example Return a subclass document as a superclass instance.
|
173
|
+
# manager.becomes(Person)
|
174
|
+
#
|
175
|
+
# @raise [ ArgumentError ] If the class doesn't include Mongoid::Document
|
176
|
+
#
|
177
|
+
# @param [ Class ] klass The class to become.
|
178
|
+
#
|
179
|
+
# @return [ Document ] An instance of the specified class.
|
180
|
+
def becomes(klass)
|
181
|
+
unless klass.include?(Mongoid::Document)
|
182
|
+
raise ArgumentError, "A class which includes Mongoid::Document is expected"
|
183
|
+
end
|
184
|
+
klass.instantiate(frozen? ? attributes.dup : attributes).tap do |became|
|
185
|
+
became.instance_variable_set(:@errors, errors)
|
186
|
+
became.instance_variable_set(:@new_record, new_record?)
|
187
|
+
became.instance_variable_set(:@destroyed, destroyed?)
|
188
|
+
became._type = klass.to_s
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
# Returns the logger
|
195
|
+
#
|
196
|
+
# @return [ Logger ] The configured logger or a default Logger instance.
|
197
|
+
#
|
198
|
+
# @since 2.2.0
|
199
|
+
def logger
|
200
|
+
Mongoid.logger
|
201
|
+
end
|
202
|
+
|
203
|
+
# Implement this for calls to flatten on array.
|
204
|
+
#
|
205
|
+
# @example Get the document as an array.
|
206
|
+
# document.to_ary
|
207
|
+
#
|
208
|
+
# @return [ nil ] Always nil.
|
209
|
+
#
|
210
|
+
# @since 2.1.0
|
211
|
+
def to_ary
|
212
|
+
nil
|
213
|
+
end
|
214
|
+
|
215
|
+
module ClassMethods #:nodoc:
|
216
|
+
|
217
|
+
# Performs class equality checking.
|
218
|
+
#
|
219
|
+
# @example Compare the classes.
|
220
|
+
# document === other
|
221
|
+
#
|
222
|
+
# @param [ Document, Object ] other The other object to compare with.
|
223
|
+
#
|
224
|
+
# @return [ true, false ] True if the classes are equal, false if not.
|
225
|
+
#
|
226
|
+
# @since 2.0.0.rc.4
|
227
|
+
def ===(other)
|
228
|
+
self == (other.is_a?(Class) ? other : other.class)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Instantiate a new object, only when loaded from the database or when
|
232
|
+
# the attributes have already been typecast.
|
233
|
+
#
|
234
|
+
# @example Create the document.
|
235
|
+
# Person.instantiate(:title => "Sir", :age => 30)
|
236
|
+
#
|
237
|
+
# @param [ Hash ] attrs The hash of attributes to instantiate with.
|
238
|
+
#
|
239
|
+
# @return [ Document ] A new document.
|
240
|
+
def instantiate(attrs = nil)
|
241
|
+
attributes = attrs || {}
|
242
|
+
allocate.tap do |doc|
|
243
|
+
doc.instance_variable_set(:@attributes, attributes)
|
244
|
+
doc.send(:apply_defaults)
|
245
|
+
IdentityMap.set(doc) unless _loading_revision?
|
246
|
+
doc.run_callbacks(:initialize) { doc }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# Returns all types to query for when using this class as the base.
|
251
|
+
#
|
252
|
+
# @example Get the types.
|
253
|
+
# document._types
|
254
|
+
#
|
255
|
+
# @return [ Array<Class> ] All subclasses of the current document.
|
256
|
+
def _types
|
257
|
+
@_type ||= [descendants + [self]].flatten.uniq.map { |t| t.to_s }
|
258
|
+
end
|
259
|
+
|
260
|
+
# Set the i18n scope to overwrite ActiveModel.
|
261
|
+
#
|
262
|
+
# @return [ Symbol ] :mongoid
|
263
|
+
def i18n_scope
|
264
|
+
:mongoid
|
265
|
+
end
|
266
|
+
|
267
|
+
# Returns the logger
|
268
|
+
#
|
269
|
+
# @example Get the logger.
|
270
|
+
# Person.logger
|
271
|
+
#
|
272
|
+
# @return [ Logger ] The configured logger or a default Logger instance.
|
273
|
+
#
|
274
|
+
# @since 2.2.0
|
275
|
+
def logger
|
276
|
+
Mongoid.logger
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|