mongoid 7.6.2 → 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 +2 -0
- data/README.md +3 -3
- data/Rakefile +21 -85
- data/lib/config/locales/en.yml +46 -56
- 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/depending.rb +4 -8
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +28 -5
- 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 +2 -1
- data/lib/mongoid/association/many.rb +5 -0
- data/lib/mongoid/association/nested/many.rb +5 -39
- data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
- 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 -18
- data/lib/mongoid/association/referenced/has_many/proxy.rb +11 -107
- 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/attributes/processing.rb +9 -2
- data/lib/mongoid/attributes.rb +30 -27
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/changeable.rb +37 -2
- data/lib/mongoid/clients/factory.rb +0 -4
- data/lib/mongoid/clients/options.rb +4 -0
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/config.rb +15 -73
- data/lib/mongoid/contextual/aggregable/memory.rb +22 -20
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +2 -2
- data/lib/mongoid/contextual/memory.rb +63 -47
- data/lib/mongoid/contextual/mongo.rb +173 -287
- data/lib/mongoid/contextual/none.rb +33 -15
- 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 -15
- 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 -16
- 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 +0 -12
- 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 +2 -133
- data/lib/mongoid/criteria/queryable/selector.rb +90 -5
- data/lib/mongoid/criteria/queryable/smash.rb +39 -6
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/criteria/queryable.rb +11 -6
- data/lib/mongoid/criteria.rb +1 -28
- data/lib/mongoid/deprecable.rb +36 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +88 -33
- data/lib/mongoid/equality.rb +4 -4
- data/lib/mongoid/errors/document_not_found.rb +6 -2
- 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 -3
- 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 +13 -32
- 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 +49 -7
- data/lib/mongoid/findable.rb +21 -16
- 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/matchable.rb +1 -6
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
- data/lib/mongoid/matcher/regex.rb +9 -8
- data/lib/mongoid/matcher.rb +0 -1
- data/lib/mongoid/persistable/creatable.rb +14 -5
- data/lib/mongoid/persistable/updatable.rb +12 -5
- data/lib/mongoid/persistence_context.rb +8 -42
- 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/scopable.rb +9 -11
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/shardable.rb +11 -35
- data/lib/mongoid/stateful.rb +27 -1
- data/lib/mongoid/threaded.rb +0 -3
- 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 +1 -0
- data/lib/mongoid/validatable/uniqueness.rb +2 -1
- data/lib/mongoid/version.rb +1 -5
- data/lib/mongoid/warnings.rb +3 -5
- data/lib/mongoid.rb +1 -0
- data/spec/config/mongoid.yml +16 -0
- data/spec/integration/app_spec.rb +8 -20
- data/spec/integration/associations/belongs_to_spec.rb +18 -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/i18n_fallbacks_spec.rb +1 -15
- data/spec/integration/matcher_examples_spec.rb +20 -13
- data/spec/integration/matcher_operator_data/regex.yml +0 -21
- 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/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 +198 -8
- data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -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 +36 -51
- 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 +2 -56
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +60 -156
- 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/attributes/nested_spec.rb +73 -198
- 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 +480 -27
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +22 -60
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +2 -2
- data/spec/mongoid/config_spec.rb +52 -15
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +371 -231
- 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 +467 -156
- data/spec/mongoid/contextual/mongo_spec.rb +566 -426
- data/spec/mongoid/contextual/none_spec.rb +11 -19
- data/spec/mongoid/copyable_spec.rb +451 -2
- 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/bignum_spec.rb +1 -2
- 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/fixnum_spec.rb +1 -2
- 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 -2
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -200
- data/spec/mongoid/criteria/queryable/selector_spec.rb +16 -77
- data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
- data/spec/mongoid/criteria_spec.rb +469 -1203
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/equality_spec.rb +12 -12
- data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
- 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 -236
- 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 +64 -29
- 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 +24 -0
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +1 -156
- data/spec/mongoid/reloadable_spec.rb +35 -2
- data/spec/mongoid/scopable_spec.rb +36 -34
- data/spec/mongoid/serializable_spec.rb +14 -7
- data/spec/mongoid/shardable_models.rb +0 -14
- data/spec/mongoid/shardable_spec.rb +61 -153
- 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/mongoid_spec.rb +1 -7
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/cluster_config.rb +40 -5
- data/spec/shared/lib/mrss/constraints.rb +46 -7
- data/spec/shared/lib/mrss/docker_runner.rb +21 -17
- data/spec/shared/lib/mrss/eg_config_utils.rb +31 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
- data/spec/shared/lib/mrss/lite_constraints.rb +2 -10
- data/spec/shared/lib/mrss/server_version_registry.rb +29 -18
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
- data/spec/shared/lib/mrss/utils.rb +6 -28
- data/spec/shared/share/Dockerfile.erb +114 -38
- data/spec/shared/shlib/distro.sh +0 -10
- data/spec/shared/shlib/server.sh +83 -64
- data/spec/shared/shlib/set_env.sh +81 -16
- data/spec/support/constraints.rb +24 -0
- data/spec/support/expectations.rb +17 -20
- data/spec/support/macros.rb +30 -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/fanatic.rb +8 -0
- data/spec/support/models/implant.rb +9 -0
- data/spec/support/models/label.rb +2 -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.tar.gz.sig +0 -0
- metadata +695 -650
- metadata.gz.sig +0 -0
- data/lib/mongoid/errors/eager_load.rb +0 -23
- data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
- data/lib/mongoid/errors/invalid_value.rb +0 -17
- data/lib/mongoid/field_readable.rb +0 -70
- data/lib/mongoid/matcher/regexp_budget.rb +0 -389
- data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
- data/spec/integration/query_operator_guard_spec.rb +0 -89
- data/spec/mongoid/errors/eager_load_spec.rb +0 -31
- data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
- data/spec/shared/CANDIDATE.md +0 -28
- data/spec/shared/lib/mrss/release/candidate.rb +0 -287
- data/spec/shared/lib/mrss/release/product_data.rb +0 -144
- data/spec/shared/lib/tasks/candidate.rake +0 -64
|
@@ -240,19 +240,15 @@ module Mongoid
|
|
|
240
240
|
# @note Automatically adding a sort on _id when no other sort is
|
|
241
241
|
# defined on the criteria has the potential to cause bad performance issues.
|
|
242
242
|
# If you experience unexpected poor performance when using #first or #last,
|
|
243
|
-
# use
|
|
244
|
-
# Be aware that #
|
|
243
|
+
# use #take instead.
|
|
244
|
+
# Be aware that #take won't guarantee order.
|
|
245
245
|
#
|
|
246
|
-
# @param [ Integer
|
|
247
|
-
# return, or a hash of options.
|
|
248
|
-
#
|
|
249
|
-
# @option limit_or_opts [ :none ] :id_sort This option is deprecated.
|
|
250
|
-
# Don't apply a sort on _id if no other sort is defined on the criteria.
|
|
246
|
+
# @param [ Integer ] limit The number of documents to return.
|
|
251
247
|
#
|
|
252
248
|
# @return [ Document ] The first document found.
|
|
253
|
-
def first(
|
|
249
|
+
def first(limit = nil)
|
|
254
250
|
_loaded.try(:values).try(:first) ||
|
|
255
|
-
_added[(ul = _unloaded.try(:first,
|
|
251
|
+
_added[(ul = _unloaded.try(:first, limit)).try(:_id)] ||
|
|
256
252
|
ul ||
|
|
257
253
|
_added.values.try(:first)
|
|
258
254
|
end
|
|
@@ -329,20 +325,16 @@ module Mongoid
|
|
|
329
325
|
# @note Automatically adding a sort on _id when no other sort is
|
|
330
326
|
# defined on the criteria has the potential to cause bad performance issues.
|
|
331
327
|
# If you experience unexpected poor performance when using #first or #last,
|
|
332
|
-
# use
|
|
333
|
-
# Be aware that #
|
|
334
|
-
#
|
|
335
|
-
# @param [ Integer | Hash ] limit_or_opts The number of documents to
|
|
336
|
-
# return, or a hash of options.
|
|
328
|
+
# use #take instead.
|
|
329
|
+
# Be aware that #take won't guarantee order.
|
|
337
330
|
#
|
|
338
|
-
# @
|
|
339
|
-
# Don't apply a sort on _id if no other sort is defined on the criteria.
|
|
331
|
+
# @param [ Integer ] limit The number of documents to return.
|
|
340
332
|
#
|
|
341
333
|
# @return [ Document ] The last document found.
|
|
342
|
-
def last(
|
|
334
|
+
def last(limit = nil)
|
|
343
335
|
_added.values.try(:last) ||
|
|
344
336
|
_loaded.try(:values).try(:last) ||
|
|
345
|
-
_added[(ul = _unloaded.try(:last,
|
|
337
|
+
_added[(ul = _unloaded.try(:last, limit)).try(:_id)] ||
|
|
346
338
|
ul
|
|
347
339
|
end
|
|
348
340
|
|
|
@@ -71,10 +71,11 @@ module Mongoid
|
|
|
71
71
|
#
|
|
72
72
|
# @return [ Document ] The new document.
|
|
73
73
|
def build(attributes = {}, type = nil)
|
|
74
|
-
doc = Factory.
|
|
74
|
+
doc = Factory.execute_build(type || klass, attributes, execute_callbacks: false)
|
|
75
75
|
append(doc)
|
|
76
76
|
doc.apply_post_processed_defaults
|
|
77
77
|
yield(doc) if block_given?
|
|
78
|
+
doc.run_pending_callbacks
|
|
78
79
|
doc.run_callbacks(:build) { doc }
|
|
79
80
|
doc
|
|
80
81
|
end
|
|
@@ -92,13 +93,15 @@ module Mongoid
|
|
|
92
93
|
#
|
|
93
94
|
# @return [ Document ] The matching document.
|
|
94
95
|
def delete(document)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
execute_callbacks_around(:remove, document) do
|
|
97
|
+
_target.delete(document) do |doc|
|
|
98
|
+
if doc
|
|
99
|
+
unbind_one(doc)
|
|
100
|
+
cascade!(doc) if !_assigning?
|
|
101
|
+
end
|
|
102
|
+
end.tap do
|
|
103
|
+
reset_unloaded
|
|
100
104
|
end
|
|
101
|
-
execute_callback :after_remove, doc
|
|
102
105
|
end
|
|
103
106
|
end
|
|
104
107
|
|
|
@@ -467,111 +470,12 @@ module Mongoid
|
|
|
467
470
|
# @return [ Integer ] The number of documents deleted.
|
|
468
471
|
def remove_all(conditions = nil, method = :delete_all)
|
|
469
472
|
selector = conditions || {}
|
|
470
|
-
selector.merge!(criteria.selector)
|
|
471
|
-
|
|
472
|
-
# Scanning before the delete means scanning only what is already in
|
|
473
|
-
# memory, so it is only done where there is a pattern whose cost has
|
|
474
|
-
# to be bounded. Everywhere else the delete comes first and the scan
|
|
475
|
-
# sees the survivors, which is what this association has always
|
|
476
|
-
# done.
|
|
477
|
-
#
|
|
478
|
-
# The limit is read once and carried into whichever branch is taken.
|
|
479
|
-
# Letting the branch below ask again would read it a second time,
|
|
480
|
-
# across a server round trip, and a limit that had become positive
|
|
481
|
-
# in the meantime would put a deadline on the delete_if -- a query,
|
|
482
|
-
# and an unbind of every match -- which is the arrangement this
|
|
483
|
-
# branch exists to avoid.
|
|
484
|
-
limit = Matcher::RegexpBudget.limit_for(selector)
|
|
485
|
-
return remove_all_bounded(selector, method, limit) if limit
|
|
486
|
-
|
|
487
|
-
removed = klass.send(method, selector)
|
|
488
|
-
|
|
489
|
-
# No scope around this. The scan runs after the delete, so the
|
|
490
|
-
# association this loads comes back holding only what the delete did
|
|
491
|
-
# not match, and there is no pattern here to bound in any case.
|
|
492
|
-
# Opening a scope would save _matches? from deciding once per
|
|
493
|
-
# document -- 0.48us against 1.74us for the match itself -- but a
|
|
494
|
-
# scope with nothing to bound suppresses that decision for
|
|
495
|
-
# everything nested inside it, and loading the association runs
|
|
496
|
-
# find callbacks. A pattern in a selector one of those evaluates
|
|
497
|
-
# would go unguarded, which costs more than the saving is worth on a
|
|
498
|
-
# path that has just made two round trips.
|
|
473
|
+
removed = klass.send(method, selector.merge!(criteria.selector))
|
|
499
474
|
_target.delete_if do |doc|
|
|
500
475
|
doc._matches?(selector).tap do |b|
|
|
501
476
|
unbind_one(doc) if b
|
|
502
477
|
end
|
|
503
478
|
end
|
|
504
|
-
|
|
505
|
-
removed
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
# Deletes all related documents matching a selector that carries a
|
|
509
|
-
# regular expression, with the whole scan under one regexp budget.
|
|
510
|
-
#
|
|
511
|
-
# The scan runs before anything is deleted, so a budget that runs out
|
|
512
|
-
# leaves both the database and the association untouched rather than
|
|
513
|
-
# reporting a failure for a delete that has already happened. It also
|
|
514
|
-
# means the budget is closed by the time the association is mutated,
|
|
515
|
-
# so where the budget is enforced with Timeout there is no window for
|
|
516
|
-
# the exception to land in the middle of an unbind.
|
|
517
|
-
#
|
|
518
|
-
# @param [ Hash ] selector The selector to delete with.
|
|
519
|
-
# @param [ Symbol ] method The deletion method to call.
|
|
520
|
-
# @param [ Float ] limit The seconds the scan may spend, as read by
|
|
521
|
-
# the caller when it chose this path.
|
|
522
|
-
#
|
|
523
|
-
# @return [ Integer ] The number of documents deleted.
|
|
524
|
-
def remove_all_bounded(selector, method, limit)
|
|
525
|
-
# Only what the association already holds. Iterating it instead
|
|
526
|
-
# would load the whole association before the delete, and for a
|
|
527
|
-
# broad pattern that is every document the association has: /.*/ is
|
|
528
|
-
# both the cheapest pattern an attacker can supply and the one that
|
|
529
|
-
# matches everything, so bounding the cost of the matching would
|
|
530
|
-
# have been paid for with an unbounded amount of memory. Nothing is
|
|
531
|
-
# missed by not loading, because the server evaluates the same
|
|
532
|
-
# selector for the delete itself.
|
|
533
|
-
#
|
|
534
|
-
# It also means the scan runs no query, so no deadline of ours can
|
|
535
|
-
# land on one. Where the budget is enforced with Timeout, covering
|
|
536
|
-
# a query would report a slow network as a regexp timeout and could
|
|
537
|
-
# deliver the asynchronous exception inside the driver's socket
|
|
538
|
-
# read.
|
|
539
|
-
documents = _target.in_memory
|
|
540
|
-
|
|
541
|
-
matching = Matcher::RegexpBudget.open_with(limit) do
|
|
542
|
-
documents.select { |doc| doc._matches?(selector) }
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
removed = klass.send(method, selector)
|
|
546
|
-
|
|
547
|
-
# The ids are already known to be in memory, so the loaded and added
|
|
548
|
-
# documents can be dropped directly. Enumerable#delete would look
|
|
549
|
-
# each one up by id and stop at the first hash that has it, which
|
|
550
|
-
# removes the wrong instance when both hashes hold one for the same
|
|
551
|
-
# id. Enumerable#delete_if drops it from both, as this does, but
|
|
552
|
-
# only after load_all!, which is the load this scan exists to avoid.
|
|
553
|
-
#
|
|
554
|
-
# Which documents get unbound has always depended on which ones
|
|
555
|
-
# happened to be in memory, and scanning only what is in memory
|
|
556
|
-
# keeps that. It matters for has_and_belongs_to_many, whose
|
|
557
|
-
# unbind_one pulls the id out of the foreign key array on _base and
|
|
558
|
-
# marks it dirty; the scan used to run after the delete, against an
|
|
559
|
-
# association that a cold proxy had just reloaded as holding only
|
|
560
|
-
# the survivors, so nothing matched and nothing was unbound.
|
|
561
|
-
#
|
|
562
|
-
# TODO: unbinding should not depend on what was in memory. Every
|
|
563
|
-
# matched document leaves the association, so every one of them
|
|
564
|
-
# should be unbound, which would also stop _base's foreign key
|
|
565
|
-
# array from keeping ids that no longer resolve. That is a
|
|
566
|
-
# behaviour change for has_and_belongs_to_many and belongs in a
|
|
567
|
-
# ticket of its own, with a release note; it should not ride along
|
|
568
|
-
# on this one.
|
|
569
|
-
matching.each do |doc|
|
|
570
|
-
unbind_one(doc)
|
|
571
|
-
_target._loaded.delete(doc._id)
|
|
572
|
-
_target._added.delete(doc._id)
|
|
573
|
-
end
|
|
574
|
-
|
|
575
479
|
removed
|
|
576
480
|
end
|
|
577
481
|
|
|
@@ -49,17 +49,14 @@ module Mongoid
|
|
|
49
49
|
#
|
|
50
50
|
# @return [ One ] The association.
|
|
51
51
|
def substitute(replacement)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
send(_association.dependent)
|
|
61
|
-
else
|
|
62
|
-
save if persisted?
|
|
52
|
+
if self != replacement
|
|
53
|
+
unbind_one
|
|
54
|
+
if persistable?
|
|
55
|
+
if _association.destructive?
|
|
56
|
+
send(_association.dependent)
|
|
57
|
+
else
|
|
58
|
+
save if persisted?
|
|
59
|
+
end
|
|
63
60
|
end
|
|
64
61
|
end
|
|
65
62
|
HasOne::Proxy.new(_base, replacement, _association) if replacement
|
|
@@ -67,8 +67,8 @@ module Mongoid
|
|
|
67
67
|
#
|
|
68
68
|
# @return [ Object ] The updated values.
|
|
69
69
|
def update_inverse_keys(association)
|
|
70
|
-
if
|
|
71
|
-
old, new =
|
|
70
|
+
if previous_changes.has_key?(association.foreign_key)
|
|
71
|
+
old, new = previous_changes[association.foreign_key]
|
|
72
72
|
adds, subs = new - (old || []), (old || []) - new
|
|
73
73
|
|
|
74
74
|
# If we are autosaving we don't want a duplicate to get added - the
|
|
@@ -242,7 +242,7 @@ module Mongoid
|
|
|
242
242
|
#
|
|
243
243
|
# @return [ String ] The foreign key check.
|
|
244
244
|
def foreign_key_check
|
|
245
|
-
@foreign_key_check ||= "#{foreign_key}
|
|
245
|
+
@foreign_key_check ||= "#{foreign_key}_previously_changed?" if (stores_foreign_key? && foreign_key)
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
# Create an association proxy object using the owner and target.
|
|
@@ -299,6 +299,35 @@ module Mongoid
|
|
|
299
299
|
end
|
|
300
300
|
end
|
|
301
301
|
|
|
302
|
+
# @return [ Array<String> ] The associations above this one in the inclusion tree.
|
|
303
|
+
attr_accessor :parent_inclusions
|
|
304
|
+
|
|
305
|
+
def parent_inclusions
|
|
306
|
+
@parent_inclusions ||= []
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Is this association an embeds_many or has_many association?
|
|
310
|
+
#
|
|
311
|
+
# @return [ true | false ] true if it is a *_many association, false if not.
|
|
312
|
+
def many?
|
|
313
|
+
[Referenced::HasMany, Embedded::EmbedsMany].any? { |a| self.is_a?(a) }
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Is this association an embeds_one or has_one association?
|
|
317
|
+
#
|
|
318
|
+
# @return [ true | false ] true if it is a *_one association, false if not.
|
|
319
|
+
def one?
|
|
320
|
+
[Referenced::HasOne, Embedded::EmbedsOne].any? { |a| self.is_a?(a) }
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Is this association an embedded_in or belongs_to association?
|
|
324
|
+
#
|
|
325
|
+
# @return [ true | false ] true if it is an embedded_in or belongs_to
|
|
326
|
+
# association, false if not.
|
|
327
|
+
def in_to?
|
|
328
|
+
[Referenced::BelongsTo, Embedded::EmbeddedIn].any? { |a| self.is_a?(a) }
|
|
329
|
+
end
|
|
330
|
+
|
|
302
331
|
private
|
|
303
332
|
|
|
304
333
|
# Gets the model classes with inverse associations of this model. This is used to determine
|
|
@@ -404,10 +433,15 @@ module Mongoid
|
|
|
404
433
|
def namespace_hierarchy(mod)
|
|
405
434
|
parent = Object
|
|
406
435
|
hier = [parent]
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
436
|
+
|
|
437
|
+
# name is not present on anonymous modules
|
|
438
|
+
if mod.name
|
|
439
|
+
mod.name.split('::').each do |part|
|
|
440
|
+
parent = parent.const_get(part)
|
|
441
|
+
hier << parent
|
|
442
|
+
end
|
|
410
443
|
end
|
|
444
|
+
|
|
411
445
|
hier.reverse
|
|
412
446
|
end
|
|
413
447
|
|
|
@@ -43,11 +43,18 @@ module Mongoid
|
|
|
43
43
|
# @return [ true, false ] True if pending, false if not.
|
|
44
44
|
def pending_attribute?(key, value)
|
|
45
45
|
name = key.to_s
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
aliased = if aliased_associations.key?(name)
|
|
48
|
+
aliased_associations[name]
|
|
49
|
+
else
|
|
50
|
+
name
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if relations.has_key?(aliased)
|
|
47
54
|
pending_relations[name] = value
|
|
48
55
|
return true
|
|
49
56
|
end
|
|
50
|
-
if nested_attributes.has_key?(
|
|
57
|
+
if nested_attributes.has_key?(aliased)
|
|
51
58
|
pending_nested[name] = value
|
|
52
59
|
return true
|
|
53
60
|
end
|
data/lib/mongoid/attributes.rb
CHANGED
|
@@ -86,10 +86,26 @@ module Mongoid
|
|
|
86
86
|
def read_attribute(name)
|
|
87
87
|
field = fields[name.to_s]
|
|
88
88
|
raw = read_raw_attribute(name)
|
|
89
|
-
|
|
89
|
+
process_raw_attribute(name.to_s, raw, field)
|
|
90
90
|
end
|
|
91
91
|
alias :[] :read_attribute
|
|
92
92
|
|
|
93
|
+
|
|
94
|
+
# Process the raw attribute values just read from the documents attributes.
|
|
95
|
+
#
|
|
96
|
+
# @param [ String ] name The name of the attribute to get.
|
|
97
|
+
# @param [ Object ] raw The raw attribute value.
|
|
98
|
+
# @param [ Field | nil ] field The field to use for demongoization or nil.
|
|
99
|
+
#
|
|
100
|
+
# @return [ Object ] The value of the attribute.
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
def process_raw_attribute(name, raw, field)
|
|
104
|
+
value = field ? field.demongoize(raw) : raw
|
|
105
|
+
attribute_will_change!(name) if value.resizable?
|
|
106
|
+
value
|
|
107
|
+
end
|
|
108
|
+
|
|
93
109
|
# Read a value from the attributes before type cast. If the value has not
|
|
94
110
|
# yet been assigned then this will return the attribute's existing value
|
|
95
111
|
# using read_raw_attribute.
|
|
@@ -121,6 +137,7 @@ module Mongoid
|
|
|
121
137
|
# @raise [ Errors::ReadonlyAttribute ] If the field cannot be removed due
|
|
122
138
|
# to being flagged as reaodnly.
|
|
123
139
|
def remove_attribute(name)
|
|
140
|
+
validate_writable_field_name!(name.to_s)
|
|
124
141
|
as_writable_attribute!(name) do |access|
|
|
125
142
|
_assigning do
|
|
126
143
|
attribute_will_change!(access)
|
|
@@ -143,6 +160,8 @@ module Mongoid
|
|
|
143
160
|
# @param [ String, Symbol ] name The name of the attribute to update.
|
|
144
161
|
# @param [ Object ] value The value to set for the attribute.
|
|
145
162
|
def write_attribute(name, value)
|
|
163
|
+
validate_writable_field_name!(name.to_s)
|
|
164
|
+
|
|
146
165
|
field_name = database_field_name(name)
|
|
147
166
|
|
|
148
167
|
if attribute_missing?(field_name)
|
|
@@ -151,7 +170,6 @@ module Mongoid
|
|
|
151
170
|
|
|
152
171
|
if attribute_writable?(field_name)
|
|
153
172
|
_assigning do
|
|
154
|
-
validate_attribute_value(field_name, value)
|
|
155
173
|
localized = fields[field_name].try(:localized?)
|
|
156
174
|
attributes_before_type_cast[name.to_s] = value
|
|
157
175
|
typed_value = typed_value_for(field_name, value)
|
|
@@ -164,6 +182,11 @@ module Mongoid
|
|
|
164
182
|
else
|
|
165
183
|
attributes[field_name] = typed_value
|
|
166
184
|
end
|
|
185
|
+
|
|
186
|
+
# when writing an attribute, also remove it from the unsets,
|
|
187
|
+
# so that removing then writing doesn't result in a removal.
|
|
188
|
+
delayed_atomic_unsets.delete(field_name)
|
|
189
|
+
|
|
167
190
|
typed_value
|
|
168
191
|
end
|
|
169
192
|
else
|
|
@@ -266,7 +289,11 @@ module Mongoid
|
|
|
266
289
|
end
|
|
267
290
|
|
|
268
291
|
if hash_dot_syntax?(normalized)
|
|
269
|
-
|
|
292
|
+
if fields.key?(normalized)
|
|
293
|
+
attributes[normalized]
|
|
294
|
+
else
|
|
295
|
+
attributes.__nested__(normalized)
|
|
296
|
+
end
|
|
270
297
|
else
|
|
271
298
|
attributes[normalized]
|
|
272
299
|
end
|
|
@@ -325,30 +352,6 @@ module Mongoid
|
|
|
325
352
|
|
|
326
353
|
private
|
|
327
354
|
|
|
328
|
-
# Validates an attribute value as being assignable to the specified field.
|
|
329
|
-
#
|
|
330
|
-
# For now, only Hash and Array fields are validated, and the value is
|
|
331
|
-
# being checked to be of an appropriate type (i.e. either Hash or Array,
|
|
332
|
-
# respectively, or nil).
|
|
333
|
-
#
|
|
334
|
-
# This method takes the name of the field as stored in the document
|
|
335
|
-
# in the database, not (necessarily) the Ruby method name used to read/write
|
|
336
|
-
# the said field.
|
|
337
|
-
#
|
|
338
|
-
# @param [ String, Symbol ] field_name The name of the field.
|
|
339
|
-
# @param [ Object ] value The value to be validated.
|
|
340
|
-
def validate_attribute_value(field_name, value)
|
|
341
|
-
return if value.nil?
|
|
342
|
-
field = fields[field_name]
|
|
343
|
-
return unless field
|
|
344
|
-
validatable_types = [ Hash, Array ]
|
|
345
|
-
if validatable_types.include?(field.type)
|
|
346
|
-
unless value.is_a?(field.type)
|
|
347
|
-
raise Mongoid::Errors::InvalidValue.new(field.type, value.class)
|
|
348
|
-
end
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
|
|
352
355
|
def lookup_attribute_presence(name, value)
|
|
353
356
|
if localized_fields.has_key?(name) && value
|
|
354
357
|
value = localized_fields[name].send(:lookup, value)
|
data/lib/mongoid/cacheable.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Mongoid
|
|
|
15
15
|
# plural model name.
|
|
16
16
|
#
|
|
17
17
|
# If new_record? - will append /new
|
|
18
|
-
# If not - will append /id-updated_at.
|
|
18
|
+
# If not - will append /id-updated_at.to_s(cache_timestamp_format)
|
|
19
19
|
# Without updated_at - will append /id
|
|
20
20
|
#
|
|
21
21
|
# This is usually called inside a cache() block
|
|
@@ -26,7 +26,7 @@ module Mongoid
|
|
|
26
26
|
# @return [ String ] the string with or without updated_at
|
|
27
27
|
def cache_key
|
|
28
28
|
return "#{model_key}/new" if new_record?
|
|
29
|
-
return "#{model_key}/#{_id}-#{updated_at.utc.
|
|
29
|
+
return "#{model_key}/#{_id}-#{updated_at.utc.to_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
|
|
30
30
|
"#{model_key}/#{_id}"
|
|
31
31
|
end
|
|
32
32
|
end
|
data/lib/mongoid/changeable.rb
CHANGED
|
@@ -62,13 +62,14 @@ module Mongoid
|
|
|
62
62
|
|
|
63
63
|
# Call this method after save, so the changes can be properly switched.
|
|
64
64
|
#
|
|
65
|
-
# This will unset the memoized children array, set new record to
|
|
65
|
+
# This will unset the memoized children array, set new record flag to
|
|
66
66
|
# false, set the document as validated, and move the dirty changes.
|
|
67
67
|
#
|
|
68
68
|
# @example Move the changes to previous.
|
|
69
69
|
# person.move_changes
|
|
70
70
|
def move_changes
|
|
71
71
|
@previous_changes = changes
|
|
72
|
+
@previous_attributes = attributes.dup
|
|
72
73
|
Atomic::UPDATES.each do |update|
|
|
73
74
|
send(update).clear
|
|
74
75
|
end
|
|
@@ -81,6 +82,7 @@ module Mongoid
|
|
|
81
82
|
# document.post_persist
|
|
82
83
|
def post_persist
|
|
83
84
|
reset_persisted_descendants
|
|
85
|
+
reset_attributes_before_type_cast
|
|
84
86
|
move_changes
|
|
85
87
|
end
|
|
86
88
|
|
|
@@ -133,6 +135,13 @@ module Mongoid
|
|
|
133
135
|
|
|
134
136
|
private
|
|
135
137
|
|
|
138
|
+
# Get attributes of the document before the document was saved.
|
|
139
|
+
#
|
|
140
|
+
# @return [ Hash ] Previous attributes
|
|
141
|
+
def previous_attributes
|
|
142
|
+
@previous_attributes ||= {}
|
|
143
|
+
end
|
|
144
|
+
|
|
136
145
|
# Get the old and new value for the provided attribute.
|
|
137
146
|
#
|
|
138
147
|
# @example Get the attribute change.
|
|
@@ -185,6 +194,25 @@ module Mongoid
|
|
|
185
194
|
attribute_changed?(attr) ? changed_attributes[attr] : attributes[attr]
|
|
186
195
|
end
|
|
187
196
|
|
|
197
|
+
# Get the previous attribute value that was changed
|
|
198
|
+
# before the document was saved.
|
|
199
|
+
#
|
|
200
|
+
# It the document has not been saved yet, or was just loaded from database,
|
|
201
|
+
# this method returns nil for all attributes.
|
|
202
|
+
#
|
|
203
|
+
# @param [ String ] attr The attribute name.
|
|
204
|
+
#
|
|
205
|
+
# @return [ Object | nil ] Attribute value before the document was saved,
|
|
206
|
+
# or nil if the document has not been saved yet.
|
|
207
|
+
def attribute_previously_was(attr)
|
|
208
|
+
attr = database_field_name(attr)
|
|
209
|
+
if previous_changes.key?(attr)
|
|
210
|
+
previous_changes[attr].first
|
|
211
|
+
else
|
|
212
|
+
previous_attributes[attr]
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
188
216
|
# Flag an attribute as going to change.
|
|
189
217
|
#
|
|
190
218
|
# @example Flag the attribute.
|
|
@@ -221,6 +249,10 @@ module Mongoid
|
|
|
221
249
|
end
|
|
222
250
|
end
|
|
223
251
|
|
|
252
|
+
def reset_attributes_before_type_cast
|
|
253
|
+
@attributes_before_type_cast = @attributes.dup
|
|
254
|
+
end
|
|
255
|
+
|
|
224
256
|
module ClassMethods
|
|
225
257
|
|
|
226
258
|
private
|
|
@@ -291,7 +323,7 @@ module Mongoid
|
|
|
291
323
|
end
|
|
292
324
|
end
|
|
293
325
|
|
|
294
|
-
# Creates the dirty change previous value
|
|
326
|
+
# Creates the dirty change previous value accessors.
|
|
295
327
|
#
|
|
296
328
|
# @example Create the accessor.
|
|
297
329
|
# Model.create_dirty_previous_value_accessor("name", "alias")
|
|
@@ -303,6 +335,9 @@ module Mongoid
|
|
|
303
335
|
re_define_method("#{meth}_was") do
|
|
304
336
|
attribute_was(name)
|
|
305
337
|
end
|
|
338
|
+
re_define_method("#{meth}_previously_was") do
|
|
339
|
+
attribute_previously_was(name)
|
|
340
|
+
end
|
|
306
341
|
end
|
|
307
342
|
end
|
|
308
343
|
|
|
@@ -95,10 +95,6 @@ module Mongoid
|
|
|
95
95
|
[MONGOID_WRAPPING_LIBRARY] + options[:wrapping_libraries]
|
|
96
96
|
else
|
|
97
97
|
[MONGOID_WRAPPING_LIBRARY]
|
|
98
|
-
end.tap do |wrap|
|
|
99
|
-
if defined?(::Rails) && ::Rails.respond_to?(:version)
|
|
100
|
-
wrap << { name: 'Rails', version: ::Rails.version }
|
|
101
|
-
end
|
|
102
98
|
end
|
|
103
99
|
options[:wrapping_libraries] = wrap_lib
|
|
104
100
|
end
|
|
@@ -43,13 +43,7 @@ module Mongoid
|
|
|
43
43
|
Threaded.set_session(session)
|
|
44
44
|
yield(session)
|
|
45
45
|
rescue Mongo::Error::InvalidSession => ex
|
|
46
|
-
if
|
|
47
|
-
# Driver 2.13.0+
|
|
48
|
-
defined?(Mongo::Error::SessionsNotSupported) &&
|
|
49
|
-
Mongo::Error::SessionsNotSupported === ex ||
|
|
50
|
-
# Legacy drivers
|
|
51
|
-
ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
|
52
|
-
then
|
|
46
|
+
if Mongo::Error::SessionsNotSupported === ex
|
|
53
47
|
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
|
54
48
|
end
|
|
55
49
|
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|
|
@@ -100,13 +94,7 @@ module Mongoid
|
|
|
100
94
|
Threaded.set_session(session)
|
|
101
95
|
yield(session)
|
|
102
96
|
rescue Mongo::Error::InvalidSession => ex
|
|
103
|
-
if
|
|
104
|
-
# Driver 2.13.0+
|
|
105
|
-
defined?(Mongo::Error::SessionsNotSupported) &&
|
|
106
|
-
Mongo::Error::SessionsNotSupported === ex ||
|
|
107
|
-
# Legacy drivers
|
|
108
|
-
ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
|
109
|
-
then
|
|
97
|
+
if Mongo::Error::SessionsNotSupported === ex
|
|
110
98
|
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
|
111
99
|
end
|
|
112
100
|
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|