mongoid 8.0.3 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/lib/config/locales/en.yml +46 -14
- data/lib/mongoid/association/accessors.rb +2 -2
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +23 -21
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +5 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/proxy.rb +7 -3
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +104 -4
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +101 -0
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +233 -33
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +373 -113
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
- data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
- data/lib/mongoid/criteria/translator.rb +45 -0
- data/lib/mongoid/criteria.rb +7 -5
- data/lib/mongoid/deprecable.rb +1 -1
- data/lib/mongoid/document.rb +50 -13
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -1
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/factory.rb +21 -8
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +69 -13
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +7 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +21 -6
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/shardable.rb +35 -11
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/threaded.rb +30 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/macros.rb +5 -5
- data/lib/mongoid/validatable.rb +4 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +17 -1
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -2
- data/spec/integration/callbacks_models.rb +37 -0
- data/spec/integration/callbacks_spec.rb +134 -0
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +57 -57
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +148 -224
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +111 -164
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +5 -8
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -18
- data/spec/mongoid/contextual/memory_spec.rb +332 -76
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +995 -36
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +3 -11
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
- data/spec/mongoid/criteria/translator_spec.rb +132 -0
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -9
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -34
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +15 -3
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -4
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +9 -30
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +153 -61
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +35 -9
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/spec_helper.rb +5 -0
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/cover.rb +10 -0
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +700 -656
- metadata.gz.sig +0 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
data/lib/mongoid/traversable.rb
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
|
|
5
|
+
# @api private
|
|
6
|
+
module Utils
|
|
7
|
+
|
|
8
|
+
# This function should be used if you need to measure time.
|
|
9
|
+
# @example Calculate elapsed time.
|
|
10
|
+
# starting = Utils.monotonic_time
|
|
11
|
+
# # do something time consuming
|
|
12
|
+
# ending = Utils.monotonic_time
|
|
13
|
+
# puts "It took #{(ending - starting).to_i} seconds"
|
|
14
|
+
#
|
|
15
|
+
# @see https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/
|
|
16
|
+
#
|
|
17
|
+
# @return [Float] seconds according to monotonic clock
|
|
18
|
+
module_function def monotonic_time
|
|
19
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -18,7 +18,7 @@ module Mongoid
|
|
|
18
18
|
# validates_associated :name, :addresses
|
|
19
19
|
# end
|
|
20
20
|
#
|
|
21
|
-
# @param [
|
|
21
|
+
# @param [ Object... ] *args The arguments to pass to the validator.
|
|
22
22
|
def validates_associated(*args)
|
|
23
23
|
validates_with(AssociatedValidator, _merge_attributes(args))
|
|
24
24
|
end
|
|
@@ -35,7 +35,7 @@ module Mongoid
|
|
|
35
35
|
# validates_uniqueness_of :title
|
|
36
36
|
# end
|
|
37
37
|
#
|
|
38
|
-
# @param [
|
|
38
|
+
# @param [ Object... ] *args The arguments to pass to the validator.
|
|
39
39
|
def validates_uniqueness_of(*args)
|
|
40
40
|
validates_with(UniquenessValidator, _merge_attributes(args))
|
|
41
41
|
end
|
|
@@ -50,7 +50,7 @@ module Mongoid
|
|
|
50
50
|
# validates_format_of :title, with: /\A[a-z0-9 \-_]*\z/i
|
|
51
51
|
# end
|
|
52
52
|
#
|
|
53
|
-
# @param [
|
|
53
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
54
54
|
def validates_format_of(*args)
|
|
55
55
|
validates_with(FormatValidator, _merge_attributes(args))
|
|
56
56
|
end
|
|
@@ -65,7 +65,7 @@ module Mongoid
|
|
|
65
65
|
# validates_length_of :title, minimum: 100
|
|
66
66
|
# end
|
|
67
67
|
#
|
|
68
|
-
# @param [
|
|
68
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
69
69
|
def validates_length_of(*args)
|
|
70
70
|
validates_with(LengthValidator, _merge_attributes(args))
|
|
71
71
|
end
|
|
@@ -80,7 +80,7 @@ module Mongoid
|
|
|
80
80
|
# validates_presence_of :title
|
|
81
81
|
# end
|
|
82
82
|
#
|
|
83
|
-
# @param [
|
|
83
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
84
84
|
def validates_presence_of(*args)
|
|
85
85
|
validates_with(PresenceValidator, _merge_attributes(args))
|
|
86
86
|
end
|
data/lib/mongoid/validatable.rb
CHANGED
|
@@ -44,6 +44,8 @@ module Mongoid
|
|
|
44
44
|
#
|
|
45
45
|
# @param [ Hash ] options The options to check.
|
|
46
46
|
#
|
|
47
|
+
# @option options [ true | false ] :validate Whether or not to validate.
|
|
48
|
+
#
|
|
47
49
|
# @return [ true | false ] If we are validating.
|
|
48
50
|
def performing_validations?(options = {})
|
|
49
51
|
options[:validate].nil? ? true : options[:validate]
|
|
@@ -129,7 +131,8 @@ module Mongoid
|
|
|
129
131
|
# @example Validate with a specific validator.
|
|
130
132
|
# validates_with MyValidator, on: :create
|
|
131
133
|
#
|
|
132
|
-
# @param [
|
|
134
|
+
# @param [ ActiveModel::Validator..., Hash ] *args The validator classes
|
|
135
|
+
# and options hash.
|
|
133
136
|
#
|
|
134
137
|
# @note See ActiveModel::Validations::With for full options. This is
|
|
135
138
|
# overridden to add autosave functionality when presence validation is
|
data/lib/mongoid/version.rb
CHANGED
data/lib/mongoid/warnings.rb
CHANGED
|
@@ -23,6 +23,22 @@ module Mongoid
|
|
|
23
23
|
|
|
24
24
|
warning :geo_haystack_deprecated, 'The geoHaystack type is deprecated.'
|
|
25
25
|
warning :as_json_compact_deprecated, '#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.'
|
|
26
|
-
warning :symbol_type_deprecated, 'The BSON Symbol type is deprecated by MongoDB. Please use String or StringifiedSymbol field types instead of the Symbol field type'
|
|
26
|
+
warning :symbol_type_deprecated, 'The BSON Symbol type is deprecated by MongoDB. Please use String or StringifiedSymbol field types instead of the Symbol field type.'
|
|
27
|
+
warning :legacy_readonly, 'The readonly! method will only mark the document readonly when the legacy_readonly feature flag is switched off.'
|
|
28
|
+
warning :use_activesupport_time_zone_deprecated, 'Config option :use_activesupport_time_zone is deprecated and should be removed from your config. It will always be true beginning in Mongoid 9.0.'
|
|
29
|
+
warning :broken_aggregables_deprecated, 'Config option :broken_aggregables is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
30
|
+
warning :broken_alias_handling_deprecated, 'Config option :broken_alias_handling is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
31
|
+
warning :broken_and_deprecated, 'Config option :broken_and is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
32
|
+
warning :broken_scoping_deprecated, 'Config option :broken_scoping is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
33
|
+
warning :broken_updates_deprecated, 'Config option :broken_updates is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
34
|
+
warning :compare_time_by_ms_deprecated, 'Config option :compare_time_by_ms is deprecated. It will always be true beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
35
|
+
warning :legacy_attributes_deprecated, 'Config option :legacy_attributes is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
36
|
+
warning :legacy_pluck_distinct_deprecated, 'Config option :legacy_pluck_distinct is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
37
|
+
warning :legacy_triple_equals_deprecated, 'Config option :legacy_triple_equals is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
38
|
+
warning :object_id_as_json_oid_deprecated, 'Config option :object_id_as_json_oid is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
39
|
+
warning :overwrite_chained_operators_deprecated, 'Config option :overwrite_chained_operators is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
40
|
+
warning :mutable_ids, 'In Mongoid 9.0 the _id field will be immutable. In earlier versions of 8.x, mutating the _id field was supported inconsistently. Prepare your code for 9.0 by setting Mongoid::Config.immutable_ids to true.'
|
|
41
|
+
warning :mongoid_query_cache, 'In Mongoid 9.0, Mongoid::QueryCache will be removed. Please replace it with Mongo::QueryCache.'
|
|
42
|
+
warning :mongoid_query_cache_clear, 'In Mongoid 9.0, Mongoid::QueryCache#clear_cache should be replaced it with Mongo::QueryCache#clear.'
|
|
27
43
|
end
|
|
28
44
|
end
|
data/lib/mongoid.rb
CHANGED
|
@@ -12,8 +12,10 @@ require "active_support/inflector"
|
|
|
12
12
|
require "active_support/time_with_zone"
|
|
13
13
|
require "active_model"
|
|
14
14
|
|
|
15
|
+
require 'concurrent-ruby'
|
|
16
|
+
|
|
15
17
|
require "mongo"
|
|
16
|
-
require
|
|
18
|
+
require "mongo/active_support"
|
|
17
19
|
|
|
18
20
|
require "mongoid/version"
|
|
19
21
|
require "mongoid/deprecable"
|
|
@@ -25,6 +27,7 @@ require "mongoid/document"
|
|
|
25
27
|
require "mongoid/tasks/database"
|
|
26
28
|
require "mongoid/query_cache"
|
|
27
29
|
require "mongoid/warnings"
|
|
30
|
+
require "mongoid/utils"
|
|
28
31
|
|
|
29
32
|
# If we are using Rails then we will include the Mongoid railtie. This has all
|
|
30
33
|
# the nifty initializers that Mongoid needs.
|
|
@@ -58,9 +61,19 @@ module Mongoid
|
|
|
58
61
|
# }
|
|
59
62
|
# end
|
|
60
63
|
#
|
|
64
|
+
# @example Using a block without an argument. Use `config` inside
|
|
65
|
+
# the block to perform variable assignment.
|
|
66
|
+
#
|
|
67
|
+
# Mongoid.configure do
|
|
68
|
+
# connect_to("mongoid_test")
|
|
69
|
+
#
|
|
70
|
+
# config.preload_models = true
|
|
71
|
+
#
|
|
61
72
|
# @return [ Config ] The configuration object.
|
|
62
|
-
def configure
|
|
63
|
-
|
|
73
|
+
def configure(&block)
|
|
74
|
+
return Config unless block_given?
|
|
75
|
+
|
|
76
|
+
block.arity == 0 ? Config.instance_exec(&block) : yield(Config)
|
|
64
77
|
end
|
|
65
78
|
|
|
66
79
|
# Convenience method for getting the default client.
|
|
@@ -326,7 +326,7 @@ describe 'Mongoid application tests' do
|
|
|
326
326
|
end
|
|
327
327
|
|
|
328
328
|
def wait_for_port(port, timeout, process)
|
|
329
|
-
deadline =
|
|
329
|
+
deadline = Mongoid::Utils.monotonic_time + timeout
|
|
330
330
|
loop do
|
|
331
331
|
begin
|
|
332
332
|
Socket.tcp('localhost', port, nil, nil, connect_timeout: 0.5) do |socket|
|
|
@@ -336,7 +336,7 @@ describe 'Mongoid application tests' do
|
|
|
336
336
|
unless process.alive?
|
|
337
337
|
raise "Process #{process} died while waiting for port #{port}"
|
|
338
338
|
end
|
|
339
|
-
if
|
|
339
|
+
if Mongoid::Utils.monotonic_time > deadline
|
|
340
340
|
raise
|
|
341
341
|
end
|
|
342
342
|
end
|
|
@@ -153,3 +153,40 @@ class Building
|
|
|
153
153
|
|
|
154
154
|
has_and_belongs_to_many :architects, dependent: :nullify
|
|
155
155
|
end
|
|
156
|
+
|
|
157
|
+
class Root
|
|
158
|
+
include Mongoid::Document
|
|
159
|
+
embeds_many :embedded_once, cascade_callbacks: true
|
|
160
|
+
after_save :trace
|
|
161
|
+
|
|
162
|
+
attr_accessor :logger
|
|
163
|
+
|
|
164
|
+
def trace
|
|
165
|
+
logger << :root
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class EmbeddedOnce
|
|
170
|
+
include Mongoid::Document
|
|
171
|
+
embeds_many :embedded_twice, cascade_callbacks: true
|
|
172
|
+
embedded_in :root
|
|
173
|
+
after_save :trace
|
|
174
|
+
|
|
175
|
+
attr_accessor :logger
|
|
176
|
+
|
|
177
|
+
def trace
|
|
178
|
+
logger << :embedded_once
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class EmbeddedTwice
|
|
183
|
+
include Mongoid::Document
|
|
184
|
+
embedded_in :embedded_once
|
|
185
|
+
after_save :trace
|
|
186
|
+
|
|
187
|
+
attr_accessor :logger
|
|
188
|
+
|
|
189
|
+
def trace
|
|
190
|
+
logger << :embedded_twice
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -447,4 +447,138 @@ describe 'callbacks integration tests' do
|
|
|
447
447
|
expect(saved_person.previously_persisted_value).to be_truthy
|
|
448
448
|
end
|
|
449
449
|
end
|
|
450
|
+
|
|
451
|
+
context 'saved_change_to_attribute, attribute_before_last_save, will_save_change_to_attribute' do
|
|
452
|
+
class TestSCTAAndABLSInCallbacks
|
|
453
|
+
include Mongoid::Document
|
|
454
|
+
|
|
455
|
+
field :name, type: String
|
|
456
|
+
field :age, type: Integer
|
|
457
|
+
|
|
458
|
+
set_callback :save, :before do |doc|
|
|
459
|
+
[:name, :age].each do |attr|
|
|
460
|
+
saved_change_to_attribute_values_before[attr] += [saved_change_to_attribute(attr)]
|
|
461
|
+
attribute_before_last_save_values_before[attr] += [attribute_before_last_save(attr)]
|
|
462
|
+
will_save_change_to_attribute_values_before[attr] += [will_save_change_to_attribute?(attr)]
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
set_callback :save, :after do |doc|
|
|
467
|
+
[:name, :age].each do |attr|
|
|
468
|
+
saved_change_to_attribute_values_after[attr] += [saved_change_to_attribute(attr)]
|
|
469
|
+
saved_change_to_attribute_q_values_after[attr] += [saved_change_to_attribute?(attr)]
|
|
470
|
+
attribute_before_last_save_values_after[attr] += [attribute_before_last_save(attr)]
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def saved_change_to_attribute_values_before
|
|
475
|
+
@saved_change_to_attribute_values_before ||= Hash.new do
|
|
476
|
+
[]
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def attribute_before_last_save_values_before
|
|
481
|
+
@attribute_before_last_save_values_before ||= Hash.new do
|
|
482
|
+
[]
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
def saved_change_to_attribute_values_after
|
|
487
|
+
@saved_change_to_attribute_values_after ||= Hash.new do
|
|
488
|
+
[]
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def saved_change_to_attribute_q_values_after
|
|
493
|
+
@saved_change_to_attribute_q_values_after ||= Hash.new do
|
|
494
|
+
[]
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def attribute_before_last_save_values_after
|
|
499
|
+
@attribute_before_last_save_values_after ||= Hash.new do
|
|
500
|
+
[]
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def will_save_change_to_attribute_values_before
|
|
505
|
+
@will_save_change_to_attribute_values_before ||= Hash.new do
|
|
506
|
+
[]
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
it 'reproduces ActiveRecord::AttributeMethods::Dirty behavior' do
|
|
512
|
+
subject = TestSCTAAndABLSInCallbacks.new(name: 'Name 1')
|
|
513
|
+
subject.save!
|
|
514
|
+
subject.age = 18
|
|
515
|
+
subject.save!
|
|
516
|
+
subject.name = 'Name 2'
|
|
517
|
+
subject.save!
|
|
518
|
+
|
|
519
|
+
expect(subject.saved_change_to_attribute_values_before).to eq(
|
|
520
|
+
{
|
|
521
|
+
:name => [nil, [nil, "Name 1"], nil],
|
|
522
|
+
:age => [nil, nil, [nil, 18]],
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
expect(subject.saved_change_to_attribute_values_after).to eq(
|
|
526
|
+
{
|
|
527
|
+
:name => [[nil, "Name 1"], nil, ["Name 1", "Name 2"]],
|
|
528
|
+
:age => [nil, [nil, 18], nil],
|
|
529
|
+
}
|
|
530
|
+
)
|
|
531
|
+
expect(subject.saved_change_to_attribute_q_values_after).to eq(
|
|
532
|
+
{
|
|
533
|
+
:name => [true, false, true],
|
|
534
|
+
:age => [false, true, false],
|
|
535
|
+
}
|
|
536
|
+
)
|
|
537
|
+
expect(subject.attribute_before_last_save_values_before).to eq(
|
|
538
|
+
{
|
|
539
|
+
:name => [nil, nil, "Name 1"],
|
|
540
|
+
:age => [nil, nil, nil]
|
|
541
|
+
}
|
|
542
|
+
)
|
|
543
|
+
expect(subject.attribute_before_last_save_values_after).to eq(
|
|
544
|
+
{
|
|
545
|
+
:name => [nil, "Name 1", "Name 1"],
|
|
546
|
+
:age => [nil, nil, 18]
|
|
547
|
+
}
|
|
548
|
+
)
|
|
549
|
+
expect(subject.will_save_change_to_attribute_values_before).to eq(
|
|
550
|
+
{
|
|
551
|
+
:name => [true, false, true],
|
|
552
|
+
:age => [false, true, false]
|
|
553
|
+
}
|
|
554
|
+
)
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
context 'nested embedded documents' do
|
|
559
|
+
config_override :prevent_multiple_calls_of_embedded_callbacks, true
|
|
560
|
+
|
|
561
|
+
let(:logger) { Array.new }
|
|
562
|
+
|
|
563
|
+
let(:root) do
|
|
564
|
+
Root.new(
|
|
565
|
+
embedded_once: [
|
|
566
|
+
EmbeddedOnce.new(
|
|
567
|
+
embedded_twice: [EmbeddedTwice.new]
|
|
568
|
+
)
|
|
569
|
+
]
|
|
570
|
+
)
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
before(:each) do
|
|
574
|
+
root.logger = logger
|
|
575
|
+
root.embedded_once.first.logger = logger
|
|
576
|
+
root.embedded_once.first.embedded_twice.first.logger = logger
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
it 'runs callbacks in the correct order' do
|
|
580
|
+
root.save!
|
|
581
|
+
expect(logger).to eq(%i[embedded_twice embedded_once root])
|
|
582
|
+
end
|
|
583
|
+
end
|
|
450
584
|
end
|
|
@@ -81,8 +81,9 @@ describe "#discriminator_key" do
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
context "before class creation" do
|
|
84
|
+
config_override :discriminator_key, "test"
|
|
85
|
+
|
|
84
86
|
before do
|
|
85
|
-
Mongoid.discriminator_key = "test"
|
|
86
87
|
|
|
87
88
|
class PreGlobalIntDiscriminatorParent
|
|
88
89
|
include Mongoid::Document
|
|
@@ -93,7 +94,6 @@ describe "#discriminator_key" do
|
|
|
93
94
|
end
|
|
94
95
|
|
|
95
96
|
after do
|
|
96
|
-
Mongoid.discriminator_key = "_type"
|
|
97
97
|
Object.send(:remove_const, :PreGlobalIntDiscriminatorParent)
|
|
98
98
|
Object.send(:remove_const, :PreGlobalIntDiscriminatorChild)
|
|
99
99
|
end
|
|
@@ -336,9 +336,9 @@ describe "#discriminator_key" do
|
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
context "Example 3" do
|
|
339
|
-
|
|
340
|
-
Mongoid.discriminator_key = "shape_type"
|
|
339
|
+
config_override :discriminator_key, "shape_type"
|
|
341
340
|
|
|
341
|
+
before do
|
|
342
342
|
class Example3Shape
|
|
343
343
|
include Mongoid::Document
|
|
344
344
|
field :x, type: Integer
|
|
@@ -358,7 +358,6 @@ describe "#discriminator_key" do
|
|
|
358
358
|
end
|
|
359
359
|
|
|
360
360
|
after do
|
|
361
|
-
Mongoid.discriminator_key = "_type"
|
|
362
361
|
Object.send(:remove_const, :Example3Shape)
|
|
363
362
|
Object.send(:remove_const, :Example3Circle)
|
|
364
363
|
Object.send(:remove_const, :Example3Rectangle)
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
|
|
5
5
|
describe 'i18n fallbacks' do
|
|
6
|
-
|
|
6
|
+
require_fallbacks
|
|
7
7
|
|
|
8
8
|
context 'when fallbacks are enabled with a locale list' do
|
|
9
|
+
with_default_i18n_configs
|
|
10
|
+
|
|
9
11
|
before do
|
|
10
|
-
I18n.default_locale = :en
|
|
11
12
|
I18n.fallbacks[:de] = [ :en ]
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -616,4 +616,31 @@ describe Mongoid::Association::Embedded::EmbeddedIn::Proxy do
|
|
|
616
616
|
end
|
|
617
617
|
end
|
|
618
618
|
end
|
|
619
|
+
|
|
620
|
+
context "when assigning a hash" do
|
|
621
|
+
let(:building_address) { BuildingAddress.new }
|
|
622
|
+
|
|
623
|
+
before do
|
|
624
|
+
building_address.building = { name: "Chrysler" }
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
it "creates the objects correctly" do
|
|
628
|
+
expect(building_address.building).to be_a(Building)
|
|
629
|
+
expect(building_address.building.name).to eq("Chrysler")
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
context "when replacing an association with a hash" do
|
|
634
|
+
let(:building_address) { BuildingAddress.new }
|
|
635
|
+
|
|
636
|
+
before do
|
|
637
|
+
building_address.building = { name: "Chrysler" }
|
|
638
|
+
building_address.building = { name: "Empire State" }
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
it "creates the objects correctly" do
|
|
642
|
+
expect(building_address.building).to be_a(Building)
|
|
643
|
+
expect(building_address.building.name).to eq("Empire State")
|
|
644
|
+
end
|
|
645
|
+
end
|
|
619
646
|
end
|
|
@@ -1862,51 +1862,56 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
1862
1862
|
end
|
|
1863
1863
|
end
|
|
1864
1864
|
|
|
1865
|
-
|
|
1865
|
+
%i[ delete delete_one ].each do |method|
|
|
1866
|
+
describe "\##{method}" do
|
|
1867
|
+
let(:address_one) { Address.new(street: "first") }
|
|
1868
|
+
let(:address_two) { Address.new(street: "second") }
|
|
1866
1869
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
+
before do
|
|
1871
|
+
person.addresses << [ address_one, address_two ]
|
|
1872
|
+
end
|
|
1870
1873
|
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
+
shared_examples_for 'deleting from the collection' do
|
|
1875
|
+
context 'when the document exists in the relation' do
|
|
1876
|
+
let!(:deleted) do
|
|
1877
|
+
person.addresses.send(method, address_one)
|
|
1878
|
+
end
|
|
1874
1879
|
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1880
|
+
it 'deletes the document' do
|
|
1881
|
+
expect(person.addresses).to eq([ address_two ])
|
|
1882
|
+
expect(person.reload.addresses).to eq([ address_two ]) if person.persisted?
|
|
1883
|
+
end
|
|
1878
1884
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1885
|
+
it 'deletes the document from the unscoped' do
|
|
1886
|
+
expect(person.addresses.send(:_unscoped)).to eq([ address_two ])
|
|
1887
|
+
end
|
|
1882
1888
|
|
|
1883
|
-
|
|
1889
|
+
it 'reindexes the relation' do
|
|
1890
|
+
expect(address_two._index).to eq(0)
|
|
1891
|
+
end
|
|
1884
1892
|
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1893
|
+
it 'returns the document' do
|
|
1894
|
+
expect(deleted).to eq(address_one)
|
|
1895
|
+
end
|
|
1896
|
+
end
|
|
1888
1897
|
|
|
1889
|
-
|
|
1890
|
-
|
|
1898
|
+
context 'when the document does not exist' do
|
|
1899
|
+
it 'returns nil' do
|
|
1900
|
+
expect(person.addresses.send(method, Address.new)).to be_nil
|
|
1901
|
+
end
|
|
1902
|
+
end
|
|
1891
1903
|
end
|
|
1892
1904
|
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
end
|
|
1905
|
+
context 'when the root document is unpersisted' do
|
|
1906
|
+
let(:person) { Person.new }
|
|
1896
1907
|
|
|
1897
|
-
|
|
1898
|
-
expect(address_two._index).to eq(0)
|
|
1908
|
+
it_behaves_like 'deleting from the collection'
|
|
1899
1909
|
end
|
|
1900
1910
|
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
end
|
|
1904
|
-
end
|
|
1911
|
+
context 'when the root document is persisted' do
|
|
1912
|
+
let(:person) { Person.create }
|
|
1905
1913
|
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
it "returns nil" do
|
|
1909
|
-
expect(person.addresses.delete(Address.new)).to be_nil
|
|
1914
|
+
it_behaves_like 'deleting from the collection'
|
|
1910
1915
|
end
|
|
1911
1916
|
end
|
|
1912
1917
|
end
|
|
@@ -2352,10 +2357,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
2352
2357
|
context "when the id does not match" do
|
|
2353
2358
|
|
|
2354
2359
|
context "when config set to raise error" do
|
|
2355
|
-
|
|
2356
|
-
before do
|
|
2357
|
-
Mongoid.raise_not_found_error = true
|
|
2358
|
-
end
|
|
2360
|
+
config_override :raise_not_found_error, true
|
|
2359
2361
|
|
|
2360
2362
|
it "raises an error" do
|
|
2361
2363
|
expect {
|
|
@@ -2365,19 +2367,12 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
2365
2367
|
end
|
|
2366
2368
|
|
|
2367
2369
|
context "when config set not to raise error" do
|
|
2370
|
+
config_override :raise_not_found_error, false
|
|
2368
2371
|
|
|
2369
2372
|
let(:address) do
|
|
2370
2373
|
person.addresses.find(BSON::ObjectId.new)
|
|
2371
2374
|
end
|
|
2372
2375
|
|
|
2373
|
-
before do
|
|
2374
|
-
Mongoid.raise_not_found_error = false
|
|
2375
|
-
end
|
|
2376
|
-
|
|
2377
|
-
after do
|
|
2378
|
-
Mongoid.raise_not_found_error = true
|
|
2379
|
-
end
|
|
2380
|
-
|
|
2381
2376
|
it "returns nil" do
|
|
2382
2377
|
expect(address).to be_nil
|
|
2383
2378
|
end
|
|
@@ -2401,10 +2396,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
2401
2396
|
context "when the ids do not match" do
|
|
2402
2397
|
|
|
2403
2398
|
context "when config set to raise error" do
|
|
2404
|
-
|
|
2405
|
-
before do
|
|
2406
|
-
Mongoid.raise_not_found_error = true
|
|
2407
|
-
end
|
|
2399
|
+
config_override :raise_not_found_error, true
|
|
2408
2400
|
|
|
2409
2401
|
it "raises an error" do
|
|
2410
2402
|
expect {
|
|
@@ -2414,19 +2406,12 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
2414
2406
|
end
|
|
2415
2407
|
|
|
2416
2408
|
context "when config set not to raise error" do
|
|
2409
|
+
config_override :raise_not_found_error, false
|
|
2417
2410
|
|
|
2418
2411
|
let(:addresses) do
|
|
2419
2412
|
person.addresses.find([ BSON::ObjectId.new ])
|
|
2420
2413
|
end
|
|
2421
2414
|
|
|
2422
|
-
before do
|
|
2423
|
-
Mongoid.raise_not_found_error = false
|
|
2424
|
-
end
|
|
2425
|
-
|
|
2426
|
-
after do
|
|
2427
|
-
Mongoid.raise_not_found_error = true
|
|
2428
|
-
end
|
|
2429
|
-
|
|
2430
2415
|
it "returns an empty array" do
|
|
2431
2416
|
expect(addresses).to be_empty
|
|
2432
2417
|
end
|
|
@@ -4586,7 +4571,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
4586
4571
|
before do
|
|
4587
4572
|
band.collection.
|
|
4588
4573
|
find(_id: band.id).
|
|
4589
|
-
update_one("$set" => { records: [{ name: "Moderat" }]})
|
|
4574
|
+
update_one("$set" => { records: [{ _id: BSON::ObjectId.new, name: "Moderat" }]})
|
|
4590
4575
|
end
|
|
4591
4576
|
|
|
4592
4577
|
context "when loading the documents" do
|
|
@@ -4860,4 +4845,19 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
|
4860
4845
|
expect(from_db.company_tags.size).to eq(2)
|
|
4861
4846
|
end
|
|
4862
4847
|
end
|
|
4848
|
+
|
|
4849
|
+
context "when assigning hashes" do
|
|
4850
|
+
let(:user) { EmmUser.create! }
|
|
4851
|
+
|
|
4852
|
+
before do
|
|
4853
|
+
user.orders = [ { sku: 1 }, { sku: 2 } ]
|
|
4854
|
+
end
|
|
4855
|
+
|
|
4856
|
+
it "creates the objects correctly" do
|
|
4857
|
+
expect(user.orders.first).to be_a(EmmOrder)
|
|
4858
|
+
expect(user.orders.last).to be_a(EmmOrder)
|
|
4859
|
+
|
|
4860
|
+
expect(user.orders.map(&:sku).sort).to eq([ 1, 2 ])
|
|
4861
|
+
end
|
|
4862
|
+
end
|
|
4863
4863
|
end
|