mongoid 2.8.1 → 3.0.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- 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
|