mongoid 2.8.1 → 3.0.0.rc
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 +802 -58
- data/LICENSE +1 -1
- data/README.md +10 -11
- data/Rakefile +2 -8
- data/lib/config/locales/en.yml +441 -51
- data/lib/mongoid.rb +24 -39
- data/lib/mongoid/atomic.rb +16 -33
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic/paths/embedded.rb +4 -5
- data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
- data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
- data/lib/mongoid/atomic/paths/root.rb +4 -5
- data/lib/mongoid/attributes.rb +95 -32
- data/lib/mongoid/attributes/processing.rb +14 -10
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/callbacks.rb +90 -27
- data/lib/mongoid/collections/retry.rb +2 -3
- data/lib/mongoid/components.rb +11 -23
- data/lib/mongoid/config.rb +87 -233
- data/lib/mongoid/config/environment.rb +5 -6
- data/lib/mongoid/config/inflections.rb +6 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/contextual.rb +50 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
- data/lib/mongoid/contextual/atomic.rb +179 -0
- data/lib/mongoid/contextual/command.rb +43 -0
- data/lib/mongoid/contextual/find_and_modify.rb +66 -0
- data/lib/mongoid/contextual/map_reduce.rb +273 -0
- data/lib/mongoid/contextual/memory.rb +383 -0
- data/lib/mongoid/contextual/mongo.rb +543 -0
- data/lib/mongoid/copyable.rb +3 -34
- data/lib/mongoid/criteria.rb +436 -250
- data/lib/mongoid/criterion/inspection.rb +14 -8
- data/lib/mongoid/criterion/scoping.rb +114 -44
- data/lib/mongoid/dirty.rb +152 -67
- data/lib/mongoid/document.rb +69 -50
- data/lib/mongoid/errors.rb +22 -1
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +5 -6
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +98 -17
- data/lib/mongoid/errors/eager_load.rb +3 -6
- data/lib/mongoid/errors/invalid_collection.rb +3 -3
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_database.rb +3 -3
- data/lib/mongoid/errors/invalid_field.rb +54 -8
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +3 -3
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +4 -4
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +3 -6
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +4 -9
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +54 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +3 -3
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +4 -4
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +4 -8
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/unsupported_version.rb +4 -4
- data/lib/mongoid/errors/validations.rb +7 -6
- data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
- data/lib/mongoid/extensions.rb +28 -76
- data/lib/mongoid/extensions/array.rb +127 -0
- data/lib/mongoid/extensions/big_decimal.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +24 -0
- data/lib/mongoid/extensions/date.rb +70 -0
- data/lib/mongoid/extensions/date_time.rb +68 -0
- data/lib/mongoid/extensions/false_class.rb +26 -0
- data/lib/mongoid/extensions/float.rb +44 -0
- data/lib/mongoid/extensions/hash.rb +91 -0
- data/lib/mongoid/extensions/integer.rb +54 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +21 -0
- data/lib/mongoid/extensions/object.rb +188 -0
- data/lib/mongoid/extensions/object_id.rb +53 -0
- data/lib/mongoid/extensions/range.rb +55 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +155 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +78 -0
- data/lib/mongoid/extensions/time_with_zone.rb +55 -0
- data/lib/mongoid/extensions/true_class.rb +26 -0
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields.rb +129 -194
- data/lib/mongoid/fields/foreign_key.rb +134 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +268 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields/validators/macro.rb +83 -0
- data/lib/mongoid/finders.rb +42 -43
- data/lib/mongoid/hierarchy.rb +25 -14
- data/lib/mongoid/identity_map.rb +31 -19
- data/lib/mongoid/indexes.rb +66 -15
- data/lib/mongoid/indexes/validators/options.rb +80 -0
- data/lib/mongoid/inspection.rb +1 -1
- data/lib/mongoid/javascript.rb +1 -1
- data/lib/mongoid/json.rb +2 -2
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchers.rb +1 -1
- data/lib/mongoid/matchers/all.rb +7 -8
- data/lib/mongoid/matchers/and.rb +3 -3
- data/lib/mongoid/matchers/default.rb +6 -4
- data/lib/mongoid/matchers/exists.rb +2 -2
- data/lib/mongoid/matchers/gt.rb +2 -2
- data/lib/mongoid/matchers/gte.rb +2 -2
- data/lib/mongoid/matchers/in.rb +3 -7
- data/lib/mongoid/matchers/lt.rb +2 -2
- data/lib/mongoid/matchers/lte.rb +2 -2
- data/lib/mongoid/matchers/ne.rb +2 -2
- data/lib/mongoid/matchers/nin.rb +2 -2
- data/lib/mongoid/matchers/or.rb +2 -2
- data/lib/mongoid/matchers/size.rb +2 -2
- data/lib/mongoid/matchers/strategies.rb +3 -3
- data/lib/mongoid/multi_parameter_attributes.rb +8 -10
- data/lib/mongoid/nested_attributes.rb +17 -9
- data/lib/mongoid/observer.rb +1 -2
- data/lib/mongoid/paranoia.rb +13 -18
- data/lib/mongoid/persistence.rb +43 -39
- data/lib/mongoid/persistence/atomic.rb +2 -2
- data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
- data/lib/mongoid/persistence/atomic/bit.rb +5 -7
- data/lib/mongoid/persistence/atomic/inc.rb +5 -7
- data/lib/mongoid/persistence/atomic/operation.rb +45 -6
- data/lib/mongoid/persistence/atomic/pop.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
- data/lib/mongoid/persistence/atomic/push.rb +4 -10
- data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
- data/lib/mongoid/persistence/atomic/rename.rb +6 -7
- data/lib/mongoid/persistence/atomic/sets.rb +5 -7
- data/lib/mongoid/persistence/atomic/unset.rb +4 -5
- data/lib/mongoid/persistence/deletion.rb +2 -2
- data/lib/mongoid/persistence/insertion.rb +10 -16
- data/lib/mongoid/persistence/modification.rb +5 -9
- data/lib/mongoid/persistence/operations.rb +6 -19
- data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
- data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
- data/lib/mongoid/persistence/operations/insert.rb +4 -4
- data/lib/mongoid/persistence/operations/remove.rb +4 -4
- data/lib/mongoid/persistence/operations/update.rb +5 -5
- data/lib/mongoid/railtie.rb +26 -11
- data/lib/mongoid/railties/database.rake +22 -108
- data/lib/mongoid/relations.rb +4 -6
- data/lib/mongoid/relations/accessors.rb +119 -19
- data/lib/mongoid/relations/auto_save.rb +59 -5
- data/lib/mongoid/relations/binding.rb +211 -2
- data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
- data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
- data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
- data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
- data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
- data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
- data/lib/mongoid/relations/builder.rb +3 -3
- data/lib/mongoid/relations/builders.rb +19 -16
- data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
- data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
- data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
- data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
- data/lib/mongoid/relations/cascading.rb +6 -4
- data/lib/mongoid/relations/cascading/delete.rb +3 -5
- data/lib/mongoid/relations/cascading/destroy.rb +3 -3
- data/lib/mongoid/relations/cascading/nullify.rb +3 -3
- data/lib/mongoid/relations/cascading/restrict.rb +37 -0
- data/lib/mongoid/relations/constraint.rb +4 -3
- data/lib/mongoid/relations/conversions.rb +5 -6
- data/lib/mongoid/relations/cyclic.rb +7 -7
- data/lib/mongoid/relations/embedded/batchable.rb +346 -0
- data/lib/mongoid/relations/embedded/in.rb +23 -12
- data/lib/mongoid/relations/embedded/many.rb +99 -161
- data/lib/mongoid/relations/embedded/one.rb +25 -14
- data/lib/mongoid/relations/macros.rb +105 -61
- data/lib/mongoid/relations/many.rb +93 -14
- data/lib/mongoid/relations/metadata.rb +200 -45
- data/lib/mongoid/relations/nested_builder.rb +3 -5
- data/lib/mongoid/relations/one.rb +2 -2
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/polymorphic.rb +9 -9
- data/lib/mongoid/relations/proxy.rb +60 -31
- data/lib/mongoid/relations/referenced/in.rb +40 -15
- data/lib/mongoid/relations/referenced/many.rb +117 -132
- data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
- data/lib/mongoid/relations/referenced/one.rb +34 -13
- data/lib/mongoid/relations/reflections.rb +3 -3
- data/lib/mongoid/relations/synchronization.rb +19 -23
- data/lib/mongoid/relations/targets/enumerable.rb +86 -57
- data/lib/mongoid/reloading.rb +12 -14
- data/lib/mongoid/scoping.rb +329 -0
- data/lib/mongoid/serialization.rb +8 -27
- data/lib/mongoid/sessions.rb +359 -0
- data/lib/mongoid/sessions/factory.rb +106 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/sharding.rb +6 -6
- data/lib/mongoid/state.rb +6 -7
- data/lib/mongoid/threaded.rb +167 -59
- data/lib/mongoid/threaded/lifecycle.rb +21 -22
- data/lib/mongoid/threaded/sessions.rb +0 -0
- data/lib/mongoid/timestamps.rb +1 -1
- data/lib/mongoid/timestamps/created.rb +8 -4
- data/lib/mongoid/timestamps/timeless.rb +6 -4
- data/lib/mongoid/timestamps/updated.rb +3 -3
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validations.rb +27 -19
- data/lib/mongoid/validations/associated.rb +2 -2
- data/lib/mongoid/validations/format.rb +2 -2
- data/lib/mongoid/validations/presence.rb +31 -5
- data/lib/mongoid/validations/uniqueness.rb +9 -12
- data/lib/mongoid/version.rb +2 -2
- data/lib/mongoid/versioning.rb +25 -26
- data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
- data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
- data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
- data/lib/rails/generators/mongoid_generator.rb +5 -5
- data/lib/rails/mongoid.rb +69 -25
- metadata +110 -137
- checksums.yaml +0 -7
- data/lib/config/locales/bg.yml +0 -61
- data/lib/config/locales/de.yml +0 -61
- data/lib/config/locales/en-GB.yml +0 -64
- data/lib/config/locales/es.yml +0 -59
- data/lib/config/locales/fr.yml +0 -62
- data/lib/config/locales/hi.yml +0 -53
- data/lib/config/locales/hu.yml +0 -64
- data/lib/config/locales/id.yml +0 -62
- data/lib/config/locales/it.yml +0 -59
- data/lib/config/locales/ja.yml +0 -57
- data/lib/config/locales/kr.yml +0 -54
- data/lib/config/locales/nl.yml +0 -61
- data/lib/config/locales/pl.yml +0 -59
- data/lib/config/locales/pt-BR.yml +0 -60
- data/lib/config/locales/pt.yml +0 -60
- data/lib/config/locales/ro.yml +0 -66
- data/lib/config/locales/ru.yml +0 -61
- data/lib/config/locales/sv.yml +0 -60
- data/lib/config/locales/vi.yml +0 -62
- data/lib/config/locales/zh-CN.yml +0 -53
- data/lib/mongoid/collection.rb +0 -157
- data/lib/mongoid/collections.rb +0 -120
- data/lib/mongoid/collections/master.rb +0 -45
- data/lib/mongoid/collections/operations.rb +0 -44
- data/lib/mongoid/config/database.rb +0 -181
- data/lib/mongoid/config/replset_database.rb +0 -80
- data/lib/mongoid/contexts.rb +0 -25
- data/lib/mongoid/contexts/enumerable.rb +0 -313
- data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
- data/lib/mongoid/contexts/mongo.rb +0 -487
- data/lib/mongoid/criterion/builder.rb +0 -34
- data/lib/mongoid/criterion/complex.rb +0 -84
- data/lib/mongoid/criterion/creational.rb +0 -34
- data/lib/mongoid/criterion/exclusion.rb +0 -110
- data/lib/mongoid/criterion/inclusion.rb +0 -290
- data/lib/mongoid/criterion/optional.rb +0 -259
- data/lib/mongoid/criterion/selector.rb +0 -177
- data/lib/mongoid/cursor.rb +0 -88
- data/lib/mongoid/default_scope.rb +0 -36
- data/lib/mongoid/errors/invalid_type.rb +0 -25
- data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/array/deletion.rb +0 -29
- data/lib/mongoid/extensions/false_class/equality.rb +0 -26
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
- data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/hash/scoping.rb +0 -25
- data/lib/mongoid/extensions/integer/checks.rb +0 -23
- data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
- data/lib/mongoid/extensions/object/checks.rb +0 -29
- data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
- data/lib/mongoid/extensions/object/reflections.rb +0 -48
- data/lib/mongoid/extensions/object/substitutable.rb +0 -15
- data/lib/mongoid/extensions/object/yoda.rb +0 -44
- data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
- data/lib/mongoid/extensions/proc/scoping.rb +0 -25
- data/lib/mongoid/extensions/string/checks.rb +0 -36
- data/lib/mongoid/extensions/string/conversions.rb +0 -22
- data/lib/mongoid/extensions/string/inflections.rb +0 -118
- data/lib/mongoid/extensions/symbol/checks.rb +0 -23
- data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
- data/lib/mongoid/extensions/true_class/equality.rb +0 -26
- data/lib/mongoid/extras.rb +0 -31
- data/lib/mongoid/fields/internal/array.rb +0 -77
- data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
- data/lib/mongoid/fields/internal/bignum.rb +0 -10
- data/lib/mongoid/fields/internal/binary.rb +0 -11
- data/lib/mongoid/fields/internal/boolean.rb +0 -58
- data/lib/mongoid/fields/internal/date.rb +0 -51
- data/lib/mongoid/fields/internal/date_time.rb +0 -28
- data/lib/mongoid/fields/internal/false_class.rb +0 -10
- data/lib/mongoid/fields/internal/fixnum.rb +0 -10
- data/lib/mongoid/fields/internal/float.rb +0 -47
- data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
- data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
- data/lib/mongoid/fields/internal/hash.rb +0 -11
- data/lib/mongoid/fields/internal/integer.rb +0 -59
- data/lib/mongoid/fields/internal/localized.rb +0 -62
- data/lib/mongoid/fields/internal/nil_class.rb +0 -53
- data/lib/mongoid/fields/internal/object.rb +0 -11
- data/lib/mongoid/fields/internal/object_id.rb +0 -46
- data/lib/mongoid/fields/internal/range.rb +0 -61
- data/lib/mongoid/fields/internal/set.rb +0 -57
- data/lib/mongoid/fields/internal/string.rb +0 -42
- data/lib/mongoid/fields/internal/symbol.rb +0 -43
- data/lib/mongoid/fields/internal/time.rb +0 -23
- data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
- data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
- data/lib/mongoid/fields/internal/true_class.rb +0 -10
- data/lib/mongoid/fields/mappings.rb +0 -42
- data/lib/mongoid/fields/serializable.rb +0 -270
- data/lib/mongoid/identity.rb +0 -92
- data/lib/mongoid/keys.rb +0 -144
- data/lib/mongoid/logger.rb +0 -45
- data/lib/mongoid/multi_database.rb +0 -36
- data/lib/mongoid/named_scope.rb +0 -166
- data/lib/mongoid/relations/embedded/atomic.rb +0 -89
- data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
- data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
- data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
- data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
- data/lib/mongoid/relations/referenced/batch.rb +0 -73
- data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
- data/lib/mongoid/safety.rb +0 -105
- data/lib/mongoid/scope.rb +0 -31
data/lib/mongoid/copyable.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
module Mongoid
|
2
|
+
module Mongoid
|
3
3
|
|
4
4
|
# This module contains the behaviour of Mongoid's clone/dup of documents.
|
5
5
|
module Copyable
|
@@ -23,44 +23,13 @@ module Mongoid #:nodoc:
|
|
23
23
|
# @example Clone the document.
|
24
24
|
# document.clone
|
25
25
|
#
|
26
|
-
# @param [ Document ] other The document getting cloned.
|
27
|
-
#
|
28
|
-
# @return [ Document ] The new document.
|
29
|
-
def initialize_copy(other)
|
30
|
-
__copy__(other)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Clone or dup the current +Document+. This will return all attributes with
|
34
|
-
# the exception of the document's id and versions, and will reset all the
|
35
|
-
# instance variables.
|
36
|
-
#
|
37
|
-
# This clone also includes embedded documents.
|
38
|
-
#
|
39
26
|
# @example Dup the document.
|
40
27
|
# document.dup
|
41
28
|
#
|
42
29
|
# @param [ Document ] other The document getting cloned.
|
43
30
|
#
|
44
31
|
# @return [ Document ] The new document.
|
45
|
-
def
|
46
|
-
__copy__(other)
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
# Handle the copy of the object.
|
52
|
-
#
|
53
|
-
# @api private
|
54
|
-
#
|
55
|
-
# @example Copy the object.
|
56
|
-
# document.__copy__(other)
|
57
|
-
#
|
58
|
-
# @param [ Document ] other The other document.
|
59
|
-
#
|
60
|
-
# @return [ Document ] self.
|
61
|
-
#
|
62
|
-
# @since 3.0.0
|
63
|
-
def __copy__(other)
|
32
|
+
def initialize_copy(other)
|
64
33
|
other.as_document
|
65
34
|
instance_variables.each { |name| remove_instance_variable(name) }
|
66
35
|
COPYABLES.each do |name|
|
@@ -72,7 +41,7 @@ module Mongoid #:nodoc:
|
|
72
41
|
attributes["version"] = 1
|
73
42
|
end
|
74
43
|
@new_record = true
|
75
|
-
|
44
|
+
apply_defaults
|
76
45
|
end
|
77
46
|
end
|
78
47
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -1,15 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require "mongoid/criterion/builder"
|
3
|
-
require "mongoid/criterion/creational"
|
4
|
-
require "mongoid/criterion/complex"
|
5
|
-
require "mongoid/criterion/exclusion"
|
6
|
-
require "mongoid/criterion/inclusion"
|
7
2
|
require "mongoid/criterion/inspection"
|
8
|
-
require "mongoid/criterion/optional"
|
9
3
|
require "mongoid/criterion/scoping"
|
10
|
-
require "mongoid/criterion/selector"
|
11
4
|
|
12
|
-
module Mongoid
|
5
|
+
module Mongoid
|
13
6
|
|
14
7
|
# The +Criteria+ class is the core object needed in Mongoid to retrieve
|
15
8
|
# objects from the database. It is a DSL that essentially sets up the
|
@@ -17,78 +10,14 @@ module Mongoid #:nodoc:
|
|
17
10
|
# in the Ruby driver. Each method on the +Criteria+ returns self to they
|
18
11
|
# can be chained in order to create a readable criterion to be executed
|
19
12
|
# against the database.
|
20
|
-
#
|
21
|
-
# @example Create and execute a criteria.
|
22
|
-
# criteria = Criteria.new
|
23
|
-
# criteria.only(:field).where(:field => "value").skip(20).limit(20)
|
24
|
-
# criteria.execute
|
25
13
|
class Criteria
|
26
14
|
include Enumerable
|
27
|
-
include
|
28
|
-
include
|
29
|
-
include Criterion::Exclusion
|
30
|
-
include Criterion::Inclusion
|
15
|
+
include Contextual
|
16
|
+
include Origin::Queryable
|
31
17
|
include Criterion::Inspection
|
32
|
-
include Criterion::Optional
|
33
18
|
include Criterion::Scoping
|
34
19
|
|
35
|
-
attr_accessor
|
36
|
-
:documents,
|
37
|
-
:embedded,
|
38
|
-
:ids,
|
39
|
-
:klass,
|
40
|
-
:options,
|
41
|
-
:selector,
|
42
|
-
:field_list
|
43
|
-
|
44
|
-
delegate \
|
45
|
-
:add_to_set,
|
46
|
-
:aggregate,
|
47
|
-
:avg,
|
48
|
-
:blank?,
|
49
|
-
:count,
|
50
|
-
:size,
|
51
|
-
:length,
|
52
|
-
:delete,
|
53
|
-
:delete_all,
|
54
|
-
:destroy,
|
55
|
-
:destroy_all,
|
56
|
-
:distinct,
|
57
|
-
:empty?,
|
58
|
-
:execute,
|
59
|
-
:first,
|
60
|
-
:group,
|
61
|
-
:last,
|
62
|
-
:max,
|
63
|
-
:min,
|
64
|
-
:one,
|
65
|
-
:pull,
|
66
|
-
:shift,
|
67
|
-
:sum,
|
68
|
-
:update,
|
69
|
-
:update_all, :to => :context
|
70
|
-
|
71
|
-
# Concatinate the criteria with another enumerable. If the other is a
|
72
|
-
# +Criteria+ then it needs to get the collection from it.
|
73
|
-
#
|
74
|
-
# @example Concat 2 criteria.
|
75
|
-
# criteria + criteria
|
76
|
-
#
|
77
|
-
# @param [ Criteria ] other The other criteria.
|
78
|
-
def +(other)
|
79
|
-
entries + comparable(other)
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns the difference between the criteria and another enumerable. If
|
83
|
-
# the other is a +Criteria+ then it needs to get the collection from it.
|
84
|
-
#
|
85
|
-
# @example Get the difference of 2 criteria.
|
86
|
-
# criteria - criteria
|
87
|
-
#
|
88
|
-
# @param [ Criteria ] other The other criteria.
|
89
|
-
def -(other)
|
90
|
-
entries - comparable(other)
|
91
|
-
end
|
20
|
+
attr_accessor :embedded, :klass
|
92
21
|
|
93
22
|
# Returns true if the supplied +Enumerable+ or +Criteria+ is equal to the results
|
94
23
|
# of this +Criteria+ or the criteria itself.
|
@@ -98,51 +27,147 @@ module Mongoid #:nodoc:
|
|
98
27
|
# @param [ Object ] other The other +Enumerable+ or +Criteria+ to compare to.
|
99
28
|
#
|
100
29
|
# @return [ true, false ] If the objects are equal.
|
30
|
+
#
|
31
|
+
# @since 1.0.0
|
101
32
|
def ==(other)
|
102
33
|
case other
|
103
|
-
when Criteria
|
104
|
-
|
105
|
-
|
106
|
-
return (execute.entries == other)
|
107
|
-
else
|
108
|
-
return false
|
34
|
+
when Criteria then super
|
35
|
+
when Enumerable then entries == other
|
36
|
+
else false
|
109
37
|
end
|
110
38
|
end
|
111
39
|
|
112
|
-
#
|
40
|
+
# Needed to properly get a criteria back as json
|
113
41
|
#
|
114
|
-
# @example Get the
|
115
|
-
#
|
42
|
+
# @example Get the criteria as json.
|
43
|
+
# Person.where(:title => "Sir").as_json
|
116
44
|
#
|
117
|
-
# @
|
45
|
+
# @param [ Hash ] options Options to pass through to the serializer.
|
118
46
|
#
|
119
|
-
# @
|
120
|
-
def
|
121
|
-
|
47
|
+
# @return [ String ] The JSON string.
|
48
|
+
def as_json(options = nil)
|
49
|
+
entries.as_json(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Build a document given the selector and return it.
|
53
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
54
|
+
#
|
55
|
+
# @example build the document.
|
56
|
+
# Person.where(:title => "Sir").build
|
57
|
+
#
|
58
|
+
# @example Build with selectors getting ignored.
|
59
|
+
# Person.where(:age.gt => 5).build
|
60
|
+
#
|
61
|
+
# @return [ Document ] A non-persisted document.
|
62
|
+
#
|
63
|
+
# @since 2.0.0
|
64
|
+
def build(attrs = {})
|
65
|
+
create_document(:new, attrs)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
69
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
70
|
+
# times, however this is not advisable when working with large data sets
|
71
|
+
# as the entire results will get stored in memory.
|
72
|
+
#
|
73
|
+
# @example Flag the criteria as cached.
|
74
|
+
# criteria.cache
|
75
|
+
#
|
76
|
+
# @return [ Criteria ] The cloned criteria.
|
77
|
+
def cache
|
78
|
+
crit = clone
|
79
|
+
crit.options.merge!(cache: true)
|
80
|
+
crit
|
81
|
+
end
|
82
|
+
|
83
|
+
# Will return true if the cache option has been set.
|
84
|
+
#
|
85
|
+
# @example Is the criteria cached?
|
86
|
+
# criteria.cached?
|
87
|
+
#
|
88
|
+
# @return [ true, false ] If the criteria is flagged as cached.
|
89
|
+
def cached?
|
90
|
+
options[:cache] == true
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create a document in the database given the selector and return it.
|
94
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
95
|
+
#
|
96
|
+
# @example Create the document.
|
97
|
+
# Person.where(:title => "Sir").create
|
98
|
+
#
|
99
|
+
# @example Create with selectors getting ignored.
|
100
|
+
# Person.where(:age.gt => 5).create
|
101
|
+
#
|
102
|
+
# @return [ Document ] A newly created document.
|
103
|
+
#
|
104
|
+
# @since 2.0.0.rc.1
|
105
|
+
def create(attrs = {})
|
106
|
+
create_document(:create, attrs)
|
122
107
|
end
|
123
108
|
|
124
|
-
#
|
109
|
+
# Create a document in the database given the selector and return it.
|
110
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
111
|
+
# If validation fails, an error will be raised.
|
112
|
+
#
|
113
|
+
# @example Create the document.
|
114
|
+
# Person.where(:title => "Sir").create
|
115
|
+
#
|
116
|
+
# @example Create with selectors getting ignored.
|
117
|
+
# Person.where(:age.gt => 5).create
|
125
118
|
#
|
126
|
-
#
|
127
|
-
# otherwise it will return a Mongo context for root classes.
|
119
|
+
# @raise [ Errors::Validations ] on a validation error.
|
128
120
|
#
|
129
|
-
# @
|
130
|
-
# criteria.context
|
121
|
+
# @return [ Document ] A newly created document.
|
131
122
|
#
|
132
|
-
# @
|
133
|
-
def
|
134
|
-
|
123
|
+
# @since 3.0.0
|
124
|
+
def create!(attrs = {})
|
125
|
+
create_document(:create!, attrs)
|
135
126
|
end
|
136
127
|
|
137
|
-
#
|
138
|
-
# block to pass to each argument in the results.
|
128
|
+
# Get the documents from the embedded criteria.
|
139
129
|
#
|
140
|
-
# @example
|
141
|
-
# criteria.
|
130
|
+
# @example Get the documents.
|
131
|
+
# criteria.documents
|
142
132
|
#
|
143
|
-
# @return [
|
144
|
-
|
145
|
-
|
133
|
+
# @return [ Array<Document> ] The documents.
|
134
|
+
#
|
135
|
+
# @since 3.0.0
|
136
|
+
def documents
|
137
|
+
@documents ||= []
|
138
|
+
end
|
139
|
+
|
140
|
+
# Set the embedded documents on the criteria.
|
141
|
+
#
|
142
|
+
# @example Set the documents.
|
143
|
+
#
|
144
|
+
# @param [ Array<Document> ] docs The embedded documents.
|
145
|
+
#
|
146
|
+
# @return [ Array<Document> ] The embedded documents.
|
147
|
+
#
|
148
|
+
# @since 3.0.0
|
149
|
+
def documents=(docs)
|
150
|
+
@documents = docs
|
151
|
+
end
|
152
|
+
|
153
|
+
# Execute the criteria or raise an error if no documents found.
|
154
|
+
#
|
155
|
+
# @example Execute or raise
|
156
|
+
# criteria.execute_or_raise(id)
|
157
|
+
#
|
158
|
+
# @param [ Object ] args The arguments passed.
|
159
|
+
#
|
160
|
+
# @raise [ Errors::DocumentNotFound ] If nothing returned.
|
161
|
+
#
|
162
|
+
# @return [ Document, Array<Document> ] The document(s).
|
163
|
+
#
|
164
|
+
# @since 2.0.0
|
165
|
+
def execute_or_raise(ids, multi)
|
166
|
+
result = multiple_from_map_or_db(ids)
|
167
|
+
if (result.size < ids.size) && Mongoid.raise_not_found_error
|
168
|
+
raise Errors::DocumentNotFound.new(klass, ids, ids - result.map(&:_id))
|
169
|
+
end
|
170
|
+
multi ? result : result.first
|
146
171
|
end
|
147
172
|
|
148
173
|
# Return true if the criteria has some Document or not.
|
@@ -151,6 +176,8 @@ module Mongoid #:nodoc:
|
|
151
176
|
# criteria.exists?
|
152
177
|
#
|
153
178
|
# @return [ true, false ] If documents match.
|
179
|
+
#
|
180
|
+
# @since 1.0.0
|
154
181
|
def exists?
|
155
182
|
context.count > 0
|
156
183
|
end
|
@@ -165,7 +192,83 @@ module Mongoid #:nodoc:
|
|
165
192
|
#
|
166
193
|
# @since 2.3.0
|
167
194
|
def extract_id
|
168
|
-
selector
|
195
|
+
selector.extract_id
|
196
|
+
end
|
197
|
+
|
198
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
199
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
200
|
+
#
|
201
|
+
# @example Add extra params to the criteria.
|
202
|
+
# criteria.extras(:limit => 20, :skip => 40)
|
203
|
+
#
|
204
|
+
# @param [ Hash ] extras The extra driver options.
|
205
|
+
#
|
206
|
+
# @return [ Criteria ] The cloned criteria.
|
207
|
+
#
|
208
|
+
# @since 2.0.0
|
209
|
+
def extras(extras)
|
210
|
+
crit = clone
|
211
|
+
crit.options.merge!(extras)
|
212
|
+
crit
|
213
|
+
end
|
214
|
+
|
215
|
+
# Get the list of included fields.
|
216
|
+
#
|
217
|
+
# @example Get the field list.
|
218
|
+
# criteria.field_list
|
219
|
+
#
|
220
|
+
# @return [ Array<String> ] The fields.
|
221
|
+
#
|
222
|
+
# @since 2.0.0
|
223
|
+
def field_list
|
224
|
+
if options[:fields]
|
225
|
+
options[:fields].keys.reject!{ |key| key == "_type" }
|
226
|
+
else
|
227
|
+
[]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Find the matchind document(s) in the criteria for the provided ids.
|
232
|
+
#
|
233
|
+
# @example Find by an id.
|
234
|
+
# criteria.find(BSON::ObjectId.new)
|
235
|
+
#
|
236
|
+
# @example Find by multiple ids.
|
237
|
+
# criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
|
238
|
+
#
|
239
|
+
# @param [ Array<BSON::ObjectId> ] args The ids to search for.
|
240
|
+
#
|
241
|
+
# @return [ Array<Document>, Document ] The matching document(s).
|
242
|
+
#
|
243
|
+
# @since 1.0.0
|
244
|
+
def find(*args)
|
245
|
+
multi = args.first.is_a?(::Array) || args.first.is_a?(::Range) || args.size > 1
|
246
|
+
ids = *args.flat_map do |arg|
|
247
|
+
arg.is_a?(::Range) ? arg.to_a : arg
|
248
|
+
end
|
249
|
+
raise_invalid if ids.any?(&:nil?)
|
250
|
+
for_ids(ids).execute_or_raise(ids, multi)
|
251
|
+
end
|
252
|
+
|
253
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
254
|
+
#
|
255
|
+
# @example Add a single id criteria.
|
256
|
+
# criteria.for_ids([ 1 ])
|
257
|
+
#
|
258
|
+
# @example Add multiple id criteria.
|
259
|
+
# criteria.for_ids([ 1, 2 ])
|
260
|
+
#
|
261
|
+
# @param [ Array ] ids The array of ids.
|
262
|
+
#
|
263
|
+
# @return [ Criteria ] The cloned criteria.
|
264
|
+
def for_ids(ids)
|
265
|
+
field = klass.fields["_id"]
|
266
|
+
method = extract_id ? :all_of : :where
|
267
|
+
if ids.size > 1
|
268
|
+
send(method, { _id: { "$in" => ids.map{ |id| field.mongoize(id) }}})
|
269
|
+
else
|
270
|
+
send(method, { _id: field.mongoize(ids.first) })
|
271
|
+
end
|
169
272
|
end
|
170
273
|
|
171
274
|
# When freezing a criteria we need to initialize the context first
|
@@ -182,31 +285,108 @@ module Mongoid #:nodoc:
|
|
182
285
|
context and inclusions and super
|
183
286
|
end
|
184
287
|
|
185
|
-
#
|
288
|
+
# Get the document from the identity map, and if not found hit the
|
289
|
+
# database.
|
186
290
|
#
|
187
|
-
# @example
|
188
|
-
# criteria.
|
291
|
+
# @example Get the document from the map or criteria.
|
292
|
+
# criteria.from_map_or_db
|
189
293
|
#
|
190
|
-
# @
|
294
|
+
# @return [ Document ] The found document.
|
191
295
|
#
|
192
|
-
# @
|
193
|
-
def
|
194
|
-
|
195
|
-
|
296
|
+
# @since 2.2.1
|
297
|
+
def from_map_or_db
|
298
|
+
doc = IdentityMap.get(klass, extract_id || selector)
|
299
|
+
doc && doc.matches?(selector) ? doc : first
|
300
|
+
end
|
301
|
+
|
302
|
+
# Get the documents from the identity map, and if not found hit the
|
303
|
+
# database.
|
304
|
+
#
|
305
|
+
# @example Get the documents from the map or criteria.
|
306
|
+
# criteria.multiple_from_map_or_db(ids)
|
307
|
+
#
|
308
|
+
# @param [ ids ] The searched ids.
|
309
|
+
#
|
310
|
+
# @return [ Array<Document> ] The found documents.
|
311
|
+
def multiple_from_map_or_db(ids)
|
312
|
+
return entries if klass.embedded?
|
313
|
+
result = []
|
314
|
+
ids.reject! do |id|
|
315
|
+
doc = IdentityMap.get(klass, id)
|
316
|
+
doc && doc.matches?(selector) ? result.push(doc) : false
|
317
|
+
end
|
318
|
+
ids.empty? ? result : result + any_in(id: ids).entries
|
319
|
+
end
|
320
|
+
|
321
|
+
# Initialize the new criteria.
|
322
|
+
#
|
323
|
+
# @example Init the new criteria.
|
324
|
+
# Criteria.new(Band)
|
325
|
+
#
|
326
|
+
# @param [ Class ] klass The model class.
|
327
|
+
#
|
328
|
+
# @since 1.0.0
|
329
|
+
def initialize(klass)
|
330
|
+
@klass = klass
|
331
|
+
super(klass.aliased_fields, klass.fields)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Eager loads all the provided relations. Will load all the documents
|
335
|
+
# into the identity map who's ids match based on the extra query for the
|
336
|
+
# ids.
|
337
|
+
#
|
338
|
+
# @note This will only work if Mongoid's identity map is enabled. To do
|
339
|
+
# so set identity_map_enabled: true in your mongoid.yml
|
340
|
+
#
|
341
|
+
# @note This will work for embedded relations that reference another
|
342
|
+
# collection via belongs_to as well.
|
343
|
+
#
|
344
|
+
# @note Eager loading brings all the documents into memory, so there is a
|
345
|
+
# sweet spot on the performance gains. Internal benchmarks show that
|
346
|
+
# eager loading becomes slower around 100k documents, but this will
|
347
|
+
# naturally depend on the specific application.
|
348
|
+
#
|
349
|
+
# @example Eager load the provided relations.
|
350
|
+
# Person.includes(:posts, :game)
|
351
|
+
#
|
352
|
+
# @param [ Array<Symbol> ] relations The names of the relations to eager
|
353
|
+
# load.
|
354
|
+
#
|
355
|
+
# @return [ Criteria ] The cloned criteria.
|
356
|
+
#
|
357
|
+
# @since 2.2.0
|
358
|
+
def includes(*relations)
|
359
|
+
relations.each do |name|
|
360
|
+
metadata = klass.reflect_on_association(name)
|
361
|
+
inclusions.push(metadata) unless inclusions.include?(metadata)
|
196
362
|
end
|
363
|
+
clone
|
197
364
|
end
|
198
365
|
|
199
|
-
#
|
200
|
-
#
|
366
|
+
# Get a list of criteria that are to be executed for eager loading.
|
367
|
+
#
|
368
|
+
# @example Get the eager loading inclusions.
|
369
|
+
# Person.includes(:game).inclusions
|
201
370
|
#
|
202
|
-
# @
|
203
|
-
# Criteria.new(Model, true)
|
371
|
+
# @return [ Array<Metadata> ] The inclusions.
|
204
372
|
#
|
205
|
-
# @
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
373
|
+
# @since 2.2.0
|
374
|
+
def inclusions
|
375
|
+
@inclusions ||= []
|
376
|
+
end
|
377
|
+
|
378
|
+
# Set the inclusions for the criteria.
|
379
|
+
#
|
380
|
+
# @example Set the inclusions.
|
381
|
+
# criteria.inclusions = [ meta ]
|
382
|
+
#
|
383
|
+
# @param [ Array<Metadata> ] The inclusions.
|
384
|
+
#
|
385
|
+
# @return [ Array<Metadata> ] The new inclusions.
|
386
|
+
#
|
387
|
+
# @since 3.0.0
|
388
|
+
def inclusions=(value)
|
389
|
+
@inclusions = value
|
210
390
|
end
|
211
391
|
|
212
392
|
# Merges another object with this +Criteria+ and returns a new criteria.
|
@@ -214,27 +394,51 @@ module Mongoid #:nodoc:
|
|
214
394
|
# combine multiple scopes together, where a chained scope situation
|
215
395
|
# may be desired.
|
216
396
|
#
|
217
|
-
# @example Merge the criteria with a conditions hash.
|
218
|
-
# criteria.merge({ :conditions => { :title => "Sir" } })
|
219
|
-
#
|
220
397
|
# @example Merge the criteria with another criteria.
|
221
398
|
# criteri.merge(other_criteria)
|
222
399
|
#
|
223
|
-
# @param [ Criteria
|
400
|
+
# @param [ Criteria ] other The other criterion to merge with.
|
224
401
|
#
|
225
402
|
# @return [ Criteria ] A cloned self.
|
226
403
|
def merge(other)
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
404
|
+
crit = clone
|
405
|
+
crit.merge!(other)
|
406
|
+
crit
|
407
|
+
end
|
408
|
+
|
409
|
+
# Merge the other criteria into this one.
|
410
|
+
#
|
411
|
+
# @example Merge another criteria into this criteria.
|
412
|
+
# criteria.merge(Person.where(name: "bob"))
|
413
|
+
#
|
414
|
+
# @param [ Criteria ] other The criteria to merge in.
|
415
|
+
#
|
416
|
+
# @return [ Criteria ] The merged criteria.
|
417
|
+
#
|
418
|
+
# @since 3.0.0
|
419
|
+
def merge!(other)
|
420
|
+
criteria = other.to_criteria
|
421
|
+
selector.update(criteria.selector)
|
422
|
+
options.update(criteria.options)
|
423
|
+
self.documents = criteria.documents.dup if criteria.documents.any?
|
424
|
+
self.scoping_options = criteria.scoping_options
|
425
|
+
self.inclusions = (inclusions + criteria.inclusions.dup).uniq
|
426
|
+
self
|
427
|
+
end
|
428
|
+
|
429
|
+
# Overriden to include _type in the fields.
|
430
|
+
#
|
431
|
+
# @example Limit the fields returned from the database.
|
432
|
+
# Band.only(:name)
|
433
|
+
#
|
434
|
+
# @param [ Array<Symbol> ] args The names of the fields.
|
435
|
+
#
|
436
|
+
# @return [ Criteria ] The cloned criteria.
|
437
|
+
#
|
438
|
+
# @since 1.0.0
|
439
|
+
def only(*args)
|
440
|
+
return clone if args.empty?
|
441
|
+
super(*(args + [:_type]))
|
238
442
|
end
|
239
443
|
|
240
444
|
# Returns true if criteria responds to the given method.
|
@@ -247,118 +451,107 @@ module Mongoid #:nodoc:
|
|
247
451
|
#
|
248
452
|
# @return [ true, false ] If the criteria responds to the method.
|
249
453
|
def respond_to?(name, include_private = false)
|
250
|
-
|
251
|
-
# don't include klass private methods because method_missing won't call them
|
252
|
-
super || @klass.respond_to?(name) || entries.respond_to?(name, include_private)
|
454
|
+
super || klass.respond_to?(name) || entries.respond_to?(name, include_private)
|
253
455
|
end
|
254
456
|
|
255
|
-
# Returns the selector and options as a +Hash+ that would be passed to a
|
256
|
-
# scope for use with named scopes.
|
257
|
-
#
|
258
|
-
# @example Get the criteria as a scoped hash.
|
259
|
-
# criteria.as_conditions
|
260
|
-
#
|
261
|
-
# @return [ Hash ] The criteria as a scoped hash.
|
262
|
-
def as_conditions
|
263
|
-
scope_options = @options.dup
|
264
|
-
sorting = scope_options.delete(:sort)
|
265
|
-
scope_options[:order_by] = sorting if sorting
|
266
|
-
scope_options[:includes] = inclusions.map(&:name) if inclusions.any?
|
267
|
-
{ :where => @selector }.merge(scope_options)
|
268
|
-
end
|
269
457
|
alias :to_ary :to_a
|
270
458
|
|
271
|
-
#
|
459
|
+
# Convenience for objects that want to be merged into a criteria.
|
272
460
|
#
|
273
|
-
# @example
|
274
|
-
#
|
461
|
+
# @example Convert to a criteria.
|
462
|
+
# criteria.to_criteria
|
275
463
|
#
|
276
|
-
# @
|
464
|
+
# @return [ Criteria ] self.
|
277
465
|
#
|
278
|
-
# @
|
279
|
-
def
|
280
|
-
|
466
|
+
# @since 3.0.0
|
467
|
+
def to_criteria
|
468
|
+
self
|
281
469
|
end
|
282
470
|
|
283
|
-
#
|
284
|
-
#
|
285
|
-
# @example Find by an id.
|
286
|
-
# criteria.search(BSON::ObjectId.new)
|
471
|
+
# Convert the criteria to a proc.
|
287
472
|
#
|
288
|
-
# @example
|
289
|
-
# criteria.
|
290
|
-
#
|
291
|
-
# @example Conditionally find all matching documents.
|
292
|
-
# criteria.search(:all, :conditions => { :title => "Sir" })
|
473
|
+
# @example Convert the criteria to a proc.
|
474
|
+
# criteria.to_proc
|
293
475
|
#
|
294
|
-
# @
|
295
|
-
# criteria.search(:first, :conditions => { :title => "Sir" })
|
476
|
+
# @return [ Proc ] The wrapped criteria.
|
296
477
|
#
|
297
|
-
# @
|
298
|
-
|
478
|
+
# @since 3.0.0
|
479
|
+
def to_proc
|
480
|
+
->{ self }
|
481
|
+
end
|
482
|
+
|
483
|
+
# Adds a criterion to the +Criteria+ that specifies a type or an Array of
|
484
|
+
# types that must be matched.
|
299
485
|
#
|
300
|
-
# @
|
301
|
-
#
|
302
|
-
#
|
486
|
+
# @example Match only specific models.
|
487
|
+
# criteria.type('Browser')
|
488
|
+
# criteria.type(['Firefox', 'Browser'])
|
303
489
|
#
|
304
|
-
# @
|
490
|
+
# @param [ Array<String> ] types The types to match against.
|
305
491
|
#
|
306
|
-
# @
|
307
|
-
def
|
308
|
-
|
309
|
-
|
310
|
-
params = args[1] || {}
|
311
|
-
return [ :ids, for_ids(type) ] unless type.is_a?(Symbol)
|
312
|
-
conditions = params.delete(:conditions) || {}
|
313
|
-
if conditions.include?(:id)
|
314
|
-
conditions[:_id] = conditions[:id]
|
315
|
-
conditions.delete(:id)
|
316
|
-
end
|
317
|
-
return [ type, where(conditions).extras(params) ]
|
492
|
+
# @return [ Criteria ] The cloned criteria.
|
493
|
+
def type(types)
|
494
|
+
types = [types] unless types.is_a?(Array)
|
495
|
+
any_in(_type: types)
|
318
496
|
end
|
319
497
|
|
320
|
-
#
|
498
|
+
# This is the general entry point for most MongoDB queries. This either
|
499
|
+
# creates a standard field: value selection, and expanded selection with
|
500
|
+
# the use of hash methods, or a $where selection if a string is provided.
|
321
501
|
#
|
322
|
-
# @example
|
323
|
-
# criteria.
|
502
|
+
# @example Add a standard selection.
|
503
|
+
# criteria.where(name: "syd")
|
324
504
|
#
|
325
|
-
# @
|
505
|
+
# @example Add a javascript selection.
|
506
|
+
# criteria.where("this.name == 'syd'")
|
326
507
|
#
|
327
|
-
# @
|
328
|
-
def raise_invalid
|
329
|
-
raise Errors::InvalidFind.new
|
330
|
-
end
|
331
|
-
|
332
|
-
protected
|
333
|
-
|
334
|
-
# Return the entries of the other criteria or the object. Used for
|
335
|
-
# comparing criteria or an enumerable.
|
508
|
+
# @param [ String, Hash ] criterion The javascript or standard selection.
|
336
509
|
#
|
337
|
-
# @
|
338
|
-
#
|
510
|
+
# @raise [ UnsupportedJavascript ] If provided a string and the criteria
|
511
|
+
# is embedded.
|
339
512
|
#
|
340
|
-
# @
|
513
|
+
# @return [ Criteria ] The cloned selectable.
|
341
514
|
#
|
342
|
-
# @
|
343
|
-
def
|
344
|
-
|
515
|
+
# @since 1.0.0
|
516
|
+
def where(expression)
|
517
|
+
if expression.is_a?(::String) && embedded?
|
518
|
+
raise Errors::UnsupportedJavascript.new(klass, expression)
|
519
|
+
end
|
520
|
+
super
|
345
521
|
end
|
346
522
|
|
347
|
-
|
523
|
+
private
|
524
|
+
|
525
|
+
# Create a document given the provided method and attributes from the
|
526
|
+
# existing selector.
|
348
527
|
#
|
349
|
-
# @
|
350
|
-
# criteria.driver
|
528
|
+
# @api private
|
351
529
|
#
|
352
|
-
# @
|
530
|
+
# @example Create a new document.
|
531
|
+
# criteria.create_document(:new, {})
|
353
532
|
#
|
354
|
-
# @
|
355
|
-
|
356
|
-
|
533
|
+
# @param [ Symbol ] method Either :new or :create.
|
534
|
+
# @param [ Hash ] attrs Additional attributes to use.
|
535
|
+
#
|
536
|
+
# @return [ Document ] The new or saved document.
|
537
|
+
#
|
538
|
+
# @since 3.0.0
|
539
|
+
def create_document(method, attrs = {})
|
540
|
+
klass.__send__(method,
|
541
|
+
selector.reduce(attrs) do |hash, (key, value)|
|
542
|
+
unless key.to_s =~ /\$/ || value.is_a?(Hash)
|
543
|
+
hash[key] = value
|
544
|
+
end
|
545
|
+
hash
|
546
|
+
end
|
547
|
+
)
|
357
548
|
end
|
358
549
|
|
359
550
|
# Clone or dup the current +Criteria+. This will return a new criteria with
|
360
551
|
# the selector, options, klass, embedded options, etc intact.
|
361
552
|
#
|
553
|
+
# @api private
|
554
|
+
#
|
362
555
|
# @example Clone a criteria.
|
363
556
|
# criteria.clone
|
364
557
|
#
|
@@ -368,56 +561,49 @@ module Mongoid #:nodoc:
|
|
368
561
|
# @param [ Criteria ] other The criteria getting cloned.
|
369
562
|
#
|
370
563
|
# @return [ nil ] nil.
|
564
|
+
#
|
565
|
+
# @since 1.0.0
|
371
566
|
def initialize_copy(other)
|
372
567
|
@selector = other.selector.dup
|
373
568
|
@options = other.options.dup
|
374
|
-
@
|
569
|
+
@inclusions = other.inclusions.dup
|
570
|
+
@scoping_options = other.scoping_options
|
571
|
+
@documents = other.documents.dup
|
375
572
|
@context = nil
|
376
573
|
end
|
377
574
|
|
378
575
|
# Used for chaining +Criteria+ scopes together in the for of class methods
|
379
576
|
# on the +Document+ the criteria is for.
|
577
|
+
#
|
578
|
+
# @example Handle method missing.
|
579
|
+
# criteria.method_missing(:name)
|
580
|
+
#
|
581
|
+
# @param [ Symbol ] name The method name.
|
582
|
+
# @param [ Array ] args The arguments.
|
583
|
+
#
|
584
|
+
# @return [ Object ] The result of the method call.
|
585
|
+
#
|
586
|
+
# @since 1.0.0
|
380
587
|
def method_missing(name, *args, &block)
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
@klass.send(name, *args, &block)
|
588
|
+
if klass.respond_to?(name)
|
589
|
+
klass.send(:with_scope, self) do
|
590
|
+
klass.send(name, *args, &block)
|
385
591
|
end
|
386
592
|
else
|
387
593
|
return entries.send(name, *args)
|
388
594
|
end
|
389
595
|
end
|
390
596
|
|
391
|
-
#
|
392
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
# @
|
399
|
-
|
400
|
-
|
401
|
-
clone.tap do |crit|
|
402
|
-
converted = BSON::ObjectId.convert(klass, attributes || {})
|
403
|
-
converted.each_pair do |key, value|
|
404
|
-
existing = crit.selector[key]
|
405
|
-
unless existing
|
406
|
-
crit.selector[key] = { operator => value }
|
407
|
-
else
|
408
|
-
if existing.respond_to?(:merge)
|
409
|
-
if existing.has_key?(operator)
|
410
|
-
new_value = existing.values.first.send(combine, value)
|
411
|
-
crit.selector[key] = { operator => new_value }
|
412
|
-
else
|
413
|
-
crit.selector[key][operator] = value
|
414
|
-
end
|
415
|
-
else
|
416
|
-
crit.selector[key] = { operator => value }
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
end
|
597
|
+
# Convenience method of raising an invalid options error.
|
598
|
+
#
|
599
|
+
# @example Raise the error.
|
600
|
+
# criteria.raise_invalid
|
601
|
+
#
|
602
|
+
# @raise [ Errors::InvalidOptions ] The error.
|
603
|
+
#
|
604
|
+
# @since 2.0.0
|
605
|
+
def raise_invalid
|
606
|
+
raise Errors::InvalidFind.new
|
421
607
|
end
|
422
608
|
end
|
423
609
|
end
|