mongoid 5.4.1 → 6.0.0.beta
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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/config/locales/en.yml +23 -16
- data/lib/mongoid.rb +4 -9
- data/lib/mongoid/atomic.rb +1 -1
- data/lib/mongoid/atomic/modifiers.rb +8 -12
- data/lib/mongoid/attributes.rb +9 -11
- data/lib/mongoid/attributes/dynamic.rb +5 -6
- data/lib/mongoid/attributes/nested.rb +1 -1
- data/lib/mongoid/attributes/processing.rb +4 -0
- data/lib/mongoid/attributes/readonly.rb +22 -0
- data/lib/mongoid/cacheable.rb +36 -0
- data/lib/mongoid/changeable.rb +37 -1
- data/lib/mongoid/clients.rb +0 -63
- data/lib/mongoid/clients/factory.rb +0 -2
- data/lib/mongoid/clients/options.rb +54 -249
- data/lib/mongoid/clients/storage_options.rb +1 -69
- data/lib/mongoid/composable.rb +26 -2
- data/lib/mongoid/config.rb +1 -1
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -0
- data/lib/mongoid/contextual/atomic.rb +6 -9
- data/lib/mongoid/contextual/geo_near.rb +2 -3
- data/lib/mongoid/contextual/map_reduce.rb +97 -24
- data/lib/mongoid/contextual/memory.rb +7 -4
- data/lib/mongoid/contextual/mongo.rb +63 -54
- data/lib/mongoid/contextual/none.rb +2 -2
- data/lib/mongoid/copyable.rb +19 -19
- data/lib/mongoid/criteria.rb +5 -4
- data/lib/mongoid/criteria/findable.rb +2 -3
- data/lib/mongoid/criteria/includable.rb +63 -16
- data/lib/mongoid/criteria/marshalable.rb +2 -2
- data/lib/mongoid/criteria/modifiable.rb +17 -1
- data/lib/mongoid/criteria/options.rb +25 -0
- data/lib/mongoid/criteria/queryable.rb +86 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
- data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
- data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +45 -0
- data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
- data/lib/mongoid/criteria/queryable/key.rb +103 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
- data/lib/mongoid/criteria/queryable/optional.rb +411 -0
- data/lib/mongoid/criteria/queryable/options.rb +136 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
- data/lib/mongoid/criteria/queryable/selector.rb +196 -0
- data/lib/mongoid/criteria/queryable/smash.rb +103 -0
- data/lib/mongoid/document.rb +9 -23
- data/lib/mongoid/errors.rb +2 -1
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
- data/lib/mongoid/errors/delete_restriction.rb +2 -2
- data/lib/mongoid/errors/invalid_field.rb +2 -2
- data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
- data/lib/mongoid/errors/invalid_relation.rb +66 -0
- data/lib/mongoid/errors/inverse_not_found.rb +1 -1
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions.rb +0 -5
- data/lib/mongoid/extensions/big_decimal.rb +17 -8
- data/lib/mongoid/extensions/date.rb +4 -1
- data/lib/mongoid/extensions/hash.rb +2 -3
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/string.rb +4 -3
- data/lib/mongoid/extensions/time.rb +5 -2
- data/lib/mongoid/factory.rb +1 -0
- data/lib/mongoid/fields/foreign_key.rb +2 -2
- data/lib/mongoid/fields/localized.rb +3 -8
- data/lib/mongoid/fields/validators/macro.rb +18 -0
- data/lib/mongoid/findable.rb +3 -3
- data/lib/mongoid/indexable.rb +17 -16
- data/lib/mongoid/indexable/specification.rb +1 -1
- data/lib/mongoid/indexable/validators/options.rb +1 -2
- data/lib/mongoid/interceptable.rb +6 -17
- data/lib/mongoid/loggable.rb +1 -1
- data/lib/mongoid/matchable.rb +3 -10
- data/lib/mongoid/matchable/gt.rb +2 -0
- data/lib/mongoid/matchable/gte.rb +2 -0
- data/lib/mongoid/matchable/lt.rb +2 -0
- data/lib/mongoid/matchable/lte.rb +2 -0
- data/lib/mongoid/persistable.rb +6 -5
- data/lib/mongoid/persistable/creatable.rb +2 -0
- data/lib/mongoid/persistable/deletable.rb +7 -3
- data/lib/mongoid/persistable/settable.rb +3 -16
- data/lib/mongoid/persistable/updatable.rb +10 -12
- data/lib/mongoid/persistence_context.rb +216 -0
- data/lib/mongoid/query_cache.rb +5 -30
- data/lib/mongoid/relations/accessors.rb +6 -2
- data/lib/mongoid/relations/auto_save.rb +12 -4
- data/lib/mongoid/relations/bindings/embedded/in.rb +4 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +8 -1
- data/lib/mongoid/relations/bindings/embedded/one.rb +10 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +4 -0
- data/lib/mongoid/relations/builders.rb +2 -2
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
- data/lib/mongoid/relations/conversions.rb +1 -1
- data/lib/mongoid/relations/counter_cache.rb +28 -18
- data/lib/mongoid/relations/eager.rb +19 -7
- data/lib/mongoid/relations/eager/base.rb +5 -5
- data/lib/mongoid/relations/embedded/batchable.rb +9 -33
- data/lib/mongoid/relations/embedded/in.rb +16 -2
- data/lib/mongoid/relations/embedded/many.rb +23 -8
- data/lib/mongoid/relations/embedded/one.rb +17 -2
- data/lib/mongoid/relations/macros.rb +9 -2
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/nested_builder.rb +1 -1
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +2 -33
- data/lib/mongoid/relations/referenced/in.rb +23 -11
- data/lib/mongoid/relations/referenced/many.rb +24 -16
- data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
- data/lib/mongoid/relations/referenced/one.rb +17 -1
- data/lib/mongoid/relations/reflections.rb +3 -5
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/reloadable.rb +1 -1
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +2 -3
- data/lib/mongoid/tasks/database.rb +1 -2
- data/lib/mongoid/threaded.rb +4 -4
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/validatable.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +2 -4
- data/lib/mongoid/validatable/uniqueness.rb +1 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -7
- data/spec/app/models/album.rb +5 -1
- data/spec/app/models/artist.rb +21 -0
- data/spec/app/models/band.rb +0 -1
- data/spec/app/models/church.rb +0 -2
- data/spec/app/models/ordered_post.rb +5 -0
- data/spec/app/models/oscar.rb +1 -2
- data/spec/app/models/person.rb +3 -1
- data/spec/app/models/post.rb +0 -1
- data/spec/app/models/princess.rb +2 -0
- data/spec/app/models/record.rb +1 -0
- data/spec/app/models/thing.rb +1 -1
- data/spec/config/mongoid.yml +1 -5
- data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
- data/spec/mongoid/atomic_spec.rb +17 -17
- data/spec/mongoid/attributes/nested_spec.rb +14 -14
- data/spec/mongoid/attributes/readonly_spec.rb +87 -44
- data/spec/mongoid/attributes_spec.rb +63 -0
- data/spec/mongoid/cacheable_spec.rb +112 -0
- data/spec/mongoid/changeable_spec.rb +58 -0
- data/spec/mongoid/clients/factory_spec.rb +3 -11
- data/spec/mongoid/clients/options_spec.rb +378 -96
- data/spec/mongoid/clients_spec.rb +207 -170
- data/spec/mongoid/composable_spec.rb +7 -0
- data/spec/mongoid/config_spec.rb +41 -21
- data/spec/mongoid/contextual/atomic_spec.rb +77 -343
- data/spec/mongoid/contextual/map_reduce_spec.rb +119 -111
- data/spec/mongoid/contextual/memory_spec.rb +56 -316
- data/spec/mongoid/contextual/mongo_spec.rb +104 -378
- data/spec/mongoid/copyable_spec.rb +8 -15
- data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
- data/spec/mongoid/criteria/options_spec.rb +29 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
- data/spec/mongoid/{extensions/origin/regexp_raw_spec.rb → criteria/queryable/extensions/regexp_spec.rb} +21 -20
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1786 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +4159 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +778 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
- data/spec/mongoid/criteria_spec.rb +45 -63
- data/spec/mongoid/document_spec.rb +21 -88
- data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
- data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
- data/spec/mongoid/extensions/date_spec.rb +2 -6
- data/spec/mongoid/extensions/date_time_spec.rb +2 -6
- data/spec/mongoid/extensions/float_spec.rb +8 -1
- data/spec/mongoid/extensions/integer_spec.rb +8 -1
- data/spec/mongoid/extensions/object_spec.rb +11 -0
- data/spec/mongoid/extensions/string_spec.rb +21 -0
- data/spec/mongoid/extensions/time_spec.rb +4 -8
- data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
- data/spec/mongoid/fields/localized_spec.rb +0 -91
- data/spec/mongoid/findable_spec.rb +46 -1
- data/spec/mongoid/indexable_spec.rb +6 -46
- data/spec/mongoid/interceptable_spec.rb +49 -10
- data/spec/mongoid/matchable/gt_spec.rb +11 -0
- data/spec/mongoid/matchable/gte_spec.rb +10 -0
- data/spec/mongoid/matchable/lt_spec.rb +11 -0
- data/spec/mongoid/matchable/lte_spec.rb +11 -0
- data/spec/mongoid/matchable_spec.rb +1 -51
- data/spec/mongoid/persistable/creatable_spec.rb +2 -2
- data/spec/mongoid/persistable/deletable_spec.rb +1 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
- data/spec/mongoid/persistable/savable_spec.rb +30 -30
- data/spec/mongoid/persistable/settable_spec.rb +0 -185
- data/spec/mongoid/persistable/updatable_spec.rb +166 -5
- data/spec/mongoid/persistence_context_spec.rb +654 -0
- data/spec/mongoid/positional_spec.rb +10 -10
- data/spec/mongoid/query_cache_spec.rb +89 -65
- data/spec/mongoid/relations/accessors_spec.rb +1 -1
- data/spec/mongoid/relations/auto_save_spec.rb +39 -6
- data/spec/mongoid/relations/builders_spec.rb +37 -10
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -15
- data/spec/mongoid/relations/cyclic_spec.rb +0 -22
- data/spec/mongoid/relations/embedded/many_spec.rb +9 -41
- data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
- data/spec/mongoid/relations/macros_spec.rb +395 -7
- data/spec/mongoid/relations/proxy_spec.rb +3 -1
- data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +6 -29
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +6 -29
- data/spec/mongoid/relations/reflections_spec.rb +9 -9
- data/spec/mongoid/reloadable_spec.rb +51 -0
- data/spec/mongoid/scopable_spec.rb +0 -12
- data/spec/mongoid/serializable_spec.rb +0 -50
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +16 -9
- data/spec/mongoid/validatable_spec.rb +16 -0
- data/spec/spec_helper.rb +10 -10
- metadata +536 -479
- metadata.gz.sig +0 -0
- data/lib/mongoid/clients/thread_options.rb +0 -19
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +0 -20
- data/lib/mongoid/extensions/decimal128.rb +0 -39
- data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
- data/lib/mongoid/matchable/regexp.rb +0 -27
- data/spec/app/models/post_genre.rb +0 -6
- data/spec/mongoid/extensions/decimal128_spec.rb +0 -44
- data/spec/mongoid/matchable/regexp_spec.rb +0 -59
@@ -57,7 +57,7 @@ module Mongoid
|
|
57
57
|
# @example Allow pluck for null context.
|
58
58
|
# context.pluck(:name)
|
59
59
|
#
|
60
|
-
# @param [ String, Symbol, Array ]
|
60
|
+
# @param [ String, Symbol, Array ] field or fields to pluck.
|
61
61
|
#
|
62
62
|
# @return [ Array ] Emtpy Array
|
63
63
|
def pluck(*args)
|
@@ -69,7 +69,7 @@ module Mongoid
|
|
69
69
|
# @example Create the new context.
|
70
70
|
# Null.new(criteria)
|
71
71
|
#
|
72
|
-
# @param [ Criteria ]
|
72
|
+
# @param [ Criteria ] The criteria.
|
73
73
|
#
|
74
74
|
# @since 4.0.0
|
75
75
|
def initialize(criteria)
|
data/lib/mongoid/copyable.rb
CHANGED
@@ -14,17 +14,26 @@ module Mongoid
|
|
14
14
|
# @example Clone the document.
|
15
15
|
# document.clone
|
16
16
|
#
|
17
|
+
# @param [ Document ] other The document getting cloned.
|
18
|
+
#
|
17
19
|
# @return [ Document ] The new document.
|
18
20
|
def clone
|
19
21
|
# @note This next line is here to address #2704, even though having an
|
20
22
|
# _id and id field in the document would cause problems with Mongoid
|
21
23
|
# elsewhere.
|
22
24
|
attrs = clone_document.except("_id", "id")
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
dynamic_attrs = {}
|
26
|
+
attrs.reject! do |attr_name, value|
|
27
|
+
dynamic_attrs[attr_name] = value unless self.attribute_names.include?(attr_name)
|
28
|
+
end
|
29
|
+
self.class.new(attrs).tap do |object|
|
30
|
+
dynamic_attrs.each do |attr_name, value|
|
31
|
+
if object.respond_to?("#{attr_name}=")
|
32
|
+
object.send("#{attr_name}=", value)
|
33
|
+
else
|
34
|
+
object.attributes[attr_name] = value
|
35
|
+
end
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
alias :dup :clone
|
@@ -38,10 +47,12 @@ module Mongoid
|
|
38
47
|
# @example clone document
|
39
48
|
# model.clone_document
|
40
49
|
#
|
50
|
+
# @param [ Hash ] dcoument The document with hash format
|
51
|
+
#
|
41
52
|
# @since 3.0.22
|
42
53
|
def clone_document
|
43
54
|
attrs = as_document.__deep_copy__
|
44
|
-
process_localized_attributes(
|
55
|
+
process_localized_attributes(attrs)
|
45
56
|
attrs
|
46
57
|
end
|
47
58
|
|
@@ -56,23 +67,12 @@ module Mongoid
|
|
56
67
|
# @param [ Hash ] attrs The attributes.
|
57
68
|
#
|
58
69
|
# @since 3.0.20
|
59
|
-
def process_localized_attributes(
|
60
|
-
|
70
|
+
def process_localized_attributes(attrs)
|
71
|
+
localized_fields.keys.each do |name|
|
61
72
|
if value = attrs.delete(name)
|
62
73
|
attrs["#{name}_translations"] = value
|
63
74
|
end
|
64
75
|
end
|
65
|
-
klass.embedded_relations.each do |_, metadata|
|
66
|
-
next unless attrs.present? && attrs[metadata.key].present?
|
67
|
-
|
68
|
-
if metadata.macro == :embeds_many
|
69
|
-
attrs[metadata.key].each do |attr|
|
70
|
-
process_localized_attributes(metadata.klass, attr)
|
71
|
-
end
|
72
|
-
else
|
73
|
-
process_localized_attributes(metadata.klass, attrs[metadata.key])
|
74
|
-
end
|
75
|
-
end
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -4,7 +4,9 @@ require "mongoid/criteria/includable"
|
|
4
4
|
require "mongoid/criteria/inspectable"
|
5
5
|
require "mongoid/criteria/marshalable"
|
6
6
|
require "mongoid/criteria/modifiable"
|
7
|
+
require "mongoid/criteria/queryable"
|
7
8
|
require "mongoid/criteria/scopable"
|
9
|
+
require "mongoid/criteria/options"
|
8
10
|
|
9
11
|
module Mongoid
|
10
12
|
|
@@ -17,7 +19,7 @@ module Mongoid
|
|
17
19
|
class Criteria
|
18
20
|
include Enumerable
|
19
21
|
include Contextual
|
20
|
-
include
|
22
|
+
include Queryable
|
21
23
|
include Findable
|
22
24
|
include Inspectable
|
23
25
|
include Includable
|
@@ -25,6 +27,7 @@ module Mongoid
|
|
25
27
|
include Modifiable
|
26
28
|
include Scopable
|
27
29
|
include Clients::Options
|
30
|
+
include Options
|
28
31
|
|
29
32
|
# Static array used to check with method missing - we only need to ever
|
30
33
|
# instantiate once.
|
@@ -193,8 +196,6 @@ module Mongoid
|
|
193
196
|
# @since 1.0.0
|
194
197
|
def initialize(klass)
|
195
198
|
@klass = klass
|
196
|
-
@embedded = nil
|
197
|
-
@none = nil
|
198
199
|
klass ? super(klass.aliased_fields, klass.fields) : super({}, {})
|
199
200
|
end
|
200
201
|
|
@@ -386,7 +387,7 @@ module Mongoid
|
|
386
387
|
# @example Add a javascript selection.
|
387
388
|
# criteria.where("this.name == 'syd'")
|
388
389
|
#
|
389
|
-
# @param [ String, Hash ]
|
390
|
+
# @param [ String, Hash ] criterion The javascript or standard selection.
|
390
391
|
#
|
391
392
|
# @raise [ UnsupportedJavascript ] If provided a string and the criteria
|
392
393
|
# is embedded.
|
@@ -8,8 +8,7 @@ module Mongoid
|
|
8
8
|
# @example Execute or raise
|
9
9
|
# criteria.execute_or_raise(id)
|
10
10
|
#
|
11
|
-
# @param [ Object ]
|
12
|
-
# @param [ true, false ] multi Whether there arguments were a list.
|
11
|
+
# @param [ Object ] args The arguments passed.
|
13
12
|
#
|
14
13
|
# @raise [ Errors::DocumentNotFound ] If nothing returned.
|
15
14
|
#
|
@@ -67,7 +66,7 @@ module Mongoid
|
|
67
66
|
# @example Get the documents from the map or criteria.
|
68
67
|
# criteria.multiple_from_map_or_db(ids)
|
69
68
|
#
|
70
|
-
# @param [
|
69
|
+
# @param [ ids ] The searched ids.
|
71
70
|
#
|
72
71
|
# @return [ Array<Document> ] The found documents.
|
73
72
|
def multiple_from_db(ids)
|
@@ -27,7 +27,13 @@ module Mongoid
|
|
27
27
|
#
|
28
28
|
# @since 2.2.0
|
29
29
|
def includes(*relations)
|
30
|
-
|
30
|
+
relations.flatten.each do |relation|
|
31
|
+
if relation.is_a?(Hash)
|
32
|
+
extract_nested_inclusion(klass, relation)
|
33
|
+
else
|
34
|
+
add_inclusion(klass, relation)
|
35
|
+
end
|
36
|
+
end
|
31
37
|
clone
|
32
38
|
end
|
33
39
|
|
@@ -48,7 +54,7 @@ module Mongoid
|
|
48
54
|
# @example Set the inclusions.
|
49
55
|
# criteria.inclusions = [ meta ]
|
50
56
|
#
|
51
|
-
# @param [ Array<Metadata> ]
|
57
|
+
# @param [ Array<Metadata> ] The inclusions.
|
52
58
|
#
|
53
59
|
# @return [ Array<Metadata> ] The new inclusions.
|
54
60
|
#
|
@@ -65,31 +71,72 @@ module Mongoid
|
|
65
71
|
# criteria.add_inclusion(Person, :posts)
|
66
72
|
#
|
67
73
|
# @param [ Class, String, Symbol ] _klass The class or string/symbol of the class name.
|
68
|
-
# @param [ Symbol ]
|
74
|
+
# @param [ Symbol ] relation The relation.
|
69
75
|
#
|
70
76
|
# @raise [ Errors::InvalidIncludes ] If no relation is found.
|
71
77
|
#
|
72
78
|
# @since 5.1.0
|
73
|
-
def add_inclusion(_klass,
|
79
|
+
def add_inclusion(_klass, relation)
|
80
|
+
metadata = get_inclusion_metadata(_klass, relation)
|
81
|
+
raise Errors::InvalidIncludes.new(_klass, [ relation ]) unless metadata
|
74
82
|
inclusions.push(metadata) unless inclusions.include?(metadata)
|
75
83
|
end
|
76
84
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
# Extract inclusion definitions from a list.
|
86
|
+
#
|
87
|
+
# @example Extract the inclusions from a list.
|
88
|
+
# criteria.extract_relations_list(:posts, [{ :alerts => :items }])
|
89
|
+
#
|
90
|
+
# @param [ Symbol ] association The name of the association.
|
91
|
+
# @param [ Array ] relations A list of associations.
|
92
|
+
#
|
93
|
+
# @since 5.1.0
|
94
|
+
def extract_relations_list(association, relations)
|
95
|
+
relations.each do |relation|
|
96
|
+
if relation.is_a?(Hash)
|
97
|
+
extract_nested_inclusion(association, relation)
|
86
98
|
else
|
87
|
-
|
88
|
-
raise Errors::InvalidIncludes.new(_parent_class, [ relation_object ]) unless metadata
|
89
|
-
add_inclusion(_parent_class, metadata)
|
99
|
+
add_inclusion(association, relation)
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
103
|
+
|
104
|
+
# Extract nested inclusion.
|
105
|
+
#
|
106
|
+
# @example Extract the inclusions from a nested definition.
|
107
|
+
# criteria.extract_nested_inclusion(User, { :posts => [:alerts] })
|
108
|
+
#
|
109
|
+
# @param [ Class, Symbol ] _klass The class for which the inclusion should be added.
|
110
|
+
# @param [ Hash ] relation The nested inclusion.
|
111
|
+
#
|
112
|
+
# @since 5.1.0
|
113
|
+
def extract_nested_inclusion(_klass, relation)
|
114
|
+
relation.each do |association, _inclusion|
|
115
|
+
add_inclusion(_klass, association)
|
116
|
+
if _inclusion.is_a?(Array)
|
117
|
+
extract_relations_list(association, _inclusion)
|
118
|
+
else
|
119
|
+
add_inclusion(association, _inclusion)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get the metadata for an inclusion.
|
125
|
+
#
|
126
|
+
# @example Get the metadata for an inclusion definition.
|
127
|
+
# criteria.get_inclusion_metadata(User, :posts)
|
128
|
+
#
|
129
|
+
# @param [ Class, Symbol, String ] _klass The class for determining the association metadata
|
130
|
+
# @param [ Symbol ] association The name of the association.
|
131
|
+
#
|
132
|
+
# @since 5.1.0
|
133
|
+
def get_inclusion_metadata(_klass, association)
|
134
|
+
if _klass.is_a?(Class)
|
135
|
+
_klass.reflect_on_association(association)
|
136
|
+
else
|
137
|
+
_klass.to_s.classify.constantize.reflect_on_association(association)
|
138
|
+
end
|
139
|
+
end
|
93
140
|
end
|
94
141
|
end
|
95
142
|
end
|
@@ -27,8 +27,8 @@ module Mongoid
|
|
27
27
|
def marshal_load(data)
|
28
28
|
@scoping_options, raw_selector, raw_options = data.pop(3)
|
29
29
|
@klass, @driver, @inclusions, @documents, @strategy, @negating = data
|
30
|
-
@selector = load_hash(
|
31
|
-
@options = load_hash(
|
30
|
+
@selector = load_hash(Queryable::Selector, raw_selector)
|
31
|
+
@options = load_hash(Queryable::Options, raw_options)
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
@@ -173,7 +173,7 @@ module Mongoid
|
|
173
173
|
# @since 3.0.0
|
174
174
|
def create_document(method, attrs = nil, &block)
|
175
175
|
attributes = selector.reduce(attrs ? attrs.dup : {}) do |hash, (key, value)|
|
176
|
-
unless key
|
176
|
+
unless invalid_key?(hash, key) || invalid_embedded_doc?(value)
|
177
177
|
hash[key] = value
|
178
178
|
end
|
179
179
|
hash
|
@@ -216,6 +216,22 @@ module Mongoid
|
|
216
216
|
def first_or(method, attrs = {}, &block)
|
217
217
|
first || create_document(method, attrs, &block)
|
218
218
|
end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
def invalid_key?(hash, key)
|
223
|
+
# @todo Change this to BSON::String::ILLEGAL_KEY when ruby driver 2.3.0 is
|
224
|
+
# released and mongoid is updated to depend on driver >= 2.3.0
|
225
|
+
key.to_s =~ Mongoid::Document::ILLEGAL_KEY || hash.key?(key.to_sym) || hash.key?(key)
|
226
|
+
end
|
227
|
+
|
228
|
+
def invalid_embedded_doc?(value)
|
229
|
+
# @todo Change this to BSON::String::ILLEGAL_KEY when ruby driver 2.3.0 is
|
230
|
+
# released and mongoid is updated to depend on driver >= 2.3.0
|
231
|
+
value.is_a?(Hash) && value.any? do |key, v|
|
232
|
+
key.to_s =~ Mongoid::Document::ILLEGAL_KEY || invalid_embedded_doc?(v)
|
233
|
+
end
|
234
|
+
end
|
219
235
|
end
|
220
236
|
end
|
221
237
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
class Criteria
|
4
|
+
|
5
|
+
# Module containing functionality for getting options on a Criteria object.
|
6
|
+
#
|
7
|
+
# @since 6.0.0
|
8
|
+
module Options
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def persistence_context
|
13
|
+
klass.persistence_context
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_persistence_context(options)
|
17
|
+
PersistenceContext.set(klass, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear_persistence_context(original_cluster)
|
21
|
+
PersistenceContext.clear(klass, original_cluster)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/criteria/queryable/extensions"
|
3
|
+
require "mongoid/criteria/queryable/forwardable"
|
4
|
+
require "mongoid/criteria/queryable/key"
|
5
|
+
require "mongoid/criteria/queryable/macroable"
|
6
|
+
require "mongoid/criteria/queryable/mergeable"
|
7
|
+
require "mongoid/criteria/queryable/smash"
|
8
|
+
require "mongoid/criteria/queryable/aggregable"
|
9
|
+
require "mongoid/criteria/queryable/pipeline"
|
10
|
+
require "mongoid/criteria/queryable/optional"
|
11
|
+
require "mongoid/criteria/queryable/options"
|
12
|
+
require "mongoid/criteria/queryable/selectable"
|
13
|
+
require "mongoid/criteria/queryable/selector"
|
14
|
+
|
15
|
+
module Mongoid
|
16
|
+
class Criteria
|
17
|
+
|
18
|
+
# A queryable is any object that needs queryable's dsl injected into it to build
|
19
|
+
# MongoDB queries. For example, a Mongoid::Criteria is an Queryable.
|
20
|
+
#
|
21
|
+
# @example Include queryable functionality.
|
22
|
+
# class Criteria
|
23
|
+
# include Queryable
|
24
|
+
# end
|
25
|
+
module Queryable
|
26
|
+
include Mergeable
|
27
|
+
include Aggregable
|
28
|
+
include Selectable
|
29
|
+
include Optional
|
30
|
+
|
31
|
+
# @attribute [r] aliases The aliases.
|
32
|
+
# @attribute [r] driver The Mongo driver being used.
|
33
|
+
# @attribute [r] serializers The serializers.
|
34
|
+
attr_reader :aliases, :driver, :serializers
|
35
|
+
|
36
|
+
# Is this queryable equal to another object? Is true if the selector and
|
37
|
+
# options are equal.
|
38
|
+
#
|
39
|
+
# @example Are the objects equal?
|
40
|
+
# queryable == criteria
|
41
|
+
#
|
42
|
+
# @param [ Object ] other The object to compare against.
|
43
|
+
#
|
44
|
+
# @return [ true, false ] If the objects are equal.
|
45
|
+
#
|
46
|
+
# @since 1.0.0
|
47
|
+
def ==(other)
|
48
|
+
return false unless other.is_a?(Queryable)
|
49
|
+
selector == other.selector && options == other.options
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initialize the new queryable. Will yield itself to the block if a block
|
53
|
+
# is provided for objects that need additional behaviour.
|
54
|
+
#
|
55
|
+
# @example Initialize the queryable.
|
56
|
+
# Queryable.new
|
57
|
+
#
|
58
|
+
# @param [ Hash ] aliases The optional field aliases.
|
59
|
+
# @param [ Hash ] serializers The optional field serializers.
|
60
|
+
# @param [ Symbol ] driver The driver being used.
|
61
|
+
#
|
62
|
+
# @since 1.0.0
|
63
|
+
def initialize(aliases = {}, serializers = {}, driver = :mongo)
|
64
|
+
@aliases, @driver, @serializers = aliases, driver.to_sym, serializers
|
65
|
+
@options = Options.new(aliases, serializers)
|
66
|
+
@selector = Selector.new(aliases, serializers)
|
67
|
+
@pipeline = Pipeline.new(aliases)
|
68
|
+
yield(self) if block_given?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Handle the creation of a copy via #clone or #dup.
|
72
|
+
#
|
73
|
+
# @example Handle copy initialization.
|
74
|
+
# queryable.initialize_copy(criteria)
|
75
|
+
#
|
76
|
+
# @param [ Queryable ] other The original copy.
|
77
|
+
#
|
78
|
+
# @since 1.0.0
|
79
|
+
def initialize_copy(other)
|
80
|
+
@options = other.options.__deep_copy__
|
81
|
+
@selector = other.selector.__deep_copy__
|
82
|
+
@pipeline = other.pipeline.__deep_copy__
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
class Criteria
|
4
|
+
module Queryable
|
5
|
+
|
6
|
+
# Provides a DSL around crafting aggregation framework commands.
|
7
|
+
#
|
8
|
+
# @since 2.0.0
|
9
|
+
module Aggregable
|
10
|
+
extend Macroable
|
11
|
+
|
12
|
+
# @attribute [r] pipeline The aggregation pipeline.
|
13
|
+
attr_reader :pipeline
|
14
|
+
|
15
|
+
# @attribute [rw] aggregating Flag for whether or not we are aggregating.
|
16
|
+
attr_writer :aggregating
|
17
|
+
|
18
|
+
# Has the aggregable enter an aggregation state. Ie, are only aggregation
|
19
|
+
# operations allowed at this point on.
|
20
|
+
#
|
21
|
+
# @example Is the aggregable aggregating?
|
22
|
+
# aggregable.aggregating?
|
23
|
+
#
|
24
|
+
# @return [ true, false ] If the aggregable is aggregating.
|
25
|
+
#
|
26
|
+
# @since 2.0.0
|
27
|
+
def aggregating?
|
28
|
+
!!@aggregating
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add a group ($group) operation to the aggregation pipeline.
|
32
|
+
#
|
33
|
+
# @example Add a group operation being verbose.
|
34
|
+
# aggregable.group(count: { "$sum" => 1 }, max: { "$max" => "likes" })
|
35
|
+
#
|
36
|
+
# @example Add a group operation using symbol shortcuts.
|
37
|
+
# aggregable.group(:count.sum => 1, :max.max => "likes")
|
38
|
+
#
|
39
|
+
# @param [ Hash ] operation The group operation.
|
40
|
+
#
|
41
|
+
# @return [ Aggregable ] The aggregable.
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def group(operation)
|
45
|
+
aggregation(operation) do |pipeline|
|
46
|
+
pipeline.group(operation)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
key :avg, :override, "$avg"
|
50
|
+
key :max, :override, "$max"
|
51
|
+
key :min, :override, "$min"
|
52
|
+
key :sum, :override, "$sum"
|
53
|
+
key :last, :override, "$last"
|
54
|
+
key :push, :override, "$push"
|
55
|
+
key :first, :override, "$first"
|
56
|
+
key :add_to_set, :override, "$addToSet"
|
57
|
+
|
58
|
+
# Add a projection ($project) to the aggregation pipeline.
|
59
|
+
#
|
60
|
+
# @example Add a projection to the pipeline.
|
61
|
+
# aggregable.project(author: 1, name: 0)
|
62
|
+
#
|
63
|
+
# @param [ Hash ] criterion The projection to make.
|
64
|
+
#
|
65
|
+
# @return [ Aggregable ] The aggregable.
|
66
|
+
#
|
67
|
+
# @since 2.0.0
|
68
|
+
def project(operation = nil)
|
69
|
+
aggregation(operation) do |pipeline|
|
70
|
+
pipeline.project(operation)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Add an unwind ($unwind) to the aggregation pipeline.
|
75
|
+
#
|
76
|
+
# @example Add an unwind to the pipeline.
|
77
|
+
# aggregable.unwind(:field)
|
78
|
+
#
|
79
|
+
# @param [ String, Symbol ] field The name of the field to unwind.
|
80
|
+
#
|
81
|
+
# @return [ Aggregable ] The aggregable.
|
82
|
+
#
|
83
|
+
# @since 2.0.0
|
84
|
+
def unwind(field)
|
85
|
+
aggregation(field) do |pipeline|
|
86
|
+
pipeline.unwind(field)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Add the aggregation operation.
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
#
|
96
|
+
# @example Aggregate on the operation.
|
97
|
+
# aggregation(operation) do |pipeline|
|
98
|
+
# pipeline.push("$project" => operation)
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# @param [ Hash ] operation The operation for the pipeline.
|
102
|
+
#
|
103
|
+
# @return [ Aggregable ] The cloned aggregable.
|
104
|
+
#
|
105
|
+
# @since 2.0.0
|
106
|
+
def aggregation(operation)
|
107
|
+
return self unless operation
|
108
|
+
clone.tap do |query|
|
109
|
+
unless aggregating?
|
110
|
+
query.pipeline.concat(query.selector.to_pipeline)
|
111
|
+
query.pipeline.concat(query.options.to_pipeline)
|
112
|
+
query.aggregating = true
|
113
|
+
end
|
114
|
+
yield(query.pipeline)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|