mongoid 2.4.10 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +949 -10
- data/LICENSE +1 -1
- data/README.md +10 -11
- data/Rakefile +3 -17
- data/lib/config/locales/en.yml +455 -51
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- 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/embedded.rb +4 -5
- data/lib/mongoid/atomic/paths/root.rb +4 -5
- data/lib/mongoid/atomic.rb +70 -16
- data/lib/mongoid/attributes/processing.rb +14 -10
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/attributes.rb +95 -32
- data/lib/mongoid/callbacks.rb +106 -43
- data/lib/mongoid/components.rb +12 -23
- data/lib/mongoid/config/environment.rb +7 -4
- data/lib/mongoid/config/inflections.rb +6 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config.rb +104 -225
- data/lib/mongoid/contextual/aggregable/memory.rb +109 -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 +68 -0
- data/lib/mongoid/contextual/map_reduce.rb +273 -0
- data/lib/mongoid/contextual/memory.rb +406 -0
- data/lib/mongoid/contextual/mongo.rb +662 -0
- data/lib/mongoid/contextual.rb +50 -0
- data/lib/mongoid/copyable.rb +7 -25
- data/lib/mongoid/criteria.rb +515 -245
- 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 +71 -52
- 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_metadata.rb +21 -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/errors.rb +23 -1
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions/array.rb +164 -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 +73 -0
- data/lib/mongoid/extensions/false_class.rb +38 -0
- data/lib/mongoid/extensions/float.rb +56 -0
- data/lib/mongoid/extensions/hash.rb +123 -0
- data/lib/mongoid/extensions/integer.rb +66 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +21 -0
- data/lib/mongoid/extensions/object.rb +238 -0
- data/lib/mongoid/extensions/object_id.rb +54 -0
- data/lib/mongoid/extensions/range.rb +79 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +181 -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 +38 -0
- data/lib/mongoid/extensions.rb +28 -76
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields/foreign_key.rb +150 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +268 -0
- data/lib/mongoid/fields/validators/macro.rb +83 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields.rb +142 -208
- data/lib/mongoid/finders.rb +45 -50
- data/lib/mongoid/hierarchy.rb +44 -15
- data/lib/mongoid/identity_map.rb +49 -21
- data/lib/mongoid/indexes/validators/options.rb +80 -0
- data/lib/mongoid/indexes.rb +66 -15
- data/lib/mongoid/inspection.rb +1 -1
- data/lib/mongoid/json.rb +2 -2
- data/lib/mongoid/loggable.rb +69 -0
- 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/matchers.rb +1 -1
- data/lib/mongoid/multi_parameter_attributes.rb +9 -11
- data/lib/mongoid/nested_attributes.rb +17 -9
- data/lib/mongoid/observer.rb +1 -2
- data/lib/mongoid/paranoia.rb +10 -44
- 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/atomic.rb +2 -2
- 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/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/persistence/operations/upsert.rb +28 -0
- data/lib/mongoid/persistence/operations.rb +22 -19
- data/lib/mongoid/persistence/upsertion.rb +30 -0
- data/lib/mongoid/persistence.rb +94 -39
- data/lib/mongoid/railtie.rb +26 -11
- data/lib/mongoid/railties/database.rake +22 -108
- data/lib/mongoid/relations/accessors.rb +120 -20
- 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 +4 -4
- 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 +5 -5
- data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/many.rb +6 -6
- 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/builders.rb +19 -16
- 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/cascading.rb +10 -7
- data/lib/mongoid/relations/constraint.rb +4 -3
- data/lib/mongoid/relations/conversions.rb +6 -7
- data/lib/mongoid/relations/cyclic.rb +7 -7
- data/lib/mongoid/relations/embedded/batchable.rb +347 -0
- data/lib/mongoid/relations/embedded/in.rb +23 -12
- data/lib/mongoid/relations/embedded/many.rb +100 -161
- data/lib/mongoid/relations/embedded/one.rb +25 -14
- data/lib/mongoid/relations/macros.rb +105 -60
- data/lib/mongoid/relations/many.rb +93 -14
- data/lib/mongoid/relations/metadata.rb +277 -47
- data/lib/mongoid/relations/nested_builder.rb +4 -6
- 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 +62 -31
- data/lib/mongoid/relations/referenced/in.rb +40 -15
- data/lib/mongoid/relations/referenced/many.rb +162 -130
- data/lib/mongoid/relations/referenced/many_to_many.rb +104 -48
- 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/relations/touchable.rb +32 -0
- data/lib/mongoid/relations.rb +22 -6
- data/lib/mongoid/reloading.rb +12 -14
- data/lib/mongoid/scoping.rb +312 -0
- data/lib/mongoid/serialization.rb +94 -42
- data/lib/mongoid/sessions/factory.rb +108 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions.rb +383 -0
- data/lib/mongoid/sharding.rb +6 -6
- data/lib/mongoid/state.rb +6 -7
- data/lib/mongoid/threaded/lifecycle.rb +21 -21
- data/lib/mongoid/threaded/sessions.rb +0 -0
- data/lib/mongoid/threaded.rb +219 -59
- data/lib/mongoid/timestamps/created.rb +8 -4
- data/lib/mongoid/timestamps/timeless.rb +6 -4
- data/lib/mongoid/timestamps/updated.rb +4 -3
- data/lib/mongoid/timestamps.rb +1 -1
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validations/associated.rb +2 -2
- data/lib/mongoid/validations/format.rb +2 -2
- data/lib/mongoid/validations/presence.rb +34 -4
- data/lib/mongoid/validations/uniqueness.rb +11 -12
- data/lib/mongoid/validations.rb +28 -20
- data/lib/mongoid/version.rb +2 -2
- data/lib/mongoid/versioning.rb +25 -26
- data/lib/mongoid.rb +37 -37
- 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 +65 -17
- 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 +73 -26
- metadata +103 -148
- 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/master.rb +0 -45
- data/lib/mongoid/collections/operations.rb +0 -44
- data/lib/mongoid/collections/retry.rb +0 -59
- data/lib/mongoid/collections.rb +0 -120
- data/lib/mongoid/config/database.rb +0 -181
- data/lib/mongoid/config/replset_database.rb +0 -80
- data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
- data/lib/mongoid/contexts/enumerable.rb +0 -313
- data/lib/mongoid/contexts/mongo.rb +0 -487
- data/lib/mongoid/contexts.rb +0 -25
- 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 -108
- 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 -76
- 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/javascript/functions.yml +0 -63
- data/lib/mongoid/javascript.rb +0 -20
- 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/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/embedded/atomic.rb +0 -89
- data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
- data/lib/mongoid/relations/referenced/batch.rb +0 -73
- data/lib/mongoid/safety.rb +0 -105
- data/lib/mongoid/scope.rb +0 -31
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,155 @@ 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
|
-
|
|
103
|
-
|
|
104
|
-
self.selector == other.selector && self.options == other.options
|
|
105
|
-
when Enumerable
|
|
106
|
-
return (execute.entries == other)
|
|
107
|
-
else
|
|
108
|
-
return false
|
|
109
|
-
end
|
|
33
|
+
return super if other.respond_to?(:selector)
|
|
34
|
+
entries == other
|
|
110
35
|
end
|
|
111
36
|
|
|
112
|
-
#
|
|
37
|
+
# Needed to properly get a criteria back as json
|
|
113
38
|
#
|
|
114
|
-
# @example Get the
|
|
115
|
-
#
|
|
39
|
+
# @example Get the criteria as json.
|
|
40
|
+
# Person.where(:title => "Sir").as_json
|
|
116
41
|
#
|
|
117
|
-
# @
|
|
42
|
+
# @param [ Hash ] options Options to pass through to the serializer.
|
|
118
43
|
#
|
|
119
|
-
# @
|
|
120
|
-
def
|
|
121
|
-
|
|
44
|
+
# @return [ String ] The JSON string.
|
|
45
|
+
def as_json(options = nil)
|
|
46
|
+
entries.as_json(options)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Build a document given the selector and return it.
|
|
50
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
|
51
|
+
#
|
|
52
|
+
# @example build the document.
|
|
53
|
+
# Person.where(:title => "Sir").build
|
|
54
|
+
#
|
|
55
|
+
# @example Build with selectors getting ignored.
|
|
56
|
+
# Person.where(:age.gt => 5).build
|
|
57
|
+
#
|
|
58
|
+
# @return [ Document ] A non-persisted document.
|
|
59
|
+
#
|
|
60
|
+
# @since 2.0.0
|
|
61
|
+
def build(attrs = {})
|
|
62
|
+
create_document(:new, attrs)
|
|
63
|
+
end
|
|
64
|
+
alias :new :build
|
|
65
|
+
|
|
66
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
|
67
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
|
68
|
+
# times, however this is not advisable when working with large data sets
|
|
69
|
+
# as the entire results will get stored in memory.
|
|
70
|
+
#
|
|
71
|
+
# @example Flag the criteria as cached.
|
|
72
|
+
# criteria.cache
|
|
73
|
+
#
|
|
74
|
+
# @return [ Criteria ] The cloned criteria.
|
|
75
|
+
def cache
|
|
76
|
+
crit = clone
|
|
77
|
+
crit.options.merge!(cache: true)
|
|
78
|
+
crit
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Will return true if the cache option has been set.
|
|
82
|
+
#
|
|
83
|
+
# @example Is the criteria cached?
|
|
84
|
+
# criteria.cached?
|
|
85
|
+
#
|
|
86
|
+
# @return [ true, false ] If the criteria is flagged as cached.
|
|
87
|
+
def cached?
|
|
88
|
+
options[:cache] == true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Create a document in the database given the selector and return it.
|
|
92
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
|
93
|
+
#
|
|
94
|
+
# @example Create the document.
|
|
95
|
+
# Person.where(:title => "Sir").create
|
|
96
|
+
#
|
|
97
|
+
# @example Create with selectors getting ignored.
|
|
98
|
+
# Person.where(:age.gt => 5).create
|
|
99
|
+
#
|
|
100
|
+
# @return [ Document ] A newly created document.
|
|
101
|
+
#
|
|
102
|
+
# @since 2.0.0.rc.1
|
|
103
|
+
def create(attrs = {})
|
|
104
|
+
create_document(:create, attrs)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Create a document in the database given the selector and return it.
|
|
108
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
|
109
|
+
# If validation fails, an error will be raised.
|
|
110
|
+
#
|
|
111
|
+
# @example Create the document.
|
|
112
|
+
# Person.where(:title => "Sir").create
|
|
113
|
+
#
|
|
114
|
+
# @example Create with selectors getting ignored.
|
|
115
|
+
# Person.where(:age.gt => 5).create
|
|
116
|
+
#
|
|
117
|
+
# @raise [ Errors::Validations ] on a validation error.
|
|
118
|
+
#
|
|
119
|
+
# @return [ Document ] A newly created document.
|
|
120
|
+
#
|
|
121
|
+
# @since 3.0.0
|
|
122
|
+
def create!(attrs = {})
|
|
123
|
+
create_document(:create!, attrs)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Get the documents from the embedded criteria.
|
|
127
|
+
#
|
|
128
|
+
# @example Get the documents.
|
|
129
|
+
# criteria.documents
|
|
130
|
+
#
|
|
131
|
+
# @return [ Array<Document> ] The documents.
|
|
132
|
+
#
|
|
133
|
+
# @since 3.0.0
|
|
134
|
+
def documents
|
|
135
|
+
@documents ||= []
|
|
122
136
|
end
|
|
123
137
|
|
|
124
|
-
#
|
|
138
|
+
# Set the embedded documents on the criteria.
|
|
125
139
|
#
|
|
126
|
-
#
|
|
127
|
-
# otherwise it will return a Mongo context for root classes.
|
|
140
|
+
# @example Set the documents.
|
|
128
141
|
#
|
|
129
|
-
# @
|
|
130
|
-
# criteria.context
|
|
142
|
+
# @param [ Array<Document> ] docs The embedded documents.
|
|
131
143
|
#
|
|
132
|
-
# @return [
|
|
133
|
-
|
|
134
|
-
|
|
144
|
+
# @return [ Array<Document> ] The embedded documents.
|
|
145
|
+
#
|
|
146
|
+
# @since 3.0.0
|
|
147
|
+
def documents=(docs)
|
|
148
|
+
@documents = docs
|
|
135
149
|
end
|
|
136
150
|
|
|
137
|
-
#
|
|
138
|
-
#
|
|
151
|
+
# Is the criteria for embedded documents?
|
|
152
|
+
#
|
|
153
|
+
# @example Is the criteria for embedded documents?
|
|
154
|
+
# criteria.embedded?
|
|
155
|
+
#
|
|
156
|
+
# @return [ true, false ] If the criteria is embedded.
|
|
157
|
+
#
|
|
158
|
+
# @since 3.0.0
|
|
159
|
+
def embedded?
|
|
160
|
+
!!@embedded
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Execute the criteria or raise an error if no documents found.
|
|
164
|
+
#
|
|
165
|
+
# @example Execute or raise
|
|
166
|
+
# criteria.execute_or_raise(id)
|
|
167
|
+
#
|
|
168
|
+
# @param [ Object ] args The arguments passed.
|
|
169
|
+
#
|
|
170
|
+
# @raise [ Errors::DocumentNotFound ] If nothing returned.
|
|
139
171
|
#
|
|
140
|
-
# @
|
|
141
|
-
# criteria.each { |doc| p doc }
|
|
172
|
+
# @return [ Document, Array<Document> ] The document(s).
|
|
142
173
|
#
|
|
143
|
-
# @
|
|
144
|
-
def
|
|
145
|
-
|
|
174
|
+
# @since 2.0.0
|
|
175
|
+
def execute_or_raise(ids, multi)
|
|
176
|
+
result = multiple_from_map_or_db(ids)
|
|
177
|
+
check_for_missing_documents!(result, ids)
|
|
178
|
+
multi ? result : result.first
|
|
146
179
|
end
|
|
147
180
|
|
|
148
181
|
# Return true if the criteria has some Document or not.
|
|
@@ -151,6 +184,8 @@ module Mongoid #:nodoc:
|
|
|
151
184
|
# criteria.exists?
|
|
152
185
|
#
|
|
153
186
|
# @return [ true, false ] If documents match.
|
|
187
|
+
#
|
|
188
|
+
# @since 1.0.0
|
|
154
189
|
def exists?
|
|
155
190
|
context.count > 0
|
|
156
191
|
end
|
|
@@ -165,7 +200,80 @@ module Mongoid #:nodoc:
|
|
|
165
200
|
#
|
|
166
201
|
# @since 2.3.0
|
|
167
202
|
def extract_id
|
|
168
|
-
selector
|
|
203
|
+
selector.extract_id
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
|
207
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
|
208
|
+
#
|
|
209
|
+
# @example Add extra params to the criteria.
|
|
210
|
+
# criteria.extras(:limit => 20, :skip => 40)
|
|
211
|
+
#
|
|
212
|
+
# @param [ Hash ] extras The extra driver options.
|
|
213
|
+
#
|
|
214
|
+
# @return [ Criteria ] The cloned criteria.
|
|
215
|
+
#
|
|
216
|
+
# @since 2.0.0
|
|
217
|
+
def extras(extras)
|
|
218
|
+
crit = clone
|
|
219
|
+
crit.options.merge!(extras)
|
|
220
|
+
crit
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Get the list of included fields.
|
|
224
|
+
#
|
|
225
|
+
# @example Get the field list.
|
|
226
|
+
# criteria.field_list
|
|
227
|
+
#
|
|
228
|
+
# @return [ Array<String> ] The fields.
|
|
229
|
+
#
|
|
230
|
+
# @since 2.0.0
|
|
231
|
+
def field_list
|
|
232
|
+
if options[:fields]
|
|
233
|
+
options[:fields].keys.reject{ |key| key == "_type" }
|
|
234
|
+
else
|
|
235
|
+
[]
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Find the matchind document(s) in the criteria for the provided ids.
|
|
240
|
+
#
|
|
241
|
+
# @example Find by an id.
|
|
242
|
+
# criteria.find(Moped::BSON::ObjectId.new)
|
|
243
|
+
#
|
|
244
|
+
# @example Find by multiple ids.
|
|
245
|
+
# criteria.find([ Moped::BSON::ObjectId.new, Moped::BSON::ObjectId.new ])
|
|
246
|
+
#
|
|
247
|
+
# @param [ Array<Moped::BSON::ObjectId> ] args The ids to search for.
|
|
248
|
+
#
|
|
249
|
+
# @return [ Array<Document>, Document ] The matching document(s).
|
|
250
|
+
#
|
|
251
|
+
# @since 1.0.0
|
|
252
|
+
def find(*args)
|
|
253
|
+
ids = args.__find_args__
|
|
254
|
+
raise_invalid if ids.any?(&:nil?)
|
|
255
|
+
for_ids(ids).execute_or_raise(ids, args.multi_arged?)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
|
259
|
+
#
|
|
260
|
+
# @example Add a single id criteria.
|
|
261
|
+
# criteria.for_ids([ 1 ])
|
|
262
|
+
#
|
|
263
|
+
# @example Add multiple id criteria.
|
|
264
|
+
# criteria.for_ids([ 1, 2 ])
|
|
265
|
+
#
|
|
266
|
+
# @param [ Array ] ids The array of ids.
|
|
267
|
+
#
|
|
268
|
+
# @return [ Criteria ] The cloned criteria.
|
|
269
|
+
def for_ids(ids)
|
|
270
|
+
ids = mongoize_ids(ids)
|
|
271
|
+
method = extract_id ? :all_of : :where
|
|
272
|
+
if ids.size > 1
|
|
273
|
+
send(method, { _id: { "$in" => ids }})
|
|
274
|
+
else
|
|
275
|
+
send(method, { _id: ids.first })
|
|
276
|
+
end
|
|
169
277
|
end
|
|
170
278
|
|
|
171
279
|
# When freezing a criteria we need to initialize the context first
|
|
@@ -182,31 +290,107 @@ module Mongoid #:nodoc:
|
|
|
182
290
|
context and inclusions and super
|
|
183
291
|
end
|
|
184
292
|
|
|
185
|
-
#
|
|
293
|
+
# Get the document from the identity map, and if not found hit the
|
|
294
|
+
# database.
|
|
186
295
|
#
|
|
187
|
-
# @example
|
|
188
|
-
# criteria.
|
|
296
|
+
# @example Get the document from the map or criteria.
|
|
297
|
+
# criteria.from_map_or_db
|
|
189
298
|
#
|
|
190
|
-
# @
|
|
299
|
+
# @return [ Document ] The found document.
|
|
191
300
|
#
|
|
192
|
-
# @
|
|
193
|
-
def
|
|
194
|
-
|
|
195
|
-
|
|
301
|
+
# @since 2.2.1
|
|
302
|
+
def from_map_or_db
|
|
303
|
+
id = extract_id
|
|
304
|
+
id = klass.fields["_id"].mongoize(id) if id
|
|
305
|
+
doc = IdentityMap.get(klass, id || selector.except("_type"))
|
|
306
|
+
doc && doc.matches?(selector) ? doc : first
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Get the documents from the identity map, and if not found hit the
|
|
310
|
+
# database.
|
|
311
|
+
#
|
|
312
|
+
# @example Get the documents from the map or criteria.
|
|
313
|
+
# criteria.multiple_from_map_or_db(ids)
|
|
314
|
+
#
|
|
315
|
+
# @param [ ids ] The searched ids.
|
|
316
|
+
#
|
|
317
|
+
# @return [ Array<Document> ] The found documents.
|
|
318
|
+
def multiple_from_map_or_db(ids)
|
|
319
|
+
return entries if embedded?
|
|
320
|
+
ids = mongoize_ids(ids)
|
|
321
|
+
result = from_identity_map(ids)
|
|
322
|
+
ids.empty? ? result : result + from_database(ids)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Initialize the new criteria.
|
|
326
|
+
#
|
|
327
|
+
# @example Init the new criteria.
|
|
328
|
+
# Criteria.new(Band)
|
|
329
|
+
#
|
|
330
|
+
# @param [ Class ] klass The model class.
|
|
331
|
+
#
|
|
332
|
+
# @since 1.0.0
|
|
333
|
+
def initialize(klass)
|
|
334
|
+
@klass = klass
|
|
335
|
+
super(klass.aliased_fields, klass.fields)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Eager loads all the provided relations. Will load all the documents
|
|
339
|
+
# into the identity map who's ids match based on the extra query for the
|
|
340
|
+
# ids.
|
|
341
|
+
#
|
|
342
|
+
# @note This will only work if Mongoid's identity map is enabled. To do
|
|
343
|
+
# so set identity_map_enabled: true in your mongoid.yml
|
|
344
|
+
#
|
|
345
|
+
# @note This will work for embedded relations that reference another
|
|
346
|
+
# collection via belongs_to as well.
|
|
347
|
+
#
|
|
348
|
+
# @note Eager loading brings all the documents into memory, so there is a
|
|
349
|
+
# sweet spot on the performance gains. Internal benchmarks show that
|
|
350
|
+
# eager loading becomes slower around 100k documents, but this will
|
|
351
|
+
# naturally depend on the specific application.
|
|
352
|
+
#
|
|
353
|
+
# @example Eager load the provided relations.
|
|
354
|
+
# Person.includes(:posts, :game)
|
|
355
|
+
#
|
|
356
|
+
# @param [ Array<Symbol> ] relations The names of the relations to eager
|
|
357
|
+
# load.
|
|
358
|
+
#
|
|
359
|
+
# @return [ Criteria ] The cloned criteria.
|
|
360
|
+
#
|
|
361
|
+
# @since 2.2.0
|
|
362
|
+
def includes(*relations)
|
|
363
|
+
relations.each do |name|
|
|
364
|
+
metadata = klass.reflect_on_association(name)
|
|
365
|
+
inclusions.push(metadata) unless inclusions.include?(metadata)
|
|
196
366
|
end
|
|
367
|
+
clone
|
|
197
368
|
end
|
|
198
369
|
|
|
199
|
-
#
|
|
200
|
-
#
|
|
370
|
+
# Get a list of criteria that are to be executed for eager loading.
|
|
371
|
+
#
|
|
372
|
+
# @example Get the eager loading inclusions.
|
|
373
|
+
# Person.includes(:game).inclusions
|
|
201
374
|
#
|
|
202
|
-
# @
|
|
203
|
-
# Criteria.new(Model, true)
|
|
375
|
+
# @return [ Array<Metadata> ] The inclusions.
|
|
204
376
|
#
|
|
205
|
-
# @
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
377
|
+
# @since 2.2.0
|
|
378
|
+
def inclusions
|
|
379
|
+
@inclusions ||= []
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Set the inclusions for the criteria.
|
|
383
|
+
#
|
|
384
|
+
# @example Set the inclusions.
|
|
385
|
+
# criteria.inclusions = [ meta ]
|
|
386
|
+
#
|
|
387
|
+
# @param [ Array<Metadata> ] The inclusions.
|
|
388
|
+
#
|
|
389
|
+
# @return [ Array<Metadata> ] The new inclusions.
|
|
390
|
+
#
|
|
391
|
+
# @since 3.0.0
|
|
392
|
+
def inclusions=(value)
|
|
393
|
+
@inclusions = value
|
|
210
394
|
end
|
|
211
395
|
|
|
212
396
|
# Merges another object with this +Criteria+ and returns a new criteria.
|
|
@@ -214,26 +398,55 @@ module Mongoid #:nodoc:
|
|
|
214
398
|
# combine multiple scopes together, where a chained scope situation
|
|
215
399
|
# may be desired.
|
|
216
400
|
#
|
|
217
|
-
# @example Merge the criteria with a conditions hash.
|
|
218
|
-
# criteria.merge({ :conditions => { :title => "Sir" } })
|
|
219
|
-
#
|
|
220
401
|
# @example Merge the criteria with another criteria.
|
|
221
402
|
# criteri.merge(other_criteria)
|
|
222
403
|
#
|
|
223
|
-
# @param [ Criteria
|
|
404
|
+
# @param [ Criteria ] other The other criterion to merge with.
|
|
224
405
|
#
|
|
225
406
|
# @return [ Criteria ] A cloned self.
|
|
226
407
|
def merge(other)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
408
|
+
crit = clone
|
|
409
|
+
crit.merge!(other)
|
|
410
|
+
crit
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# Merge the other criteria into this one.
|
|
414
|
+
#
|
|
415
|
+
# @example Merge another criteria into this criteria.
|
|
416
|
+
# criteria.merge(Person.where(name: "bob"))
|
|
417
|
+
#
|
|
418
|
+
# @param [ Criteria ] other The criteria to merge in.
|
|
419
|
+
#
|
|
420
|
+
# @return [ Criteria ] The merged criteria.
|
|
421
|
+
#
|
|
422
|
+
# @since 3.0.0
|
|
423
|
+
def merge!(other)
|
|
424
|
+
criteria = other.to_criteria
|
|
425
|
+
selector.merge!(criteria.selector)
|
|
426
|
+
options.merge!(criteria.options)
|
|
427
|
+
self.documents = criteria.documents.dup unless criteria.documents.empty?
|
|
428
|
+
self.scoping_options = criteria.scoping_options
|
|
429
|
+
self.inclusions = (inclusions + criteria.inclusions.dup).uniq
|
|
430
|
+
self
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# Overriden to include _type in the fields.
|
|
434
|
+
#
|
|
435
|
+
# @example Limit the fields returned from the database.
|
|
436
|
+
# Band.only(:name)
|
|
437
|
+
#
|
|
438
|
+
# @param [ Array<Symbol> ] args The names of the fields.
|
|
439
|
+
#
|
|
440
|
+
# @return [ Criteria ] The cloned criteria.
|
|
441
|
+
#
|
|
442
|
+
# @since 1.0.0
|
|
443
|
+
def only(*args)
|
|
444
|
+
return clone if args.empty?
|
|
445
|
+
args = args.flatten
|
|
446
|
+
if klass.hereditary?
|
|
447
|
+
super(*args.push(:_type))
|
|
448
|
+
else
|
|
449
|
+
super(*args)
|
|
237
450
|
end
|
|
238
451
|
end
|
|
239
452
|
|
|
@@ -247,117 +460,127 @@ module Mongoid #:nodoc:
|
|
|
247
460
|
#
|
|
248
461
|
# @return [ true, false ] If the criteria responds to the method.
|
|
249
462
|
def respond_to?(name, include_private = false)
|
|
250
|
-
|
|
251
|
-
super || @klass.respond_to?(name) || entries.respond_to?(name, include_private)
|
|
463
|
+
super || klass.respond_to?(name) || entries.respond_to?(name, include_private)
|
|
252
464
|
end
|
|
253
465
|
|
|
254
|
-
|
|
255
|
-
|
|
466
|
+
alias :to_ary :to_a
|
|
467
|
+
|
|
468
|
+
# Convenience for objects that want to be merged into a criteria.
|
|
256
469
|
#
|
|
257
|
-
# @example
|
|
258
|
-
# criteria.
|
|
470
|
+
# @example Convert to a criteria.
|
|
471
|
+
# criteria.to_criteria
|
|
472
|
+
#
|
|
473
|
+
# @return [ Criteria ] self.
|
|
259
474
|
#
|
|
260
|
-
# @
|
|
261
|
-
def
|
|
262
|
-
|
|
263
|
-
sorting = scope_options.delete(:sort)
|
|
264
|
-
scope_options[:order_by] = sorting if sorting
|
|
265
|
-
scope_options[:includes] = inclusions.map(&:name) if inclusions.any?
|
|
266
|
-
{ :where => @selector }.merge(scope_options)
|
|
475
|
+
# @since 3.0.0
|
|
476
|
+
def to_criteria
|
|
477
|
+
self
|
|
267
478
|
end
|
|
268
|
-
alias :to_ary :to_a
|
|
269
479
|
|
|
270
|
-
#
|
|
480
|
+
# Convert the criteria to a proc.
|
|
271
481
|
#
|
|
272
|
-
# @example
|
|
273
|
-
#
|
|
482
|
+
# @example Convert the criteria to a proc.
|
|
483
|
+
# criteria.to_proc
|
|
274
484
|
#
|
|
275
|
-
# @
|
|
485
|
+
# @return [ Proc ] The wrapped criteria.
|
|
276
486
|
#
|
|
277
|
-
# @
|
|
278
|
-
def
|
|
279
|
-
|
|
487
|
+
# @since 3.0.0
|
|
488
|
+
def to_proc
|
|
489
|
+
->{ self }
|
|
280
490
|
end
|
|
281
491
|
|
|
282
|
-
#
|
|
492
|
+
# Adds a criterion to the +Criteria+ that specifies a type or an Array of
|
|
493
|
+
# types that must be matched.
|
|
283
494
|
#
|
|
284
|
-
# @example
|
|
285
|
-
# criteria.
|
|
495
|
+
# @example Match only specific models.
|
|
496
|
+
# criteria.type('Browser')
|
|
497
|
+
# criteria.type(['Firefox', 'Browser'])
|
|
286
498
|
#
|
|
287
|
-
# @
|
|
288
|
-
# criteria.search([ BSON::ObjectId.new, BSON::ObjectId.new ])
|
|
499
|
+
# @param [ Array<String> ] types The types to match against.
|
|
289
500
|
#
|
|
290
|
-
# @
|
|
291
|
-
|
|
501
|
+
# @return [ Criteria ] The cloned criteria.
|
|
502
|
+
def type(types)
|
|
503
|
+
any_in(_type: Array(types))
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
# This is the general entry point for most MongoDB queries. This either
|
|
507
|
+
# creates a standard field: value selection, and expanded selection with
|
|
508
|
+
# the use of hash methods, or a $where selection if a string is provided.
|
|
292
509
|
#
|
|
293
|
-
# @example
|
|
294
|
-
# criteria.
|
|
510
|
+
# @example Add a standard selection.
|
|
511
|
+
# criteria.where(name: "syd")
|
|
295
512
|
#
|
|
296
|
-
# @example
|
|
297
|
-
# criteria.
|
|
513
|
+
# @example Add a javascript selection.
|
|
514
|
+
# criteria.where("this.name == 'syd'")
|
|
298
515
|
#
|
|
299
|
-
# @param [
|
|
300
|
-
# argument to search with.
|
|
301
|
-
# @param [ Hash ] options The options to search with.
|
|
516
|
+
# @param [ String, Hash ] criterion The javascript or standard selection.
|
|
302
517
|
#
|
|
303
|
-
# @
|
|
518
|
+
# @raise [ UnsupportedJavascript ] If provided a string and the criteria
|
|
519
|
+
# is embedded.
|
|
304
520
|
#
|
|
305
|
-
# @
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
conditions = params.delete(:conditions) || {}
|
|
312
|
-
if conditions.include?(:id)
|
|
313
|
-
conditions[:_id] = conditions[:id]
|
|
314
|
-
conditions.delete(:id)
|
|
521
|
+
# @return [ Criteria ] The cloned selectable.
|
|
522
|
+
#
|
|
523
|
+
# @since 1.0.0
|
|
524
|
+
def where(expression)
|
|
525
|
+
if expression.is_a?(::String) && embedded?
|
|
526
|
+
raise Errors::UnsupportedJavascript.new(klass, expression)
|
|
315
527
|
end
|
|
316
|
-
|
|
528
|
+
super
|
|
317
529
|
end
|
|
318
530
|
|
|
319
|
-
|
|
531
|
+
private
|
|
532
|
+
|
|
533
|
+
# Are documents in the query missing, and are we configured to raise an
|
|
534
|
+
# error?
|
|
320
535
|
#
|
|
321
|
-
# @
|
|
322
|
-
# criteria.raise_invalid
|
|
536
|
+
# @api private
|
|
323
537
|
#
|
|
324
|
-
# @
|
|
538
|
+
# @example Check for missing documents.
|
|
539
|
+
# criteria.check_for_missing_documents!([], [ 1 ])
|
|
325
540
|
#
|
|
326
|
-
# @
|
|
327
|
-
|
|
328
|
-
raise Errors::InvalidFind.new
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
protected
|
|
332
|
-
|
|
333
|
-
# Return the entries of the other criteria or the object. Used for
|
|
334
|
-
# comparing criteria or an enumerable.
|
|
335
|
-
#
|
|
336
|
-
# @example Get the comparable version.
|
|
337
|
-
# criteria.comparable(other)
|
|
541
|
+
# @param [ Array<Document> ] result The result.
|
|
542
|
+
# @param [ Array<Object> ] ids The ids.
|
|
338
543
|
#
|
|
339
|
-
# @
|
|
544
|
+
# @raise [ Errors::DocumentNotFound ] If none are found and raising an
|
|
545
|
+
# error.
|
|
340
546
|
#
|
|
341
|
-
# @
|
|
342
|
-
def
|
|
343
|
-
|
|
547
|
+
# @since 3.0.0
|
|
548
|
+
def check_for_missing_documents!(result, ids)
|
|
549
|
+
if (result.size < ids.size) && Mongoid.raise_not_found_error
|
|
550
|
+
raise Errors::DocumentNotFound.new(klass, ids, ids - result.map(&:_id))
|
|
551
|
+
end
|
|
344
552
|
end
|
|
345
553
|
|
|
346
|
-
#
|
|
554
|
+
# Create a document given the provided method and attributes from the
|
|
555
|
+
# existing selector.
|
|
347
556
|
#
|
|
348
|
-
# @
|
|
349
|
-
# criteria.driver
|
|
557
|
+
# @api private
|
|
350
558
|
#
|
|
351
|
-
# @
|
|
559
|
+
# @example Create a new document.
|
|
560
|
+
# criteria.create_document(:new, {})
|
|
352
561
|
#
|
|
353
|
-
# @
|
|
354
|
-
|
|
355
|
-
|
|
562
|
+
# @param [ Symbol ] method Either :new or :create.
|
|
563
|
+
# @param [ Hash ] attrs Additional attributes to use.
|
|
564
|
+
#
|
|
565
|
+
# @return [ Document ] The new or saved document.
|
|
566
|
+
#
|
|
567
|
+
# @since 3.0.0
|
|
568
|
+
def create_document(method, attrs = {})
|
|
569
|
+
klass.__send__(method,
|
|
570
|
+
selector.reduce(attrs) do |hash, (key, value)|
|
|
571
|
+
unless key.to_s =~ /\$/ || value.is_a?(Hash)
|
|
572
|
+
hash[key] = value
|
|
573
|
+
end
|
|
574
|
+
hash
|
|
575
|
+
end
|
|
576
|
+
)
|
|
356
577
|
end
|
|
357
578
|
|
|
358
579
|
# Clone or dup the current +Criteria+. This will return a new criteria with
|
|
359
580
|
# the selector, options, klass, embedded options, etc intact.
|
|
360
581
|
#
|
|
582
|
+
# @api private
|
|
583
|
+
#
|
|
361
584
|
# @example Clone a criteria.
|
|
362
585
|
# criteria.clone
|
|
363
586
|
#
|
|
@@ -367,55 +590,102 @@ module Mongoid #:nodoc:
|
|
|
367
590
|
# @param [ Criteria ] other The criteria getting cloned.
|
|
368
591
|
#
|
|
369
592
|
# @return [ nil ] nil.
|
|
593
|
+
#
|
|
594
|
+
# @since 1.0.0
|
|
370
595
|
def initialize_copy(other)
|
|
371
596
|
@selector = other.selector.dup
|
|
372
597
|
@options = other.options.dup
|
|
373
|
-
@
|
|
598
|
+
@inclusions = other.inclusions.dup
|
|
599
|
+
@scoping_options = other.scoping_options
|
|
600
|
+
@documents = other.documents.dup
|
|
374
601
|
@context = nil
|
|
375
602
|
end
|
|
376
603
|
|
|
604
|
+
# Get documents from the database only.
|
|
605
|
+
#
|
|
606
|
+
# @api private
|
|
607
|
+
#
|
|
608
|
+
# @example Get documents from the database.
|
|
609
|
+
# criteria.from_database(ids)
|
|
610
|
+
#
|
|
611
|
+
# @param [ Array<Object> ] ids The ids to fetch with.
|
|
612
|
+
#
|
|
613
|
+
# @return [ Array<Document> ] The matching documents.
|
|
614
|
+
#
|
|
615
|
+
# @since 3.0.0
|
|
616
|
+
def from_database(ids)
|
|
617
|
+
(ids.size > 1 ? any_in(id: ids) : where(id: ids.first)).entries
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
# Get documents from the identity map only.
|
|
621
|
+
#
|
|
622
|
+
# @api private
|
|
623
|
+
#
|
|
624
|
+
# @example Get documents from the identity map.
|
|
625
|
+
# criteria.from_identity_map(ids)
|
|
626
|
+
#
|
|
627
|
+
# @param [ Array<Object> ] ids The ids to fetch with.
|
|
628
|
+
#
|
|
629
|
+
# @return [ Array<Document> ] The matching documents.
|
|
630
|
+
#
|
|
631
|
+
# @since 3.0.0
|
|
632
|
+
def from_identity_map(ids)
|
|
633
|
+
result = []
|
|
634
|
+
ids.reject! do |id|
|
|
635
|
+
doc = IdentityMap.get(klass, id)
|
|
636
|
+
doc && doc.matches?(selector) ? result.push(doc) : false
|
|
637
|
+
end
|
|
638
|
+
result
|
|
639
|
+
end
|
|
640
|
+
|
|
377
641
|
# Used for chaining +Criteria+ scopes together in the for of class methods
|
|
378
642
|
# on the +Document+ the criteria is for.
|
|
643
|
+
#
|
|
644
|
+
# @example Handle method missing.
|
|
645
|
+
# criteria.method_missing(:name)
|
|
646
|
+
#
|
|
647
|
+
# @param [ Symbol ] name The method name.
|
|
648
|
+
# @param [ Array ] args The arguments.
|
|
649
|
+
#
|
|
650
|
+
# @return [ Object ] The result of the method call.
|
|
651
|
+
#
|
|
652
|
+
# @since 1.0.0
|
|
379
653
|
def method_missing(name, *args, &block)
|
|
380
|
-
if
|
|
381
|
-
|
|
382
|
-
|
|
654
|
+
if klass.respond_to?(name)
|
|
655
|
+
klass.send(:with_scope, self) do
|
|
656
|
+
klass.send(name, *args, &block)
|
|
383
657
|
end
|
|
384
658
|
else
|
|
385
659
|
return entries.send(name, *args)
|
|
386
660
|
end
|
|
387
661
|
end
|
|
388
662
|
|
|
389
|
-
#
|
|
390
|
-
#
|
|
391
|
-
#
|
|
392
|
-
#
|
|
393
|
-
#
|
|
394
|
-
#
|
|
395
|
-
#
|
|
396
|
-
# @param [
|
|
397
|
-
#
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
end
|
|
416
|
-
end
|
|
417
|
-
end
|
|
418
|
-
end
|
|
663
|
+
# Convert all the ids to their proper types.
|
|
664
|
+
#
|
|
665
|
+
# @api private
|
|
666
|
+
#
|
|
667
|
+
# @example Convert the ids.
|
|
668
|
+
# criteria.mongoize_ids(ids)
|
|
669
|
+
#
|
|
670
|
+
# @param [ Array<Object> ] ids The ids to convert.
|
|
671
|
+
#
|
|
672
|
+
# @return [ Array<Object> ] The converted ids.
|
|
673
|
+
#
|
|
674
|
+
# @since 3.0.0
|
|
675
|
+
def mongoize_ids(ids)
|
|
676
|
+
ids.map{ |id| klass.fields["_id"].mongoize(id) }
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# Convenience method of raising an invalid options error.
|
|
680
|
+
#
|
|
681
|
+
# @example Raise the error.
|
|
682
|
+
# criteria.raise_invalid
|
|
683
|
+
#
|
|
684
|
+
# @raise [ Errors::InvalidOptions ] The error.
|
|
685
|
+
#
|
|
686
|
+
# @since 2.0.0
|
|
687
|
+
def raise_invalid
|
|
688
|
+
raise Errors::InvalidFind.new
|
|
419
689
|
end
|
|
420
690
|
end
|
|
421
691
|
end
|