mongoid 7.4.0 → 8.0.1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +51 -28
- data/lib/mongoid/association/accessors.rb +32 -3
- data/lib/mongoid/association/bindable.rb +48 -0
- data/lib/mongoid/association/builders.rb +4 -2
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +48 -8
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
- data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
- data/lib/mongoid/association/macros.rb +22 -1
- data/lib/mongoid/association/many.rb +5 -0
- data/lib/mongoid/association/nested/many.rb +2 -1
- data/lib/mongoid/association/proxy.rb +12 -0
- data/lib/mongoid/association/referenced/auto_save.rb +3 -2
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -14
- data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
- data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
- data/lib/mongoid/association/referenced/syncable.rb +2 -2
- data/lib/mongoid/association/relatable.rb +38 -4
- data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
- data/lib/mongoid/attributes/processing.rb +9 -2
- data/lib/mongoid/attributes.rb +30 -27
- data/lib/mongoid/changeable.rb +37 -2
- data/lib/mongoid/clients/options.rb +4 -0
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/config/environment.rb +20 -4
- data/lib/mongoid/config.rb +25 -10
- data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +2 -2
- data/lib/mongoid/contextual/memory.rb +176 -17
- data/lib/mongoid/contextual/mongo.rb +226 -206
- data/lib/mongoid/contextual/none.rb +66 -4
- data/lib/mongoid/copyable.rb +32 -8
- data/lib/mongoid/criteria/includable.rb +24 -20
- data/lib/mongoid/criteria/marshalable.rb +10 -2
- data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
- data/lib/mongoid/criteria/queryable/optional.rb +3 -9
- data/lib/mongoid/criteria/queryable/options.rb +1 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +28 -34
- data/lib/mongoid/criteria/queryable/selector.rb +89 -4
- data/lib/mongoid/criteria/queryable/smash.rb +39 -6
- data/lib/mongoid/criteria/queryable.rb +11 -6
- data/lib/mongoid/criteria.rb +1 -26
- data/lib/mongoid/deprecable.rb +36 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +96 -32
- data/lib/mongoid/errors/document_not_found.rb +29 -8
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
- data/lib/mongoid/errors/invalid_field.rb +5 -1
- data/lib/mongoid/errors/invalid_field_type.rb +26 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
- data/lib/mongoid/errors.rb +2 -2
- data/lib/mongoid/extensions/array.rb +8 -6
- data/lib/mongoid/extensions/big_decimal.rb +29 -10
- data/lib/mongoid/extensions/binary.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +8 -2
- data/lib/mongoid/extensions/date.rb +26 -20
- data/lib/mongoid/extensions/date_time.rb +1 -1
- data/lib/mongoid/extensions/float.rb +4 -5
- data/lib/mongoid/extensions/hash.rb +12 -5
- data/lib/mongoid/extensions/integer.rb +4 -5
- data/lib/mongoid/extensions/object.rb +2 -0
- data/lib/mongoid/extensions/range.rb +41 -10
- data/lib/mongoid/extensions/regexp.rb +11 -4
- data/lib/mongoid/extensions/set.rb +11 -4
- data/lib/mongoid/extensions/string.rb +2 -13
- data/lib/mongoid/extensions/symbol.rb +3 -14
- data/lib/mongoid/extensions/time.rb +27 -16
- data/lib/mongoid/extensions/time_with_zone.rb +1 -2
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/factory.rb +42 -7
- data/lib/mongoid/fields/foreign_key.rb +7 -0
- data/lib/mongoid/fields/validators/macro.rb +3 -9
- data/lib/mongoid/fields.rb +194 -28
- data/lib/mongoid/findable.rb +27 -7
- data/lib/mongoid/indexable/specification.rb +1 -1
- data/lib/mongoid/indexable/validators/options.rb +4 -1
- data/lib/mongoid/interceptable.rb +69 -9
- data/lib/mongoid/persistable/creatable.rb +14 -5
- data/lib/mongoid/persistable/updatable.rb +12 -5
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/persistence_context.rb +19 -2
- data/lib/mongoid/query_cache.rb +6 -258
- data/lib/mongoid/railties/controller_runtime.rb +1 -1
- data/lib/mongoid/reloadable.rb +7 -3
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/stateful.rb +27 -1
- data/lib/mongoid/timestamps/created.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/touchable.rb +2 -3
- data/lib/mongoid/traversable.rb +5 -1
- data/lib/mongoid/validatable/uniqueness.rb +2 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +28 -0
- data/lib/mongoid.rb +2 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
- data/spec/config/mongoid.yml +16 -0
- data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
- data/spec/integration/app_spec.rb +28 -26
- data/spec/integration/associations/belongs_to_spec.rb +18 -0
- data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
- data/spec/integration/associations/embedded_spec.rb +15 -0
- data/spec/integration/associations/embeds_many_spec.rb +15 -2
- data/spec/integration/associations/embeds_one_spec.rb +18 -0
- data/spec/integration/associations/foreign_key_spec.rb +9 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
- data/spec/integration/associations/has_one_spec.rb +97 -1
- data/spec/integration/associations/scope_option_spec.rb +1 -1
- data/spec/integration/callbacks_models.rb +95 -1
- data/spec/integration/callbacks_spec.rb +226 -4
- data/spec/integration/criteria/range_spec.rb +95 -1
- data/spec/integration/discriminator_key_spec.rb +115 -76
- data/spec/integration/dots_and_dollars_spec.rb +277 -0
- data/spec/integration/matcher_examples_spec.rb +20 -13
- data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
- data/spec/integration/matcher_operator_spec.rb +3 -5
- data/spec/integration/persistence/range_field_spec.rb +350 -0
- data/spec/lite_spec_helper.rb +1 -1
- data/spec/mongoid/association/counter_cache_spec.rb +1 -1
- data/spec/mongoid/association/depending_spec.rb +9 -9
- data/spec/mongoid/association/eager_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
- data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
- data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
- data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
- data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
- data/spec/mongoid/association/syncable_spec.rb +14 -0
- data/spec/mongoid/atomic/paths_spec.rb +0 -14
- data/spec/mongoid/atomic_spec.rb +22 -0
- data/spec/mongoid/attributes/nested_spec.rb +80 -11
- data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
- data/spec/mongoid/attributes/projector_spec.rb +1 -5
- data/spec/mongoid/attributes_spec.rb +524 -27
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +34 -42
- data/spec/mongoid/clients/options_spec.rb +1 -0
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +32 -2
- data/spec/mongoid/config/environment_spec.rb +39 -1
- data/spec/mongoid/config_spec.rb +104 -13
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
- data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
- data/spec/mongoid/contextual/memory_spec.rb +1337 -69
- data/spec/mongoid/contextual/mongo_spec.rb +1105 -172
- data/spec/mongoid/contextual/none_spec.rb +38 -0
- data/spec/mongoid/copyable_spec.rb +451 -1
- data/spec/mongoid/criteria/findable_spec.rb +86 -210
- data/spec/mongoid/criteria/includable_spec.rb +1492 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
- data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
- data/spec/mongoid/criteria_spec.rb +474 -1198
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
- data/spec/mongoid/errors/no_environment_spec.rb +3 -3
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
- data/spec/mongoid/extensions/array_spec.rb +16 -2
- data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
- data/spec/mongoid/extensions/binary_spec.rb +44 -9
- data/spec/mongoid/extensions/boolean_spec.rb +68 -82
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
- data/spec/mongoid/extensions/date_spec.rb +71 -1
- data/spec/mongoid/extensions/date_time_spec.rb +15 -9
- data/spec/mongoid/extensions/float_spec.rb +48 -76
- data/spec/mongoid/extensions/hash_spec.rb +30 -0
- data/spec/mongoid/extensions/integer_spec.rb +45 -66
- data/spec/mongoid/extensions/range_spec.rb +255 -54
- data/spec/mongoid/extensions/regexp_spec.rb +58 -33
- data/spec/mongoid/extensions/set_spec.rb +106 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -25
- data/spec/mongoid/extensions/symbol_spec.rb +18 -25
- data/spec/mongoid/extensions/time_spec.rb +634 -66
- data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
- data/spec/mongoid/factory_spec.rb +61 -1
- data/spec/mongoid/fields_spec.rb +321 -50
- data/spec/mongoid/findable_spec.rb +80 -15
- data/spec/mongoid/indexable/specification_spec.rb +2 -2
- data/spec/mongoid/indexable_spec.rb +16 -19
- data/spec/mongoid/interceptable_spec.rb +584 -5
- data/spec/mongoid/interceptable_spec_models.rb +235 -4
- data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
- data/spec/mongoid/mongoizable_spec.rb +285 -0
- data/spec/mongoid/persistable/creatable_spec.rb +2 -2
- data/spec/mongoid/persistable/deletable_spec.rb +2 -2
- data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
- data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
- data/spec/mongoid/persistence_context_spec.rb +50 -1
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +0 -154
- data/spec/mongoid/reloadable_spec.rb +35 -2
- data/spec/mongoid/scopable_spec.rb +21 -1
- data/spec/mongoid/shardable_spec.rb +14 -0
- data/spec/mongoid/stateful_spec.rb +28 -0
- data/spec/mongoid/timestamps_spec.rb +390 -0
- data/spec/mongoid/timestamps_spec_models.rb +67 -0
- data/spec/mongoid/touchable_spec.rb +116 -0
- data/spec/mongoid/touchable_spec_models.rb +12 -8
- data/spec/mongoid/traversable_spec.rb +4 -11
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
- data/spec/mongoid/warnings_spec.rb +35 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/constraints.rb +8 -16
- data/spec/shared/lib/mrss/docker_runner.rb +23 -3
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
- data/spec/shared/share/Dockerfile.erb +34 -48
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/server.sh +32 -19
- data/spec/shared/shlib/set_env.sh +37 -0
- data/spec/support/constraints.rb +24 -0
- data/spec/support/macros.rb +39 -0
- data/spec/support/models/augmentation.rb +12 -0
- data/spec/support/models/band.rb +3 -0
- data/spec/support/models/catalog.rb +24 -0
- data/spec/support/models/circus.rb +3 -0
- data/spec/support/models/code.rb +2 -0
- data/spec/support/models/fanatic.rb +8 -0
- data/spec/support/models/implant.rb +9 -0
- data/spec/support/models/label.rb +2 -0
- data/spec/support/models/membership.rb +1 -0
- data/spec/support/models/passport.rb +9 -0
- data/spec/support/models/person.rb +1 -0
- data/spec/support/models/player.rb +2 -0
- data/spec/support/models/powerup.rb +12 -0
- data/spec/support/models/registry.rb +1 -0
- data/spec/support/models/school.rb +14 -0
- data/spec/support/models/shield.rb +18 -0
- data/spec/support/models/student.rb +14 -0
- data/spec/support/models/weapon.rb +12 -0
- data/spec/support/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_azure.json +17 -0
- data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_gcp.json +17 -0
- data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_kmip.json +17 -0
- data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_local.json +18 -0
- data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/spec_config.rb +4 -0
- data.tar.gz.sig +0 -0
- metadata +76 -13
- metadata.gz.sig +0 -0
- data/lib/mongoid/errors/eager_load.rb +0 -23
- data/lib/mongoid/errors/invalid_value.rb +0 -17
- data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -17,6 +17,8 @@ module Mongoid
|
|
17
17
|
include Association::EagerLoadable
|
18
18
|
include Queryable
|
19
19
|
|
20
|
+
Mongoid.deprecate(self, :geo_near)
|
21
|
+
|
20
22
|
# Options constant.
|
21
23
|
OPTIONS = [ :hint,
|
22
24
|
:limit,
|
@@ -35,16 +37,6 @@ module Mongoid
|
|
35
37
|
# @attribute [r] view The Mongo collection view.
|
36
38
|
attr_reader :view
|
37
39
|
|
38
|
-
# Is the context cached?
|
39
|
-
#
|
40
|
-
# @example Is the context cached?
|
41
|
-
# context.cached?
|
42
|
-
#
|
43
|
-
# @return [ true, false ] If the context is cached.
|
44
|
-
def cached?
|
45
|
-
!!@cache
|
46
|
-
end
|
47
|
-
|
48
40
|
# Get the number of documents matching the query.
|
49
41
|
#
|
50
42
|
# @example Get the number of matching documents.
|
@@ -64,7 +56,7 @@ module Mongoid
|
|
64
56
|
# @return [ Integer ] The number of matches.
|
65
57
|
def count(options = {}, &block)
|
66
58
|
return super(&block) if block_given?
|
67
|
-
|
59
|
+
view.count_documents(options)
|
68
60
|
end
|
69
61
|
|
70
62
|
# Get the estimated number of documents matching the query.
|
@@ -83,7 +75,7 @@ module Mongoid
|
|
83
75
|
unless self.criteria.selector.empty?
|
84
76
|
raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
|
85
77
|
end
|
86
|
-
|
78
|
+
view.estimated_document_count(options)
|
87
79
|
end
|
88
80
|
|
89
81
|
# Delete all documents in the database that match the selector.
|
@@ -151,7 +143,6 @@ module Mongoid
|
|
151
143
|
documents_for_iteration.each do |doc|
|
152
144
|
yield_document(doc, &block)
|
153
145
|
end
|
154
|
-
@cache_loaded = true
|
155
146
|
self
|
156
147
|
else
|
157
148
|
to_enum
|
@@ -164,17 +155,11 @@ module Mongoid
|
|
164
155
|
# context.exists?
|
165
156
|
#
|
166
157
|
# @note We don't use count here since Mongo does not use counted
|
167
|
-
# b-tree indexes
|
168
|
-
# used to determine the value.
|
158
|
+
# b-tree indexes.
|
169
159
|
#
|
170
160
|
# @return [ true, false ] If the count is more than zero.
|
171
161
|
def exists?
|
172
|
-
|
173
|
-
return @count > 0 if instance_variable_defined?(:@count)
|
174
|
-
|
175
|
-
try_cache(:exists) do
|
176
|
-
!!(view.projection(_id: 1).limit(1).first)
|
177
|
-
end
|
162
|
+
!!(view.projection(_id: 1).limit(1).first)
|
178
163
|
end
|
179
164
|
|
180
165
|
# Run an explain on the criteria.
|
@@ -248,29 +233,16 @@ module Mongoid
|
|
248
233
|
# @note Automatically adding a sort on _id when no other sort is
|
249
234
|
# defined on the criteria has the potential to cause bad performance issues.
|
250
235
|
# If you experience unexpected poor performance when using #first or #last
|
251
|
-
# and have no sort defined on the criteria, use
|
252
|
-
# Be aware that #
|
236
|
+
# and have no sort defined on the criteria, use #take instead.
|
237
|
+
# Be aware that #take won't guarantee order.
|
253
238
|
#
|
254
|
-
# @param [
|
255
|
-
#
|
256
|
-
# @option opts [ :none ] :id_sort Don't apply a sort on _id if no other sort
|
257
|
-
# is defined on the criteria.
|
239
|
+
# @param [ Integer ] limit The number of documents to return.
|
258
240
|
#
|
259
241
|
# @return [ Document ] The first document.
|
260
|
-
def first(
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
if raw_doc = view.sort(sort).limit(1).first
|
265
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
266
|
-
eager_load([doc]).first
|
267
|
-
end
|
268
|
-
else
|
269
|
-
if raw_doc = view.limit(1).first
|
270
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
271
|
-
eager_load([doc]).first
|
272
|
-
end
|
273
|
-
end
|
242
|
+
def first(limit = nil)
|
243
|
+
sort = view.sort || { _id: 1 }
|
244
|
+
if raw_docs = view.sort(sort).limit(limit || 1).to_a
|
245
|
+
process_raw_docs(raw_docs, limit)
|
274
246
|
end
|
275
247
|
end
|
276
248
|
alias :one :first
|
@@ -279,7 +251,6 @@ module Mongoid
|
|
279
251
|
#
|
280
252
|
# @api private
|
281
253
|
def find_first
|
282
|
-
return documents.first if cached? && cache_loaded?
|
283
254
|
if raw_doc = view.first
|
284
255
|
doc = Factory.from_db(klass, raw_doc, criteria)
|
285
256
|
eager_load([doc]).first
|
@@ -309,29 +280,6 @@ module Mongoid
|
|
309
280
|
GeoNear.new(collection, criteria, coordinates)
|
310
281
|
end
|
311
282
|
|
312
|
-
# Invoke the block for each element of Contextual. Create a new array
|
313
|
-
# containing the values returned by the block.
|
314
|
-
#
|
315
|
-
# If the symbol field name is passed instead of the block, additional
|
316
|
-
# optimizations would be used.
|
317
|
-
#
|
318
|
-
# @example Map by some field.
|
319
|
-
# context.map(:field1)
|
320
|
-
#
|
321
|
-
# @example Map with block.
|
322
|
-
# context.map(&:field1)
|
323
|
-
#
|
324
|
-
# @param [ Symbol ] field The field name.
|
325
|
-
#
|
326
|
-
# @return [ Array ] The result of mapping.
|
327
|
-
def map(field = nil, &block)
|
328
|
-
if block_given?
|
329
|
-
super(&block)
|
330
|
-
else
|
331
|
-
criteria.pluck(field)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
283
|
# Create the new Mongo context. This delegates operations to the
|
336
284
|
# underlying driver.
|
337
285
|
#
|
@@ -340,7 +288,7 @@ module Mongoid
|
|
340
288
|
#
|
341
289
|
# @param [ Criteria ] criteria The criteria.
|
342
290
|
def initialize(criteria)
|
343
|
-
@criteria, @klass
|
291
|
+
@criteria, @klass = criteria, criteria.klass
|
344
292
|
@collection = @klass.collection
|
345
293
|
criteria.send(:merge_type_selection)
|
346
294
|
@view = collection.find(criteria.selector, session: _session)
|
@@ -357,32 +305,26 @@ module Mongoid
|
|
357
305
|
# @note Automatically adding a sort on _id when no other sort is
|
358
306
|
# defined on the criteria has the potential to cause bad performance issues.
|
359
307
|
# If you experience unexpected poor performance when using #first or #last
|
360
|
-
# and have no sort defined on the criteria, use
|
361
|
-
# Be aware that #
|
362
|
-
#
|
363
|
-
# @param [
|
364
|
-
#
|
365
|
-
# @
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
with_inverse_sorting(opts) do
|
370
|
-
if raw_doc = view.limit(1).first
|
371
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
372
|
-
eager_load([doc]).first
|
373
|
-
end
|
374
|
-
end
|
375
|
-
end
|
308
|
+
# and have no sort defined on the criteria, use #take instead.
|
309
|
+
# Be aware that #take won't guarantee order.
|
310
|
+
#
|
311
|
+
# @param [ Integer ] limit The number of documents to return.
|
312
|
+
#
|
313
|
+
# @return [ Document ] The last document.
|
314
|
+
def last(limit = nil)
|
315
|
+
raw_docs = view.sort(inverse_sorting).limit(limit || 1).to_a.reverse
|
316
|
+
process_raw_docs(raw_docs, limit)
|
376
317
|
end
|
377
318
|
|
378
|
-
#
|
319
|
+
# Returns the number of documents in the database matching
|
320
|
+
# the query selector.
|
379
321
|
#
|
380
322
|
# @example Get the length.
|
381
323
|
# context.length
|
382
324
|
#
|
383
325
|
# @return [ Integer ] The number of documents.
|
384
326
|
def length
|
385
|
-
|
327
|
+
self.count
|
386
328
|
end
|
387
329
|
alias :size :length
|
388
330
|
|
@@ -398,6 +340,44 @@ module Mongoid
|
|
398
340
|
@view = view.limit(value) and self
|
399
341
|
end
|
400
342
|
|
343
|
+
# Take the given number of documents from the database.
|
344
|
+
#
|
345
|
+
# @example Take 10 documents
|
346
|
+
# context.take(10)
|
347
|
+
#
|
348
|
+
# @param [ Integer | nil ] limit The number of documents to return or nil.
|
349
|
+
#
|
350
|
+
# @return [ Document | Array<Document> ] The list of documents, or one
|
351
|
+
# document if no value was given.
|
352
|
+
def take(limit = nil)
|
353
|
+
if limit
|
354
|
+
limit(limit).to_a
|
355
|
+
else
|
356
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
357
|
+
# result is not sorted.
|
358
|
+
limit(1).to_a.first
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
# Take one document from the database and raise an error if there are none.
|
363
|
+
#
|
364
|
+
# @example Take a document
|
365
|
+
# context.take!
|
366
|
+
#
|
367
|
+
# @return [ Document ] The document.
|
368
|
+
#
|
369
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
370
|
+
# documents to take.
|
371
|
+
def take!
|
372
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
373
|
+
# result is not sorted.
|
374
|
+
if fst = limit(1).to_a.first
|
375
|
+
fst
|
376
|
+
else
|
377
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
401
381
|
# Initiate a map/reduce operation from the context.
|
402
382
|
#
|
403
383
|
# @example Initiate a map/reduce.
|
@@ -417,9 +397,6 @@ module Mongoid
|
|
417
397
|
# @example Pluck a field.
|
418
398
|
# context.pluck(:_id)
|
419
399
|
#
|
420
|
-
# @note This method will return the raw db values - it performs no custom
|
421
|
-
# serialization.
|
422
|
-
#
|
423
400
|
# @param [ String, Symbol, Array ] fields Fields to pluck.
|
424
401
|
#
|
425
402
|
# @return [ Array<Object, Array> ] The plucked values.
|
@@ -452,6 +429,87 @@ module Mongoid
|
|
452
429
|
end
|
453
430
|
end
|
454
431
|
|
432
|
+
# Pick the single field values from the database.
|
433
|
+
#
|
434
|
+
# @example Pick a field.
|
435
|
+
# context.pick(:_id)
|
436
|
+
#
|
437
|
+
# @param [ String, Symbol, Array ] fields Fields to pick.
|
438
|
+
#
|
439
|
+
# @return [ Object, Array<Object> ] The picked values.
|
440
|
+
def pick(*fields)
|
441
|
+
limit(1).pluck(*fields).first
|
442
|
+
end
|
443
|
+
|
444
|
+
# Get a hash of counts for the values of a single field. For example,
|
445
|
+
# if the following documents were in the database:
|
446
|
+
#
|
447
|
+
# { _id: 1, age: 21 }
|
448
|
+
# { _id: 2, age: 21 }
|
449
|
+
# { _id: 3, age: 22 }
|
450
|
+
#
|
451
|
+
# Model.tally("age")
|
452
|
+
#
|
453
|
+
# would yield the following result:
|
454
|
+
#
|
455
|
+
# { 21 => 2, 22 => 1 }
|
456
|
+
#
|
457
|
+
# When tallying a field inside an array or embeds_many association:
|
458
|
+
#
|
459
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 } ] }
|
460
|
+
# { _id: 2, array: [ { x: 1 }, { x: 2 } ] }
|
461
|
+
# { _id: 3, array: [ { x: 1 }, { x: 3 } ] }
|
462
|
+
#
|
463
|
+
# Model.tally("array.x")
|
464
|
+
#
|
465
|
+
# The keys of the resulting hash are arrays:
|
466
|
+
#
|
467
|
+
# { [ 1, 2 ] => 2, [ 1, 3 ] => 1 }
|
468
|
+
#
|
469
|
+
# Note that if tallying an element in an array of hashes, and the key
|
470
|
+
# doesn't exist in some of the hashes, tally will not include those
|
471
|
+
# nil keys in the resulting hash:
|
472
|
+
#
|
473
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 }, { y: 3 } ] }
|
474
|
+
#
|
475
|
+
# Model.tally("array.x")
|
476
|
+
# # => { [ 1, 2 ] => 1 }
|
477
|
+
#
|
478
|
+
# @param [ String | Symbol ] field The field name.
|
479
|
+
#
|
480
|
+
# @return [ Hash ] The hash of counts.
|
481
|
+
def tally(field)
|
482
|
+
name = klass.cleanse_localized_field_names(field)
|
483
|
+
|
484
|
+
fld = klass.traverse_association_tree(name)
|
485
|
+
pipeline = [ { "$group" => { _id: "$#{name}", counts: { "$sum": 1 } } } ]
|
486
|
+
pipeline.unshift("$match" => view.filter) unless view.filter.blank?
|
487
|
+
|
488
|
+
collection.aggregate(pipeline).reduce({}) do |tallies, doc|
|
489
|
+
is_translation = "#{name}_translations" == field.to_s
|
490
|
+
val = doc["_id"]
|
491
|
+
|
492
|
+
key = if val.is_a?(Array)
|
493
|
+
val.map do |v|
|
494
|
+
demongoize_with_field(fld, v, is_translation)
|
495
|
+
end
|
496
|
+
else
|
497
|
+
demongoize_with_field(fld, val, is_translation)
|
498
|
+
end
|
499
|
+
|
500
|
+
# The only time where a key will already exist in the tallies hash
|
501
|
+
# is when the values are stored differently in the database, but
|
502
|
+
# demongoize to the same value. A good example of when this happens
|
503
|
+
# is when using localized fields. While the server query won't group
|
504
|
+
# together hashes that have other values in different languages, the
|
505
|
+
# demongoized value is just the translation in the current locale,
|
506
|
+
# which can be the same across multiple of those unequal hashes.
|
507
|
+
tallies[key] ||= 0
|
508
|
+
tallies[key] += doc["counts"]
|
509
|
+
tallies
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
455
513
|
# Skips the provided number of documents.
|
456
514
|
#
|
457
515
|
# @example Skip the documents.
|
@@ -518,22 +576,6 @@ module Mongoid
|
|
518
576
|
|
519
577
|
private
|
520
578
|
|
521
|
-
# yield the block given or return the cached value
|
522
|
-
#
|
523
|
-
# @param [ String, Symbol ] key The instance variable name
|
524
|
-
#
|
525
|
-
# @return the result of the block
|
526
|
-
def try_cache(key, &block)
|
527
|
-
unless cached?
|
528
|
-
yield
|
529
|
-
else
|
530
|
-
unless ret = instance_variable_get("@#{key}")
|
531
|
-
instance_variable_set("@#{key}", ret = yield)
|
532
|
-
end
|
533
|
-
ret
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
579
|
# Update the documents for the provided method.
|
538
580
|
#
|
539
581
|
# @api private
|
@@ -594,55 +636,9 @@ module Mongoid
|
|
594
636
|
# Map the inverse sort symbols to the correct MongoDB values.
|
595
637
|
#
|
596
638
|
# @api private
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
def with_inverse_sorting(opts = {})
|
601
|
-
begin
|
602
|
-
if sort = criteria.options[:sort] || ( { _id: 1 } unless opts[:id_sort] == :none )
|
603
|
-
@view = view.sort(Hash[sort.map{|k, v| [k, -1*v]}])
|
604
|
-
end
|
605
|
-
yield
|
606
|
-
ensure
|
607
|
-
apply_option(:sort)
|
608
|
-
end
|
609
|
-
end
|
610
|
-
|
611
|
-
# Is the cache able to be added to?
|
612
|
-
#
|
613
|
-
# @api private
|
614
|
-
#
|
615
|
-
# @example Is the context cacheable?
|
616
|
-
# context.cacheable?
|
617
|
-
#
|
618
|
-
# @return [ true, false ] If caching, and the cache isn't loaded.
|
619
|
-
def cacheable?
|
620
|
-
cached? && !cache_loaded?
|
621
|
-
end
|
622
|
-
|
623
|
-
# Is the cache fully loaded? Will be true if caching after one full
|
624
|
-
# iteration.
|
625
|
-
#
|
626
|
-
# @api private
|
627
|
-
#
|
628
|
-
# @example Is the cache loaded?
|
629
|
-
# context.cache_loaded?
|
630
|
-
#
|
631
|
-
# @return [ true, false ] If the cache is loaded.
|
632
|
-
def cache_loaded?
|
633
|
-
!!@cache_loaded
|
634
|
-
end
|
635
|
-
|
636
|
-
# Get the documents for cached queries.
|
637
|
-
#
|
638
|
-
# @api private
|
639
|
-
#
|
640
|
-
# @example Get the cached documents.
|
641
|
-
# context.documents
|
642
|
-
#
|
643
|
-
# @return [ Array<Document> ] The documents.
|
644
|
-
def documents
|
645
|
-
@documents ||= []
|
639
|
+
def inverse_sorting
|
640
|
+
sort = view.sort || { _id: 1 }
|
641
|
+
Hash[sort.map{|k, v| [k, -1*v]}]
|
646
642
|
end
|
647
643
|
|
648
644
|
# Get the documents the context should iterate. This follows 3 rules:
|
@@ -660,7 +656,6 @@ module Mongoid
|
|
660
656
|
#
|
661
657
|
# @return [ Array<Document>, Mongo::Collection::View ] The docs to iterate.
|
662
658
|
def documents_for_iteration
|
663
|
-
return documents if cached? && !documents.empty?
|
664
659
|
return view unless eager_loadable?
|
665
660
|
docs = view.map{ |doc| Factory.from_db(klass, doc, criteria) }
|
666
661
|
eager_load(docs)
|
@@ -680,7 +675,6 @@ module Mongoid
|
|
680
675
|
doc = document.respond_to?(:_id) ?
|
681
676
|
document : Factory.from_db(klass, document, criteria)
|
682
677
|
yield(doc)
|
683
|
-
documents.push(doc) if cacheable?
|
684
678
|
end
|
685
679
|
|
686
680
|
private
|
@@ -693,6 +687,26 @@ module Mongoid
|
|
693
687
|
collection.write_concern.nil? || collection.write_concern.acknowledged?
|
694
688
|
end
|
695
689
|
|
690
|
+
# Fetch the element from the given hash and demongoize it using the
|
691
|
+
# given field. If the obj is an array, map over it and call this method
|
692
|
+
# on all of its elements.
|
693
|
+
#
|
694
|
+
# @param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from.
|
695
|
+
# @param [ String ] meth The key to fetch from the hash.
|
696
|
+
# @param [ Field ] field The field to use for demongoization.
|
697
|
+
#
|
698
|
+
# @return [ Object ] The demongoized value.
|
699
|
+
#
|
700
|
+
# @api private
|
701
|
+
def fetch_and_demongoize(obj, meth, field)
|
702
|
+
if obj.is_a?(Array)
|
703
|
+
obj.map { |doc| fetch_and_demongoize(doc, meth, field) }
|
704
|
+
else
|
705
|
+
res = obj.try(:fetch, meth, nil)
|
706
|
+
field ? field.demongoize(res) : res.class.demongoize(res)
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
696
710
|
# Extracts the value for the given field name from the given attribute
|
697
711
|
# hash.
|
698
712
|
#
|
@@ -701,24 +715,18 @@ module Mongoid
|
|
701
715
|
#
|
702
716
|
# @param [ Object ] The value for the given field name
|
703
717
|
def extract_value(attrs, field_name)
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
field.demongoize(res)
|
708
|
-
else
|
709
|
-
res.class.demongoize(res)
|
710
|
-
end
|
711
|
-
end
|
718
|
+
i = 1
|
719
|
+
num_meths = field_name.count('.') + 1
|
720
|
+
curr = attrs.dup
|
712
721
|
|
713
|
-
|
714
|
-
|
715
|
-
meths.each_with_index.inject(attrs) do |curr, (meth, i)|
|
722
|
+
klass.traverse_association_tree(field_name) do |meth, obj, is_field|
|
723
|
+
field = obj if is_field
|
716
724
|
is_translation = false
|
717
|
-
if
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
725
|
+
# If no association or field was found, check if the meth is an
|
726
|
+
# _translations field.
|
727
|
+
if obj.nil? & tr = meth.match(/(.*)_translations\z/)&.captures&.first
|
728
|
+
is_translation = true
|
729
|
+
meth = tr
|
722
730
|
end
|
723
731
|
|
724
732
|
# 1. If curr is an array fetch from all elements in the array.
|
@@ -731,31 +739,24 @@ module Mongoid
|
|
731
739
|
# 3. If the meth is an _translations field, do not demongoize the
|
732
740
|
# value so the full hash is returned.
|
733
741
|
# 4. Otherwise, fetch and demongoize the value for the key meth.
|
734
|
-
if curr.is_a? Array
|
735
|
-
res =
|
742
|
+
curr = if curr.is_a? Array
|
743
|
+
res = fetch_and_demongoize(curr, meth, field)
|
736
744
|
res.empty? ? nil : res
|
737
|
-
elsif !is_translation &&
|
738
|
-
if i <
|
745
|
+
elsif !is_translation && field&.localized?
|
746
|
+
if i < num_meths
|
739
747
|
curr.try(:fetch, meth, nil)
|
740
748
|
else
|
741
|
-
fetch_and_demongoize(curr, meth,
|
749
|
+
fetch_and_demongoize(curr, meth, field)
|
742
750
|
end
|
743
751
|
elsif is_translation
|
744
752
|
curr.try(:fetch, meth, nil)
|
745
753
|
else
|
746
|
-
fetch_and_demongoize(curr, meth,
|
747
|
-
end.tap do
|
748
|
-
if as = k.try(:aliased_associations)
|
749
|
-
if a = as.fetch(meth, nil)
|
750
|
-
meth = a
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
|
-
if relation = k.relations[meth]
|
755
|
-
k = relation.klass
|
756
|
-
end
|
754
|
+
fetch_and_demongoize(curr, meth, field)
|
757
755
|
end
|
756
|
+
|
757
|
+
i += 1
|
758
758
|
end
|
759
|
+
curr
|
759
760
|
end
|
760
761
|
|
761
762
|
# Recursively demongoize the given value. This method recursively traverses
|
@@ -768,30 +769,49 @@ module Mongoid
|
|
768
769
|
#
|
769
770
|
# @return [ Object ] The demongoized value.
|
770
771
|
def recursive_demongoize(field_name, value, is_translation)
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
if a = as.fetch(meth, nil)
|
775
|
-
meth = a.to_s
|
776
|
-
end
|
777
|
-
end
|
772
|
+
field = klass.traverse_association_tree(field_name)
|
773
|
+
demongoize_with_field(field, value, is_translation)
|
774
|
+
end
|
778
775
|
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
776
|
+
# Demongoize the value for the given field. If the field is nil or the
|
777
|
+
# field is a translations field, the value is demongoized using its class.
|
778
|
+
#
|
779
|
+
# @param [ Field ] field The field to use to demongoize.
|
780
|
+
# @param [ Object ] value The value to demongoize.
|
781
|
+
# @param [ Boolean ] is_translation The field we are retrieving is an
|
782
|
+
# _translations field.
|
783
|
+
#
|
784
|
+
# @return [ Object ] The demongoized value.
|
785
|
+
#
|
786
|
+
# @api private
|
787
|
+
def demongoize_with_field(field, value, is_translation)
|
788
|
+
if field
|
789
|
+
# If it's a localized field that's not a hash, don't demongoize
|
790
|
+
# again, we already have the translation. If it's an _translations
|
791
|
+
# field, don't demongoize, we want the full hash not just a
|
792
|
+
# specific translation.
|
793
|
+
# If it is a hash, and it's not a translations field, we need to
|
794
|
+
# demongoize to get the correct translation.
|
795
|
+
if field.localized? && (!value.is_a?(Hash) || is_translation)
|
796
|
+
value.class.demongoize(value)
|
791
797
|
else
|
792
|
-
|
798
|
+
field.demongoize(value)
|
793
799
|
end
|
800
|
+
else
|
801
|
+
value.class.demongoize(value)
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
# Process the raw documents retrieved for #first/#last.
|
806
|
+
#
|
807
|
+
# @return [ Array<Document> | Document ] The list of documents or a
|
808
|
+
# single document.
|
809
|
+
def process_raw_docs(raw_docs, limit)
|
810
|
+
docs = raw_docs.map do |d|
|
811
|
+
Factory.from_db(klass, d, criteria)
|
794
812
|
end
|
813
|
+
docs = eager_load(docs)
|
814
|
+
limit ? docs : docs.first
|
795
815
|
end
|
796
816
|
end
|
797
817
|
end
|