mongoid 7.1.7 → 7.1.11

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +31 -0
  5. data/lib/config/locales/en.yml +13 -0
  6. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +1 -1
  7. data/lib/mongoid/association/proxy.rb +1 -1
  8. data/lib/mongoid/association/referenced/has_many/enumerable.rb +1 -1
  9. data/lib/mongoid/association/referenced/has_many/proxy.rb +1 -1
  10. data/lib/mongoid/attributes.rb +8 -1
  11. data/lib/mongoid/config/environment.rb +9 -1
  12. data/lib/mongoid/contextual/atomic.rb +7 -2
  13. data/lib/mongoid/contextual/none.rb +3 -0
  14. data/lib/mongoid/criteria/queryable/selectable.rb +2 -2
  15. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  16. data/lib/mongoid/criteria.rb +1 -1
  17. data/lib/mongoid/document.rb +3 -2
  18. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  19. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  20. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  21. data/lib/mongoid/errors.rb +2 -0
  22. data/lib/mongoid/interceptable.rb +1 -1
  23. data/lib/mongoid/persistence_context.rb +3 -1
  24. data/lib/mongoid/reloadable.rb +5 -0
  25. data/lib/mongoid/tasks/database.rb +1 -1
  26. data/lib/mongoid/validatable/associated.rb +1 -1
  27. data/lib/mongoid/validatable/presence.rb +3 -3
  28. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  29. data/lib/mongoid/version.rb +1 -1
  30. data/lib/mongoid.rb +1 -0
  31. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  32. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  33. data/spec/app/models/address.rb +4 -0
  34. data/spec/app/models/mop.rb +26 -0
  35. data/spec/app/models/person.rb +9 -0
  36. data/spec/integration/app_spec.rb +144 -87
  37. data/spec/integration/contextual/empty_spec.rb +142 -0
  38. data/spec/integration/document_spec.rb +21 -0
  39. data/spec/lite_spec_helper.rb +5 -5
  40. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +17 -4
  41. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +17 -0
  42. data/spec/mongoid/attributes_spec.rb +241 -0
  43. data/spec/mongoid/clients/factory_spec.rb +11 -0
  44. data/spec/mongoid/clients/options_spec.rb +11 -3
  45. data/spec/mongoid/config/environment_spec.rb +86 -8
  46. data/spec/mongoid/contextual/atomic_spec.rb +81 -29
  47. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  48. data/spec/mongoid/criteria_spec.rb +4 -0
  49. data/spec/mongoid/document_query_spec.rb +51 -0
  50. data/spec/mongoid/document_spec.rb +21 -1
  51. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  52. data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
  53. data/spec/mongoid/factory_spec.rb +2 -2
  54. data/spec/mongoid/persistable/savable_spec.rb +4 -4
  55. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  56. data/spec/mongoid/persistable/updatable_spec.rb +2 -0
  57. data/spec/mongoid/persistable_spec.rb +2 -2
  58. data/spec/shared/bin/get-mongodb-download-url +17 -0
  59. data/spec/shared/bin/s3-copy +45 -0
  60. data/spec/shared/bin/s3-upload +69 -0
  61. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  62. data/spec/shared/lib/mrss/constraints.rb +67 -12
  63. data/spec/shared/lib/mrss/docker_runner.rb +10 -1
  64. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  65. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  66. data/spec/shared/lib/mrss/server_version_registry.rb +84 -33
  67. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  68. data/spec/shared/lib/mrss/utils.rb +15 -0
  69. data/spec/shared/share/Dockerfile.erb +126 -32
  70. data/spec/shared/share/haproxy-1.conf +16 -0
  71. data/spec/shared/share/haproxy-2.conf +17 -0
  72. data/spec/shared/shlib/server.sh +123 -26
  73. data/spec/shared/shlib/set_env.sh +4 -1
  74. data/spec/spec_helper.rb +3 -1
  75. data/spec/support/constraints.rb +0 -226
  76. data/spec/support/spec_config.rb +8 -0
  77. data.tar.gz.sig +0 -0
  78. metadata +555 -503
  79. metadata.gz.sig +0 -0
  80. data/spec/support/child_process_helper.rb +0 -76
  81. data/spec/support/lite_constraints.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93d8b658e53d12f1deb7a131e3d58155fead7576955078187f3b3181072c193f
4
- data.tar.gz: 35e629224f7495969e5a695a9641043ad61b92d61b57926b1d1956bd2f5e1d7c
3
+ metadata.gz: 17a1a3273952d5a0d0eb20c5a9864eaccec98bcb9b07647450a8fc86795a46c9
4
+ data.tar.gz: a992b0cea4ac0ddc46e622b405dae7e0d1eab46ff800655d4fa21b39a7b88561
5
5
  SHA512:
6
- metadata.gz: 33920733722a4da26c23190788ef198d86d0d3edfcedc3d53bc7364d9abfbda7c54634af875c678757745c1d18b225457ef8e0a5b5711db7e76b93350548d14b
7
- data.tar.gz: cb0acea4219ce1972fe67b63f988b0f31197ab44142288e5af4fe84e63f602dbc9b7dcc23edbf54cc5e465288c23346f62d3cf0632e0b37a59fabc6acb1c6925
6
+ metadata.gz: 3ac4c55216f2ee6e351afcadab0800c42fc39306b9d7e60dc31ddbeb3bc3a314e7b79961fa785b34ee267bf7d07343a4cb0ac787a9457ad9498783b6baaa5fa5
7
+ data.tar.gz: 0c4f99da1d7845b4736fe7cfb5000067462c7c91c20fb5af1ac351f4eb8562212d3a21e958e1f239b59f1bfde5a57f9f621bf18e260560622a388f5f6f657a25
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -17,7 +17,7 @@ Compatibility
17
17
 
18
18
  Mongoid supports and is tested against:
19
19
 
20
- - MRI 2.3-2.7
20
+ - MRI 2.3-3.0
21
21
  - JRuby 9.2
22
22
  - MongoDB server 2.6-4.4
23
23
 
data/Rakefile CHANGED
@@ -4,8 +4,13 @@ require "bundler"
4
4
  require "bundler/gem_tasks"
5
5
  Bundler.setup
6
6
 
7
+ ROOT = File.expand_path(File.join(File.dirname(__FILE__)))
8
+
9
+ $: << File.join(ROOT, 'spec/shared/lib')
10
+
7
11
  require "rake"
8
12
  require "rspec/core/rake_task"
13
+ require 'mrss/spec_organizer'
9
14
 
10
15
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
11
16
  require "mongoid/version"
@@ -35,6 +40,32 @@ RSpec::Core::RakeTask.new('spec:progress') do |spec|
35
40
  spec.pattern = "spec/**/*_spec.rb"
36
41
  end
37
42
 
43
+ CLASSIFIERS = [
44
+ [%r,^mongoid/attribute,, :attributes],
45
+ [%r,^mongoid/association/[or],, :associations_referenced],
46
+ [%r,^mongoid/association,, :associations],
47
+ [%r,^mongoid,, :unit],
48
+ [%r,^integration,, :integration],
49
+ [%r,^rails,, :rails],
50
+ ]
51
+
52
+ RUN_PRIORITY = %i(
53
+ unit attributes associations_referenced associations
54
+ integration rails
55
+ )
56
+
57
+ def spec_organizer
58
+ Mrss::SpecOrganizer.new(
59
+ root: ROOT,
60
+ classifiers: CLASSIFIERS,
61
+ priority_order: RUN_PRIORITY,
62
+ )
63
+ end
64
+
65
+ task :ci do
66
+ spec_organizer.run
67
+ end
68
+
38
69
  task :default => :spec
39
70
 
40
71
  desc "Generate all documentation"
@@ -77,6 +77,12 @@ en:
77
77
  different collections so a simple id lookup is not sufficient enough."
78
78
  resolution: "Don't attempt to perform this action and have patience,
79
79
  maybe this will be supported in the future."
80
+ empty_config_file:
81
+ message: "Empty configuration file: %{path}."
82
+ summary: "Your mongoid.yml configuration file appears to be empty."
83
+ resolution: "Ensure your configuration file contains the correct contents.
84
+ Please consult the following page with respect to Mongoid's configuration:
85
+ https://docs.mongodb.com/mongoid/current/reference/configuration/"
80
86
  invalid_collection:
81
87
  message: "Access to the collection for %{klass} is not allowed."
82
88
  summary: "%{klass}.collection was called, and %{klass} is an embedded
@@ -91,6 +97,13 @@ en:
91
97
  A collation option is only supported if the query is executed on a MongoDB server
92
98
  with version >= 3.4."
93
99
  resolution: "Remove the collation option from the query."
100
+ invalid_config_file:
101
+ message: "Invalid configuration file: %{path}."
102
+ summary: "Your mongoid.yml configuration file does not contain the
103
+ correct file structure."
104
+ resolution: "Ensure your configuration file contains the correct contents.
105
+ Please consult the following page with respect to Mongoid's configuration:
106
+ https://docs.mongodb.com/mongoid/current/reference/configuration/"
94
107
  invalid_config_option:
95
108
  message: "Invalid configuration option: %{name}."
96
109
  summary: "A invalid configuration option was provided in your
@@ -415,7 +415,7 @@ module Mongoid
415
415
  # @param [ Proc ] block Optional block to pass.
416
416
  #
417
417
  # @return [ Criteria, Object ] A Criteria or return value from the target.
418
- def method_missing(name, *args, &block)
418
+ ruby2_keywords def method_missing(name, *args, &block)
419
419
  return super if _target.respond_to?(name)
420
420
  klass.send(:with_scope, criteria) do
421
421
  criteria.public_send(name, *args, &block)
@@ -133,7 +133,7 @@ module Mongoid
133
133
  # @param [ String, Symbol ] name The name of the method.
134
134
  # @param [ Array ] args The arguments passed to the method.
135
135
  #
136
- def method_missing(name, *args, &block)
136
+ ruby2_keywords def method_missing(name, *args, &block)
137
137
  _target.send(name, *args, &block)
138
138
  end
139
139
 
@@ -498,7 +498,7 @@ module Mongoid
498
498
  end
499
499
  end
500
500
 
501
- def method_missing(name, *args, &block)
501
+ ruby2_keywords def method_missing(name, *args, &block)
502
502
  entries.send(name, *args, &block)
503
503
  end
504
504
 
@@ -436,7 +436,7 @@ module Mongoid
436
436
  # @return [ Criteria, Object ] A Criteria or return value from the target.
437
437
  #
438
438
  # @since 2.0.0.beta.1
439
- def method_missing(name, *args, &block)
439
+ ruby2_keywords def method_missing(name, *args, &block)
440
440
  if _target.respond_to?(name)
441
441
  _target.send(name, *args, &block)
442
442
  else
@@ -160,6 +160,11 @@ module Mongoid
160
160
  # @since 1.0.0
161
161
  def write_attribute(name, value)
162
162
  field_name = database_field_name(name)
163
+
164
+ if attribute_missing?(field_name)
165
+ raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'"
166
+ end
167
+
163
168
  if attribute_writable?(field_name)
164
169
  _assigning do
165
170
  validate_attribute_value(field_name, value)
@@ -177,6 +182,8 @@ module Mongoid
177
182
  end
178
183
  typed_value
179
184
  end
185
+ else
186
+ # TODO: MONGOID-5072
180
187
  end
181
188
  end
182
189
  alias :[]= :write_attribute
@@ -294,7 +301,7 @@ module Mongoid
294
301
  def read_raw_attribute(name)
295
302
  normalized = database_field_name(name.to_s)
296
303
  if attribute_missing?(normalized)
297
- raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'."
304
+ raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'"
298
305
  end
299
306
  if hash_dot_syntax?(normalized)
300
307
  attributes.__nested__(normalized)
@@ -52,7 +52,15 @@ module Mongoid
52
52
  # @api private
53
53
  def load_yaml(path, environment = nil)
54
54
  env = environment ? environment.to_s : env_name
55
- YAML.load(ERB.new(File.new(path).read).result)[env]
55
+ contents = File.new(path).read
56
+ if contents.empty?
57
+ raise Mongoid::Errors::EmptyConfigFile.new(path)
58
+ end
59
+ data = YAML.load(ERB.new(contents).result)
60
+ unless data.is_a?(Hash)
61
+ raise Mongoid::Errors::InvalidConfigFile.new(path)
62
+ end
63
+ data[env]
56
64
  end
57
65
  end
58
66
  end
@@ -173,13 +173,18 @@ module Mongoid
173
173
  # @example Unset the field on the matches.
174
174
  # context.unset(:name)
175
175
  #
176
- # @param [ String, Symbol, Array ] args The name of the fields.
176
+ # @param [ String | Symbol | Array<String|Symbol> | Hash ] args
177
+ # The name(s) of the field(s) to unset.
178
+ # If a Hash is specified, its keys will be used irrespective of what
179
+ # each key's value is, even if the value is nil or false.
177
180
  #
178
181
  # @return [ nil ] Nil.
179
182
  #
180
183
  # @since 3.0.0
181
184
  def unset(*args)
182
- fields = args.__find_args__.collect { |f| [database_field_name(f), true] }
185
+ fields = args.map { |a| a.is_a?(Hash) ? a.keys : a }
186
+ .__find_args__
187
+ .map { |f| [database_field_name(f), true] }
183
188
  view.update_many("$unset" => Hash[fields])
184
189
  end
185
190
 
@@ -112,6 +112,9 @@ module Mongoid
112
112
  entries.length
113
113
  end
114
114
  alias :size :length
115
+
116
+ alias :find_first :first
117
+ alias :one :first
115
118
  end
116
119
  end
117
120
  end
@@ -585,7 +585,7 @@ module Mongoid
585
585
  end
586
586
  _mongoid_expand_keys(new_s).each do |k, v|
587
587
  k = k.to_s
588
- if c.selector[k] || k[0] == ?$
588
+ if c.selector[k] || k.start_with?('$')
589
589
  c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
590
590
  else
591
591
  if v.is_a?(Hash)
@@ -874,7 +874,7 @@ module Mongoid
874
874
  clone.tap do |query|
875
875
  criterion.each do |field, value|
876
876
  field_s = field.to_s
877
- if field_s[0] == ?$
877
+ if field_s.start_with?('$')
878
878
  # Query expression-level operator, like $and or $where
879
879
  query.add_operator_expression(field_s, value)
880
880
  else
@@ -38,7 +38,7 @@ module Mongoid
38
38
  raise ArgumentError, "Field must be a string: #{field}"
39
39
  end
40
40
 
41
- if field[0] == ?$
41
+ if field.start_with?('$')
42
42
  raise ArgumentError, "Field cannot be an operator (i.e. begin with $): #{field}"
43
43
  end
44
44
 
@@ -48,7 +48,7 @@ module Mongoid
48
48
  if value.is_a?(Hash) && selector[field].is_a?(Hash) &&
49
49
  value.keys.all? { |key|
50
50
  key_s = key.to_s
51
- key_s[0] == ?$ && !selector[field].key?(key_s)
51
+ key_s.start_with?('$') && !selector[field].key?(key_s)
52
52
  }
53
53
  then
54
54
  # Multiple operators can be combined on the same field by
@@ -185,7 +185,7 @@ module Mongoid
185
185
  raise ArgumentError, "Operator must be a string: #{operator}"
186
186
  end
187
187
 
188
- unless operator[0] == ?$
188
+ unless operator.start_with?('$')
189
189
  raise ArgumentError, "Operator must begin with $: #{operator}"
190
190
  end
191
191
 
@@ -220,7 +220,7 @@ module Mongoid
220
220
  raise ArgumentError, "Field must be a string: #{field}"
221
221
  end
222
222
 
223
- if field[0] == ?$
223
+ if field.start_with?('$')
224
224
  add_operator_expression(field, value)
225
225
  else
226
226
  add_field_expression(field, value)
@@ -518,7 +518,7 @@ module Mongoid
518
518
  # @return [ Object ] The result of the method call.
519
519
  #
520
520
  # @since 1.0.0
521
- def method_missing(name, *args, &block)
521
+ ruby2_keywords def method_missing(name, *args, &block)
522
522
  if klass.respond_to?(name)
523
523
  klass.send(:with_scope, self) do
524
524
  klass.send(name, *args, &block)
@@ -194,8 +194,8 @@ module Mongoid
194
194
  #
195
195
  # @param [ Hash ] options The options.
196
196
  #
197
- # @option options [ true, false ] :compact Whether to include fields with
198
- # nil values in the json document.
197
+ # @option options [ true, false ] :compact (Deprecated) Whether to include fields
198
+ # with nil values in the json document.
199
199
  #
200
200
  # @return [ Hash ] The document as json.
201
201
  #
@@ -203,6 +203,7 @@ module Mongoid
203
203
  def as_json(options = nil)
204
204
  rv = super
205
205
  if options && options[:compact]
206
+ Mongoid.logger.warn('#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.')
206
207
  rv = rv.compact
207
208
  end
208
209
  rv
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module Mongoid
5
+ module Errors
6
+
7
+ # This error is raised when an empty configuration file is attempted to be
8
+ # loaded.
9
+ class EmptyConfigFile < MongoidError
10
+
11
+ # Create the new error.
12
+ #
13
+ # @param [ String ] path The path of the config file used.
14
+ #
15
+ # @api private
16
+ def initialize(path)
17
+ super(
18
+ compose_message(
19
+ "empty_config_file",
20
+ { path: path }
21
+ )
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module Mongoid
5
+ module Errors
6
+
7
+ # This error is raised when a bad configuration file is attempted to be
8
+ # loaded.
9
+ class InvalidConfigFile < MongoidError
10
+
11
+ # Create the new error.
12
+ #
13
+ # @param [ String ] path The path of the config file used.
14
+ #
15
+ # @api private
16
+ def initialize(path)
17
+ super(
18
+ compose_message(
19
+ "invalid_config_file",
20
+ { path: path }
21
+ )
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -48,7 +48,7 @@ module Mongoid
48
48
  #
49
49
  # @return [ String ] A localized error message string.
50
50
  def translate(key, options)
51
- ::I18n.translate("#{BASE_KEY}.#{key}", options)
51
+ ::I18n.translate("#{BASE_KEY}.#{key}", **options)
52
52
  end
53
53
 
54
54
  # Create the problem.
@@ -8,8 +8,10 @@ require "mongoid/errors/criteria_argument_required"
8
8
  require "mongoid/errors/document_not_destroyed"
9
9
  require "mongoid/errors/document_not_found"
10
10
  require "mongoid/errors/eager_load"
11
+ require "mongoid/errors/empty_config_file"
11
12
  require "mongoid/errors/in_memory_collation_not_supported"
12
13
  require "mongoid/errors/invalid_collection"
14
+ require "mongoid/errors/invalid_config_file"
13
15
  require "mongoid/errors/invalid_config_option"
14
16
  require "mongoid/errors/invalid_dependent_strategy"
15
17
  require "mongoid/errors/invalid_field"
@@ -125,7 +125,7 @@ module Mongoid
125
125
  # @return [ Document ] The document
126
126
  #
127
127
  # @since 2.3.0
128
- def run_callbacks(kind, *args, &block)
128
+ ruby2_keywords def run_callbacks(kind, *args, &block)
129
129
  cascadable_children(kind).each do |child|
130
130
  if child.run_callbacks(child_callback_type(kind, child), *args) == false
131
131
  return false
@@ -237,7 +237,9 @@ module Mongoid
237
237
  # @since 6.0.0
238
238
  def clear(object, cluster = nil, original_context = nil)
239
239
  if context = get(object)
240
- context.client.close unless (context.cluster.equal?(cluster) || cluster.nil?)
240
+ unless cluster.nil? || context.cluster.equal?(cluster)
241
+ context.client.close
242
+ end
241
243
  end
242
244
  ensure
243
245
  Thread.current["[mongoid][#{object.object_id}]:context"] = original_context
@@ -21,6 +21,11 @@ module Mongoid
21
21
  #
22
22
  # @since 1.0.0
23
23
  def reload
24
+ if @atomic_selector
25
+ # Clear atomic_selector cache for sharded clusters. MONGOID-5076
26
+ remove_instance_variable('@atomic_selector')
27
+ end
28
+
24
29
  reloaded = _reload
25
30
  if Mongoid.raise_not_found_error && reloaded.empty?
26
31
  raise Errors::DocumentNotFound.new(self.class, _id, _id)
@@ -123,7 +123,7 @@ module Mongoid
123
123
  next if model.shard_config.nil?
124
124
 
125
125
  if model.embedded? && !model.cyclic?
126
- logger.warn("MONGOID: #{model} has shard config but is emdedded")
126
+ logger.warn("MONGOID: #{model} has shard config but is embedded")
127
127
  next
128
128
  end
129
129
 
@@ -43,7 +43,7 @@ module Mongoid
43
43
  ensure
44
44
  document.exit_validate
45
45
  end
46
- document.errors.add(attribute, :invalid, options) unless valid
46
+ document.errors.add(attribute, :invalid, **options) unless valid
47
47
  end
48
48
  end
49
49
  end
@@ -34,15 +34,15 @@ module Mongoid
34
34
  document.errors.add(
35
35
  attribute,
36
36
  :blank_in_locale,
37
- options.merge(location: _locale)
37
+ **options.merge(location: _locale)
38
38
  ) if not_present?(_value)
39
39
  end
40
40
  elsif document.relations.has_key?(attribute.to_s)
41
41
  if relation_or_fk_missing?(document, attribute, value)
42
- document.errors.add(attribute, :blank, options)
42
+ document.errors.add(attribute, :blank, **options)
43
43
  end
44
44
  else
45
- document.errors.add(attribute, :blank, options) if not_present?(value)
45
+ document.errors.add(attribute, :blank, **options) if not_present?(value)
46
46
  end
47
47
  end
48
48