mongoid 7.0.4 → 7.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -0
  5. data/README.md +3 -2
  6. data/Rakefile +26 -0
  7. data/lib/mongoid.rb +2 -1
  8. data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
  9. data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
  10. data/lib/mongoid/association/proxy.rb +1 -1
  11. data/lib/mongoid/atomic.rb +13 -3
  12. data/lib/mongoid/atomic/paths/embedded.rb +1 -1
  13. data/lib/mongoid/attributes.rb +28 -20
  14. data/lib/mongoid/attributes/dynamic.rb +15 -14
  15. data/lib/mongoid/clients/sessions.rb +20 -4
  16. data/lib/mongoid/config/environment.rb +21 -8
  17. data/lib/mongoid/criteria.rb +7 -1
  18. data/lib/mongoid/criteria/modifiable.rb +13 -2
  19. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  20. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  21. data/lib/mongoid/criteria/queryable/extensions/time.rb +1 -1
  22. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
  23. data/lib/mongoid/criteria/queryable/key.rb +67 -8
  24. data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
  25. data/lib/mongoid/criteria/queryable/selectable.rb +3 -4
  26. data/lib/mongoid/criteria/queryable/selector.rb +9 -31
  27. data/lib/mongoid/extensions/hash.rb +4 -2
  28. data/lib/mongoid/extensions/regexp.rb +1 -1
  29. data/lib/mongoid/extensions/string.rb +2 -2
  30. data/lib/mongoid/fields.rb +2 -1
  31. data/lib/mongoid/matchable.rb +14 -15
  32. data/lib/mongoid/matchable/all.rb +4 -3
  33. data/lib/mongoid/matchable/default.rb +71 -24
  34. data/lib/mongoid/matchable/regexp.rb +2 -2
  35. data/lib/mongoid/persistable/pushable.rb +11 -2
  36. data/lib/mongoid/persistence_context.rb +6 -6
  37. data/lib/mongoid/positional.rb +1 -1
  38. data/lib/mongoid/query_cache.rb +24 -11
  39. data/lib/mongoid/validatable/macros.rb +1 -1
  40. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  41. data/lib/mongoid/version.rb +2 -1
  42. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  43. data/spec/README.md +18 -0
  44. data/spec/app/models/delegating_patient.rb +16 -0
  45. data/spec/integration/app_spec.rb +192 -0
  46. data/spec/integration/associations/embedded_spec.rb +62 -0
  47. data/spec/integration/criteria/date_field_spec.rb +41 -0
  48. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  49. data/spec/integration/document_spec.rb +22 -0
  50. data/spec/integration/matchable_spec.rb +680 -0
  51. data/spec/lite_spec_helper.rb +15 -5
  52. data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
  53. data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
  54. data/spec/mongoid/association/embedded/embeds_one_spec.rb +0 -2
  55. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +140 -1
  56. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
  57. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
  58. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  59. data/spec/mongoid/attributes_spec.rb +19 -7
  60. data/spec/mongoid/clients/factory_spec.rb +2 -2
  61. data/spec/mongoid/clients/options_spec.rb +4 -4
  62. data/spec/mongoid/clients/sessions_spec.rb +20 -7
  63. data/spec/mongoid/clients/transactions_spec.rb +36 -15
  64. data/spec/mongoid/clients_spec.rb +2 -2
  65. data/spec/mongoid/contextual/atomic_spec.rb +20 -10
  66. data/spec/mongoid/contextual/geo_near_spec.rb +12 -2
  67. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  68. data/spec/mongoid/contextual/mongo_spec.rb +76 -53
  69. data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
  70. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  71. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  72. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
  73. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
  74. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
  75. data/spec/mongoid/criteria/queryable/key_spec.rb +48 -6
  76. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
  77. data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
  78. data/spec/mongoid/criteria/queryable/selector_spec.rb +37 -0
  79. data/spec/mongoid/criteria_spec.rb +7 -2
  80. data/spec/mongoid/document_fields_spec.rb +88 -0
  81. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  82. data/spec/mongoid/indexable_spec.rb +6 -4
  83. data/spec/mongoid/matchable/default_spec.rb +10 -3
  84. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  85. data/spec/mongoid/matchable_spec.rb +2 -2
  86. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  87. data/spec/mongoid/query_cache_spec.rb +62 -8
  88. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  89. data/spec/mongoid/scopable_spec.rb +2 -1
  90. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  91. data/spec/mongoid/tasks/database_spec.rb +1 -1
  92. data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
  93. data/spec/spec_helper.rb +4 -37
  94. data/spec/support/child_process_helper.rb +76 -0
  95. data/spec/support/cluster_config.rb +158 -0
  96. data/spec/support/constraints.rb +201 -30
  97. data/spec/support/expectations.rb +17 -3
  98. data/spec/support/spec_config.rb +12 -4
  99. metadata +490 -454
  100. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97ae228df96e11fe59977a8d1af1bb0e86597fe5ee31d8cbe257a077d6e87d4f
4
- data.tar.gz: b8face8e682359ca47c26c0dc168ab1a99762769176fd2f8796ae472a341cd76
3
+ metadata.gz: 5ad9fbedf524c291d800a33349aed2f382c34bbe7b2db4417b7fc73f4c6b0ced
4
+ data.tar.gz: 2dc25b9b97f8a9d56249ea690affb49537f3d8cc73d03e149abf5b3f9511f5bf
5
5
  SHA512:
6
- metadata.gz: 1aafc53e49a0576a7bfb081bca208629ba7323c1a52468e0279644b0b9c2a9d4015c63d35cdf1f16b0967056ed976d015638fab512bce7a221acfeda75c867ed
7
- data.tar.gz: 0c3e7557c424ccd5a95d3e5c4249e4a45a31f74577be2ba7cfac70d67d3226cd00b0b655e7f9d576086a0fc18c7b9d7bf37c57e8a06fb07131a3bec99e85fe8a
6
+ metadata.gz: 86f6b6b3df1aaa98de5344f58e152b0a05b6f0ea21153e7fadd4a1d3b1ba74bed9a7b967ab608ce01dc2cb401c81e153f69569f5e8d19a96dcc953be27b16823
7
+ data.tar.gz: e99a2501707a844f35a4eecc827163f871b77fd2f681e347e9bede2b0708dab8bdec0ce8520304f01f475c63cc33fc0216bd7d8b7e98556f5f6b696b8682ffe1
Binary file
data.tar.gz.sig CHANGED
Binary file
data/LICENSE CHANGED
@@ -1,4 +1,5 @@
1
1
  Copyright (c) 2009-2016 Durran Jordan
2
+ Copyright (c) 2015-2020 MongoDB, Inc.
2
3
 
3
4
  Permission is hereby granted, free of charge, to any person obtaining
4
5
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -14,7 +14,7 @@ Project Tracking
14
14
  ----------------
15
15
 
16
16
  * [Mongoid Website and Documentation](http://mongoid.org)
17
- * [Mongoid Google Group](http://groups.google.com/group/mongoid)
17
+ * [MongoDB Community Forum](https://developer.mongodb.com/community/forums/tags/c/drivers-odms-connectors/7/mongoid-odm)
18
18
  * [Stackoverflow](http://stackoverflow.com/questions/tagged/mongoid)
19
19
  * [#mongoid](http://webchat.freenode.net/?channels=mongoid) on freenode IRC
20
20
 
@@ -31,7 +31,8 @@ Please see the [MongoDB website](http://docs.mongodb.org/ecosystem/tutorial/ruby
31
31
  License
32
32
  -------
33
33
 
34
- Copyright (c) 2009-2017 Durran Jordan
34
+ Copyright (c) 2009-2016 Durran Jordan
35
+ Copyright (c) 2015-2020 MongoDB, Inc.
35
36
 
36
37
  Permission is hereby granted, free of charge, to any person obtaining
37
38
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require "bundler"
2
+ require "bundler/gem_tasks"
2
3
  Bundler.setup
3
4
 
4
5
  require "rake"
@@ -7,6 +8,9 @@ require "rspec/core/rake_task"
7
8
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
9
  require "mongoid/version"
9
10
 
11
+ tasks = Rake.application.instance_variable_get('@tasks')
12
+ tasks['release:do'] = tasks.delete('release')
13
+
10
14
  task :gem => :build
11
15
  task :build do
12
16
  system "gem build mongoid.gemspec"
@@ -33,3 +37,25 @@ RSpec::Core::RakeTask.new('spec:progress') do |spec|
33
37
  end
34
38
 
35
39
  task :default => :spec
40
+
41
+ desc "Generate all documentation"
42
+ task :docs => 'docs:yard'
43
+
44
+ namespace :docs do
45
+ desc "Generate yard documention"
46
+ task :yard do
47
+ out = File.join('yard-docs', Mongoid::VERSION)
48
+ FileUtils.rm_rf(out)
49
+ system "yardoc -o #{out} --title mongoid-#{Mongoid::VERSION}"
50
+ end
51
+ end
52
+
53
+ namespace :release do
54
+ task :check_private_key do
55
+ unless File.exist?('gem-private_key.pem')
56
+ raise "No private key present, cannot release"
57
+ end
58
+ end
59
+ end
60
+
61
+ task :release => ['release:check_private_key', 'release:do']
@@ -13,6 +13,7 @@ require "active_support/time_with_zone"
13
13
  require "active_model"
14
14
 
15
15
  require "mongo"
16
+ require 'mongo/active_support'
16
17
 
17
18
  require "mongoid/version"
18
19
  require "mongoid/config"
@@ -101,5 +102,5 @@ module Mongoid
101
102
  # Mongoid.database = Mongo::Connection.new.db("test")
102
103
  #
103
104
  # @since 1.0.0
104
- delegate(*(Config.public_instance_methods(false) - [ :logger=, :logger ] << { to: Config }))
105
+ delegate(*(Config.public_instance_methods(false) - [ :logger=, :logger ]), to: Config)
105
106
  end
@@ -197,7 +197,8 @@ module Mongoid
197
197
  def determine_inverses(other)
198
198
  matches = relation_class.relations.values.select do |rel|
199
199
  relation_complements.include?(rel.class) &&
200
- rel.relation_class_name == inverse_class_name
200
+ # https://jira.mongodb.org/browse/MONGOID-4882
201
+ rel.relation_class_name.sub(/\A::/, '') == inverse_class_name
201
202
  end
202
203
  if matches.size > 1
203
204
  raise Errors::AmbiguousRelationship.new(relation_class, @owner_class, name, matches)
@@ -159,7 +159,8 @@ module Mongoid
159
159
  def determine_inverses(other)
160
160
  matches = relation_class.relations.values.select do |rel|
161
161
  relation_complements.include?(rel.class) &&
162
- rel.relation_class_name == inverse_class_name
162
+ # https://jira.mongodb.org/browse/MONGOID-4882
163
+ rel.relation_class_name.sub(/\A::/, '') == inverse_class_name
163
164
 
164
165
  end
165
166
  if matches.size > 1
@@ -12,7 +12,7 @@ module Mongoid
12
12
  # We undefine most methods to get them sent through to the target.
13
13
  instance_methods.each do |method|
14
14
  undef_method(method) unless
15
- method =~ /^(__.*|send|object_id|equal\?|respond_to\?|tap|public_send|extend_proxy|extend_proxies)$/
15
+ method =~ /\A(__.*|send|object_id|equal\?|respond_to\?|tap|public_send|extend_proxy|extend_proxies)\z/
16
16
  end
17
17
 
18
18
  include Threaded::Lifecycle
@@ -36,7 +36,9 @@ module Mongoid
36
36
  # @since 2.2.0
37
37
  def add_atomic_pull(document)
38
38
  document.flagged_for_destroy = true
39
- (delayed_atomic_pulls[document.association_name.to_s] ||= []).push(document)
39
+ key = document.association_name.to_s
40
+ delayed_atomic_pulls[key] ||= []
41
+ delayed_atomic_pulls[key] << document
40
42
  end
41
43
 
42
44
  # Add an atomic unset for the document.
@@ -51,7 +53,9 @@ module Mongoid
51
53
  # @since 3.0.0
52
54
  def add_atomic_unset(document)
53
55
  document.flagged_for_destroy = true
54
- (delayed_atomic_unsets[document.association_name.to_s] ||= []).push(document)
56
+ key = document.association_name.to_s
57
+ delayed_atomic_unsets[key] ||= []
58
+ delayed_atomic_unsets[key] << document
55
59
  end
56
60
 
57
61
  # Returns path of the attribute for modification
@@ -189,7 +193,13 @@ module Mongoid
189
193
  #
190
194
  # @since 2.1.0
191
195
  def atomic_paths
192
- @atomic_paths ||= _association ? _association.path(self) : Atomic::Paths::Root.new(self)
196
+ @atomic_paths ||= begin
197
+ if _association
198
+ _association.path(self)
199
+ else
200
+ Atomic::Paths::Root.new(self)
201
+ end
202
+ end
193
203
  end
194
204
 
195
205
  # Get all the attributes that need to be pulled.
@@ -20,7 +20,7 @@ module Mongoid
20
20
  #
21
21
  # @since 2.1.0
22
22
  def path
23
- @path ||= position.sub(/\.\d+$/, "")
23
+ @path ||= position.sub(/\.\d+\z/, "")
24
24
  end
25
25
  end
26
26
  end
@@ -157,21 +157,21 @@ module Mongoid
157
157
  #
158
158
  # @since 1.0.0
159
159
  def write_attribute(name, value)
160
- access = database_field_name(name)
161
- if attribute_writable?(access)
160
+ field_name = database_field_name(name)
161
+ if attribute_writable?(field_name)
162
162
  _assigning do
163
- validate_attribute_value(access, value)
164
- localized = fields[access].try(:localized?)
163
+ validate_attribute_value(field_name, value)
164
+ localized = fields[field_name].try(:localized?)
165
165
  attributes_before_type_cast[name.to_s] = value
166
- typed_value = typed_value_for(access, value)
167
- unless attributes[access] == typed_value || attribute_changed?(access)
168
- attribute_will_change!(access)
166
+ typed_value = typed_value_for(field_name, value)
167
+ unless attributes[field_name] == typed_value || attribute_changed?(field_name)
168
+ attribute_will_change!(field_name)
169
169
  end
170
170
  if localized
171
- attributes[access] ||= {}
172
- attributes[access].merge!(typed_value)
171
+ attributes[field_name] ||= {}
172
+ attributes[field_name].merge!(typed_value)
173
173
  else
174
- attributes[access] = typed_value
174
+ attributes[field_name] = typed_value
175
175
  end
176
176
  typed_value
177
177
  end
@@ -337,20 +337,28 @@ module Mongoid
337
337
 
338
338
  private
339
339
 
340
- # Validates an attribute value. This provides validation checking if
341
- # the value is valid for given a field.
342
- # For now, only Hash and Array fields are validated.
340
+ # Validates an attribute value as being assignable to the specified field.
343
341
  #
344
- # @param [ String, Symbol ] access The name of the attribute to validate.
345
- # @param [ Object ] value The to be validated.
342
+ # For now, only Hash and Array fields are validated, and the value is
343
+ # being checked to be of an appropriate type (i.e. either Hash or Array,
344
+ # respectively, or nil).
345
+ #
346
+ # This method takes the name of the field as stored in the document
347
+ # in the database, not (necessarily) the Ruby method name used to read/write
348
+ # the said field.
349
+ #
350
+ # @param [ String, Symbol ] field_name The name of the field.
351
+ # @param [ Object ] value The value to be validated.
346
352
  #
347
353
  # @since 3.0.10
348
- def validate_attribute_value(access, value)
349
- return unless fields[access] && value
354
+ def validate_attribute_value(field_name, value)
355
+ return if value.nil?
356
+ field = fields[field_name]
357
+ return unless field
350
358
  validatable_types = [ Hash, Array ]
351
- if validatable_types.include? fields[access].type
352
- unless value.is_a? fields[access].type
353
- raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
359
+ if validatable_types.include?(field.type)
360
+ unless value.is_a?(field.type)
361
+ raise Mongoid::Errors::InvalidValue.new(field.type, value.class)
354
362
  end
355
363
  end
356
364
  end
@@ -38,12 +38,13 @@ module Mongoid
38
38
  # @since 4.0.0
39
39
  def define_dynamic_reader(name)
40
40
  return unless name.valid_method_name?
41
- class_eval <<-READER, __FILE__, __LINE__ + 1
42
- def #{name}
43
- attribute_will_change!(#{name.inspect})
44
- read_raw_attribute(#{name.inspect})
41
+
42
+ class_eval do
43
+ define_method(name) do
44
+ attribute_will_change!(name)
45
+ read_raw_attribute(name)
45
46
  end
46
- READER
47
+ end
47
48
  end
48
49
 
49
50
  # Define a reader method for a dynamic attribute before type cast.
@@ -57,12 +58,12 @@ module Mongoid
57
58
  #
58
59
  # @since 4.0.0
59
60
  def define_dynamic_before_type_cast_reader(name)
60
- class_eval <<-READER, __FILE__, __LINE__ + 1
61
- def #{name}_before_type_cast
62
- attribute_will_change!(#{name.inspect})
63
- read_attribute_before_type_cast(#{name.inspect})
61
+ class_eval do
62
+ define_method("#{name}_before_type_cast") do
63
+ attribute_will_change!(name)
64
+ read_attribute_before_type_cast(name)
64
65
  end
65
- READER
66
+ end
66
67
  end
67
68
 
68
69
  # Define a writer method for a dynamic attribute.
@@ -78,11 +79,11 @@ module Mongoid
78
79
  def define_dynamic_writer(name)
79
80
  return unless name.valid_method_name?
80
81
 
81
- class_eval <<-WRITER, __FILE__, __LINE__ + 1
82
- def #{name}=(value)
83
- write_attribute(#{name.inspect}, value)
82
+ class_eval do
83
+ define_method("#{name}=") do |value|
84
+ write_attribute(name, value)
84
85
  end
85
- WRITER
86
+ end
86
87
  end
87
88
 
88
89
  # If the attribute is dynamic, add a field for it with a type of object
@@ -38,12 +38,20 @@ module Mongoid
38
38
  #
39
39
  # @since 6.4.0
40
40
  def with_session(options = {})
41
- raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
41
+ if Threaded.get_session
42
+ raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting)
43
+ end
42
44
  session = persistence_context.client.start_session(options)
43
45
  Threaded.set_session(session)
44
46
  yield(session)
45
47
  rescue Mongo::Error::InvalidSession => ex
46
- if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
48
+ if
49
+ # Driver 2.13.0+
50
+ defined?(Mongo::Error::SessionsNotSupported) &&
51
+ Mongo::Error::SessionsNotSupported === ex ||
52
+ # Legacy drivers
53
+ ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
54
+ then
47
55
  raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
48
56
  end
49
57
  raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
@@ -89,12 +97,20 @@ module Mongoid
89
97
  #
90
98
  # @since 6.4.0
91
99
  def with_session(options = {})
92
- raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
100
+ if Threaded.get_session
101
+ raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting)
102
+ end
93
103
  session = persistence_context.client.start_session(options)
94
104
  Threaded.set_session(session)
95
105
  yield(session)
96
106
  rescue Mongo::Error::InvalidSession => ex
97
- if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
107
+ if
108
+ # Driver 2.13.0+
109
+ defined?(Mongo::Error::SessionsNotSupported) &&
110
+ Mongo::Error::SessionsNotSupported === ex ||
111
+ # Legacy drivers
112
+ ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
113
+ then
98
114
  raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
99
115
  end
100
116
  raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
@@ -6,35 +6,48 @@ module Mongoid
6
6
  module Environment
7
7
  extend self
8
8
 
9
- # Get the name of the environment that we are running under. This first
10
- # looks for Rails, then Sinatra, then a RACK_ENV environment variable,
11
- # and if none of those are found raises an error.
9
+ # Get the name of the environment that Mongoid is running under.
10
+ #
11
+ # Uses the following sources in order:
12
+ # - If +::Rails+ is defined, +Rails.env+.
13
+ # - If +::Sinatra+ is defined, +Sinatra::Base.environment+.
14
+ # - +RACK_ENV+
15
+ # - +MONGOID_ENV*
12
16
  #
13
17
  # @example Get the env name.
14
18
  # Environment.env_name
15
19
  #
16
- # @raise [ Errors::NoEnvironment ] If no environment was set.
20
+ # @raise [ Errors::NoEnvironment ] If environment name cannot be
21
+ # determined because none of the sources was set.
17
22
  #
18
23
  # @return [ String ] The name of the current environment.
19
24
  #
20
25
  # @since 2.3.0
26
+ # @api public
21
27
  def env_name
22
- return Rails.env if defined?(Rails) && Rails.respond_to?(:env)
23
- return Sinatra::Base.environment.to_s if defined?(Sinatra)
24
- ENV["RACK_ENV"] || ENV["MONGOID_ENV"] || raise(Errors::NoEnvironment.new)
28
+ if defined?(::Rails)
29
+ return ::Rails.env
30
+ end
31
+ if defined?(::Sinatra)
32
+ return ::Sinatra::Base.environment.to_s
33
+ end
34
+ ENV["RACK_ENV"] || ENV["MONGOID_ENV"] or raise Errors::NoEnvironment
25
35
  end
26
36
 
27
37
  # Load the yaml from the provided path and return the settings for the
28
- # current environment.
38
+ # specified environment, or for the current Mongoid environment.
29
39
  #
30
40
  # @example Load the yaml.
31
41
  # Environment.load_yaml("/work/mongoid.yml")
32
42
  #
33
43
  # @param [ String ] path The location of the file.
44
+ # @param [ String | Symbol ] environment Optional environment name to
45
+ # override the current Mongoid environment.
34
46
  #
35
47
  # @return [ Hash ] The settings.
36
48
  #
37
49
  # @since 2.3.0
50
+ # @api private
38
51
  def load_yaml(path, environment = nil)
39
52
  env = environment ? environment.to_s : env_name
40
53
  YAML.load(ERB.new(File.new(path).read).result)[env]
@@ -435,7 +435,13 @@ module Mongoid
435
435
  #
436
436
  # @since 3.1.0
437
437
  def for_js(javascript, scope = {})
438
- js_query(BSON::CodeWithScope.new(javascript, scope))
438
+ code = if scope.empty?
439
+ # CodeWithScope is not supported for $where as of MongoDB 4.4
440
+ BSON::Code.new(javascript)
441
+ else
442
+ BSON::CodeWithScope.new(javascript, scope)
443
+ end
444
+ js_query(code)
439
445
  end
440
446
 
441
447
  private
@@ -3,6 +3,10 @@ module Mongoid
3
3
  class Criteria
4
4
  module Modifiable
5
5
 
6
+ # @attribute [r] create_attrs Additional attributes to add to the Document upon creation.
7
+ # @api private
8
+ attr_reader :create_attrs
9
+
6
10
  # Build a document given the selector and return it.
7
11
  # Complex criteria, such as $in and $or operations will get ignored.
8
12
  #
@@ -57,6 +61,9 @@ module Mongoid
57
61
 
58
62
  # Define attributes with which new documents will be created.
59
63
  #
64
+ # Note that if `find_or_create_by` is called after this in a method chain, the attributes in
65
+ # the query will override those from this method.
66
+ #
60
67
  # @example Define attributes to be used when a new document is created.
61
68
  # Person.create_with(job: 'Engineer').find_or_create_by(employer: 'MongoDB')
62
69
  #
@@ -64,7 +71,10 @@ module Mongoid
64
71
  #
65
72
  # @since 5.1.0
66
73
  def create_with(attrs = {})
67
- where(selector.merge(attrs))
74
+ tap do
75
+ @create_attrs ||= {}
76
+ @create_attrs.update(attrs)
77
+ end
68
78
  end
69
79
 
70
80
  # Find the first +Document+ given the conditions, or creates a new document
@@ -172,7 +182,8 @@ module Mongoid
172
182
  #
173
183
  # @since 3.0.0
174
184
  def create_document(method, attrs = nil, &block)
175
- attributes = selector.reduce(attrs ? attrs.dup : {}) do |hash, (key, value)|
185
+ attrs = (create_attrs || {}).merge(attrs || {})
186
+ attributes = selector.reduce(attrs) do |hash, (key, value)|
176
187
  unless invalid_key?(hash, key) || invalid_embedded_doc?(value)
177
188
  hash[key] = value
178
189
  end