mongoid 9.0.0 → 9.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/Rakefile +44 -21
- data/lib/config/locales/en.yml +4 -0
- data/lib/mongoid/atomic_update_preparer.rb +7 -6
- data/lib/mongoid/config.rb +9 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +3 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +5 -2
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -1
- data/lib/mongoid/errors/invalid_around_callback.rb +16 -0
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/fields.rb +13 -7
- data/lib/mongoid/interceptable.rb +18 -13
- data/lib/mongoid/scopable.rb +7 -1
- data/lib/mongoid/touchable.rb +1 -7
- data/lib/mongoid/version.rb +1 -1
- data/spec/mongoid/association_spec.rb +14 -0
- data/spec/mongoid/attributes_spec.rb +16 -0
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +11 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +11 -0
- data/spec/mongoid/contextual/mongo_spec.rb +72 -3
- data/spec/mongoid/fields_spec.rb +2 -2
- data/spec/mongoid/interceptable_spec.rb +31 -0
- data/spec/mongoid/scopable_spec.rb +88 -85
- data/spec/mongoid/touchable_spec.rb +75 -0
- data/spec/mongoid/touchable_spec_models.rb +16 -0
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/lat_lng.rb +6 -0
- metadata +8 -80
- checksums.yaml.gz.sig +0 -1
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -298
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -281
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -417
- data/spec/shared/shlib/set_env.sh +0 -146
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f756ccb6822c09519cb0e833a2d3bd2edf5b5a0abf3f3c29205a756682e5d954
|
4
|
+
data.tar.gz: 7d44016955b7e2e90d2dc07b2142cc6c79bacfb83831705f26fdafc773e17e7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e69bc7c2b6031330346265b5c6cdc8d11909fd1204e32727845e3220c6f105dde407006635f31491df9857597711f610a688818dfaa3bc32f27525e2574ce29d
|
7
|
+
data.tar.gz: 259996128cd10553af4972c6b40f5a8ac537158eeaa1cd012bbc9e6d90d67ad745def51fbd47bafaffe9330324967695e45787732446b305d5bdd13338b94075
|
data/README.md
CHANGED
@@ -14,6 +14,8 @@ Mongoid has [extensive user documentation](https://www.mongodb.com/docs/mongoid/
|
|
14
14
|
Mongoid is built on top of the MongoDB Ruby driver which has
|
15
15
|
[its own user documentation](https://www.mongodb.com/docs/ruby-driver/current/).
|
16
16
|
|
17
|
+
High-level Mongoid documentation including tutorials and the reference that were in the docs folder can now be found at the docs-mongoid repository, [here](https://github.com/mongodb/docs-mongoid).
|
18
|
+
|
17
19
|
Compatibility
|
18
20
|
-------------
|
19
21
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# rubocop:todo all
|
3
3
|
|
4
4
|
require "bundler"
|
5
|
-
require "bundler/gem_tasks"
|
6
5
|
Bundler.setup
|
7
6
|
|
8
7
|
ROOT = File.expand_path(File.join(File.dirname(__FILE__)))
|
@@ -11,25 +10,53 @@ $: << File.join(ROOT, 'spec/shared/lib')
|
|
11
10
|
|
12
11
|
require "rake"
|
13
12
|
require "rspec/core/rake_task"
|
14
|
-
require 'mrss/spec_organizer'
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
tasks['release:do'] = tasks.delete('release')
|
21
|
-
|
22
|
-
task :gem => :build
|
14
|
+
# stands in for the Bundler-provided `build` task, which builds the
|
15
|
+
# gem for this project. Our release process builds the gems in a
|
16
|
+
# particular way, in a GitHub action. This task is just to help remind
|
17
|
+
# developers of that fact.
|
23
18
|
task :build do
|
24
|
-
|
19
|
+
abort <<~WARNING
|
20
|
+
`rake build` does nothing in this project. The gem must be built via
|
21
|
+
the `Mongoid Release` action on GitHub, which is triggered manually when
|
22
|
+
a new release is ready.
|
23
|
+
WARNING
|
25
24
|
end
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
# `rake version` is used by the deployment system so get the release version
|
27
|
+
# of the product beng deployed. It must do nothing more than just print the
|
28
|
+
# product version number.
|
29
|
+
#
|
30
|
+
# See the mongodb-labs/driver-github-tools/ruby/publish Github action.
|
31
|
+
desc "Print the current value of Mongoid::VERSION"
|
32
|
+
task :version do
|
33
|
+
require 'mongoid/version'
|
34
|
+
|
35
|
+
puts Mongoid::VERSION
|
29
36
|
end
|
30
37
|
|
38
|
+
# overrides the default Bundler-provided `release` task, which also
|
39
|
+
# builds the gem. Our release process assumes the gem has already
|
40
|
+
# been built (and signed via GPG), so we just need `rake release` to
|
41
|
+
# push the gem to rubygems.
|
31
42
|
task :release do
|
32
|
-
|
43
|
+
require 'mongoid/version'
|
44
|
+
|
45
|
+
if ENV['GITHUB_ACTION'].nil?
|
46
|
+
abort <<~WARNING
|
47
|
+
`rake release` must be invoked from the `Mongoid Release` GitHub action,
|
48
|
+
and must not be invoked locally. This ensures the gem is properly signed
|
49
|
+
and distributed by the appropriate user.
|
50
|
+
|
51
|
+
Note that it is the `rubygems/release-gem@v1` step in the `Mongoid Release`
|
52
|
+
action that invokes this task. Do not rename or remove this task, or the
|
53
|
+
release-gem step will fail. Reimplement this task with caution.
|
54
|
+
|
55
|
+
mongoid-#{Mongoid::VERSION}.gem was NOT pushed to RubyGems.
|
56
|
+
WARNING
|
57
|
+
end
|
58
|
+
|
59
|
+
system 'gem', 'push', "mongoid-#{Mongoid::VERSION}.gem"
|
33
60
|
end
|
34
61
|
|
35
62
|
RSpec::Core::RakeTask.new("spec") do |spec|
|
@@ -96,6 +123,8 @@ RUN_PRIORITY = %i(
|
|
96
123
|
)
|
97
124
|
|
98
125
|
def spec_organizer
|
126
|
+
require 'mrss/spec_organizer'
|
127
|
+
|
99
128
|
Mrss::SpecOrganizer.new(
|
100
129
|
root: ROOT,
|
101
130
|
classifiers: CLASSIFIERS,
|
@@ -131,16 +160,10 @@ task :docs => 'docs:yard'
|
|
131
160
|
namespace :docs do
|
132
161
|
desc "Generate yard documentation"
|
133
162
|
task :yard do
|
163
|
+
require "mongoid/version"
|
164
|
+
|
134
165
|
out = File.join('yard-docs', Mongoid::VERSION)
|
135
166
|
FileUtils.rm_rf(out)
|
136
167
|
system "yardoc -o #{out} --title mongoid-#{Mongoid::VERSION}"
|
137
168
|
end
|
138
169
|
end
|
139
|
-
|
140
|
-
namespace :release do
|
141
|
-
task :check_private_key do
|
142
|
-
unless File.exist?('gem-private_key.pem')
|
143
|
-
raise "No private key present, cannot release"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
data/lib/config/locales/en.yml
CHANGED
@@ -140,6 +140,10 @@ en:
|
|
140
140
|
A collation option is only supported if the query is executed on a MongoDB server
|
141
141
|
with version >= 3.4."
|
142
142
|
resolution: "Remove the collation option from the query."
|
143
|
+
invalid_around_callback:
|
144
|
+
message: "An around callback must contain a yield in its definition."
|
145
|
+
summary: "The block needs to be yielded to for around callbacks to function as intended."
|
146
|
+
resolution: "Ensure there is a yield statement inside the body of the around callback."
|
143
147
|
invalid_async_query_executor:
|
144
148
|
message: "Invalid async_query_executor option: %{executor}."
|
145
149
|
summary: "A invalid async query executor was specified.
|
@@ -25,7 +25,7 @@ module Mongoid
|
|
25
25
|
if key.to_s.start_with?('$')
|
26
26
|
(atomic_updates[key] ||= {}).update(prepare_operation(klass, key, value))
|
27
27
|
else
|
28
|
-
(atomic_updates['$set'] ||= {})[key] = mongoize_for(
|
28
|
+
(atomic_updates['$set'] ||= {})[key] = mongoize_for('$set', klass, key, value)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -43,24 +43,25 @@ module Mongoid
|
|
43
43
|
def prepare_operation(klass, key, value)
|
44
44
|
value.each_with_object({}) do |(key2, value2), hash|
|
45
45
|
key2 = klass.database_field_name(key2)
|
46
|
-
hash[key2] = value_for(key, klass, value2)
|
46
|
+
hash[key2] = value_for(key, klass, key2, value2)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
# Get the value for the provided operator, klass, key and value.
|
51
51
|
#
|
52
|
-
# This is necessary for special cases like $rename, $addToSet and $
|
52
|
+
# This is necessary for special cases like $rename, $addToSet, $push, $pull and $pop.
|
53
53
|
#
|
54
54
|
# @param [ String ] operator The operator.
|
55
55
|
# @param [ Class ] klass The model class.
|
56
|
+
# @param [ String | Symbol ] key The field key.
|
56
57
|
# @param [ Object ] value The original value.
|
57
58
|
#
|
58
59
|
# @return [ Object ] Value prepared for the provided operator.
|
59
|
-
def value_for(operator, klass, value)
|
60
|
+
def value_for(operator, klass, key, value)
|
60
61
|
case operator
|
61
62
|
when '$rename' then value.to_s
|
62
|
-
when '$addToSet', '$push' then value.mongoize
|
63
|
-
else mongoize_for(operator, klass,
|
63
|
+
when '$addToSet', '$push', '$pull', '$pop' then value.mongoize
|
64
|
+
else mongoize_for(operator, klass, key, value)
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
data/lib/mongoid/config.rb
CHANGED
@@ -171,6 +171,15 @@ module Mongoid
|
|
171
171
|
# See https://jira.mongodb.org/browse/MONGOID-5658 for more details.
|
172
172
|
option :around_callbacks_for_embeds, default: false
|
173
173
|
|
174
|
+
# When this flag is false, named scopes cannot unset a default scope.
|
175
|
+
# This is the traditional (and default) behavior in Mongoid 9 and earlier.
|
176
|
+
#
|
177
|
+
# Setting this flag to true will allow named scopes to unset the default
|
178
|
+
# scope. This will be the default in Mongoid 10.
|
179
|
+
#
|
180
|
+
# See https://jira.mongodb.org/browse/MONGOID-5785 for more details.
|
181
|
+
option :allow_scopes_to_unset_default_scope, default: false
|
182
|
+
|
174
183
|
# Returns the Config singleton, for use in the configure DSL.
|
175
184
|
#
|
176
185
|
# @return [ self ] The Config singleton.
|
@@ -90,11 +90,12 @@ module Mongoid
|
|
90
90
|
# @example Get the sum for the provided block.
|
91
91
|
# aggregable.sum(&:likes)
|
92
92
|
#
|
93
|
-
# @param [ Symbol ] field The field to sum
|
93
|
+
# @param [ Symbol | Numeric ] field The field to sum, or the intial
|
94
|
+
# value of the sum when a block is given.
|
94
95
|
#
|
95
96
|
# @return [ Numeric ] The sum value.
|
96
97
|
def sum(field = nil)
|
97
|
-
return super() if block_given?
|
98
|
+
return super(field || 0) if block_given?
|
98
99
|
|
99
100
|
aggregate_by(field, :sum) || 0
|
100
101
|
end
|
@@ -96,11 +96,14 @@ module Mongoid
|
|
96
96
|
# @example Get the sum for the provided block.
|
97
97
|
# aggregable.sum(&:likes)
|
98
98
|
#
|
99
|
-
# @param [ Symbol ] field The field to sum
|
99
|
+
# @param [ Symbol | Numeric ] field The field to sum, or the initial
|
100
|
+
# value of the sum when a block is given.
|
100
101
|
#
|
101
102
|
# @return [ Float ] The sum value.
|
102
103
|
def sum(field = nil)
|
103
|
-
|
104
|
+
return super(field || 0) if block_given?
|
105
|
+
|
106
|
+
aggregates(field)["sum"] || 0
|
104
107
|
end
|
105
108
|
|
106
109
|
private
|
@@ -169,12 +169,12 @@ module Mongoid
|
|
169
169
|
args.size > 1 || !args.first.is_a?(Hash) && args.first.resizable?
|
170
170
|
end
|
171
171
|
|
172
|
-
# Convenience method of raising an invalid
|
172
|
+
# Convenience method of raising an invalid find error.
|
173
173
|
#
|
174
174
|
# @example Raise the error.
|
175
175
|
# criteria.raise_invalid
|
176
176
|
#
|
177
|
-
# @raise [ Errors::
|
177
|
+
# @raise [ Errors::InvalidFind ] The error.
|
178
178
|
def raise_invalid
|
179
179
|
raise Errors::InvalidFind.new
|
180
180
|
end
|
@@ -44,7 +44,21 @@ module Mongoid
|
|
44
44
|
#
|
45
45
|
# @return [ Object ] The converted number.
|
46
46
|
def __numeric__(object)
|
47
|
-
|
47
|
+
str = object.to_s
|
48
|
+
raise ArgumentError if str.empty?
|
49
|
+
|
50
|
+
# These requirements seem a bit odd, but they're explicitly specified in the tests,
|
51
|
+
# so we're obligated to keep them, for now. (This code was rewritten from a one-line
|
52
|
+
# regex, due to security concerns with a polynomial regex being used on uncontrolled
|
53
|
+
# data).
|
54
|
+
|
55
|
+
str = str.chop if str.end_with?('.')
|
56
|
+
return 0 if str.empty?
|
57
|
+
|
58
|
+
result = Integer(str) rescue Float(object)
|
59
|
+
|
60
|
+
integer = result.to_i
|
61
|
+
integer == result ? integer : result
|
48
62
|
end
|
49
63
|
|
50
64
|
# Evolve the object to an integer.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Errors
|
5
|
+
# This error is raised when an around callback is
|
6
|
+
# defined by the user without a yield
|
7
|
+
class InvalidAroundCallback < MongoidError
|
8
|
+
# Create the new error.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
def initialize
|
12
|
+
super(compose_message('invalid_around_callback'))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/mongoid/errors.rb
CHANGED
@@ -13,6 +13,7 @@ require "mongoid/errors/empty_config_file"
|
|
13
13
|
require "mongoid/errors/immutable_attribute"
|
14
14
|
require "mongoid/errors/in_memory_collation_not_supported"
|
15
15
|
require "mongoid/errors/invalid_auto_encryption_configuration"
|
16
|
+
require "mongoid/errors/invalid_around_callback"
|
16
17
|
require "mongoid/errors/invalid_async_query_executor"
|
17
18
|
require "mongoid/errors/invalid_collection"
|
18
19
|
require "mongoid/errors/invalid_config_file"
|
data/lib/mongoid/fields.rb
CHANGED
@@ -49,6 +49,11 @@ module Mongoid
|
|
49
49
|
# @api private
|
50
50
|
INVALID_BSON_CLASSES = [ BSON::Decimal128, BSON::Int32, BSON::Int64 ].freeze
|
51
51
|
|
52
|
+
# The suffix for generated translated fields.
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
TRANSLATIONS_SFX = '_translations'
|
56
|
+
|
52
57
|
module ClassMethods
|
53
58
|
# Returns the list of id fields for this model class, as both strings
|
54
59
|
# and symbols.
|
@@ -101,8 +106,8 @@ module Mongoid
|
|
101
106
|
ar.each_with_index do |fn, i|
|
102
107
|
key = fn
|
103
108
|
unless klass.fields.key?(fn) || klass.relations.key?(fn)
|
104
|
-
if
|
105
|
-
key =
|
109
|
+
if fn.end_with?(TRANSLATIONS_SFX)
|
110
|
+
key = fn.delete_suffix(TRANSLATIONS_SFX)
|
106
111
|
else
|
107
112
|
key = fn
|
108
113
|
end
|
@@ -408,7 +413,8 @@ module Mongoid
|
|
408
413
|
#
|
409
414
|
# @api private
|
410
415
|
def database_field_name(name, relations, aliased_fields, aliased_associations)
|
411
|
-
return
|
416
|
+
return "" unless name.present?
|
417
|
+
|
412
418
|
key = name.to_s
|
413
419
|
segment, remaining = key.split('.', 2)
|
414
420
|
|
@@ -725,11 +731,11 @@ module Mongoid
|
|
725
731
|
# @api private
|
726
732
|
def create_translations_getter(name, meth)
|
727
733
|
generated_methods.module_eval do
|
728
|
-
re_define_method("#{meth}
|
734
|
+
re_define_method("#{meth}#{TRANSLATIONS_SFX}") do
|
729
735
|
attributes[name] ||= {}
|
730
736
|
attributes[name].with_indifferent_access
|
731
737
|
end
|
732
|
-
alias_method :"#{meth}_t", :"#{meth}
|
738
|
+
alias_method :"#{meth}_t", :"#{meth}#{TRANSLATIONS_SFX}"
|
733
739
|
end
|
734
740
|
end
|
735
741
|
|
@@ -745,14 +751,14 @@ module Mongoid
|
|
745
751
|
# @api private
|
746
752
|
def create_translations_setter(name, meth, field)
|
747
753
|
generated_methods.module_eval do
|
748
|
-
re_define_method("#{meth}
|
754
|
+
re_define_method("#{meth}#{TRANSLATIONS_SFX}=") do |value|
|
749
755
|
attribute_will_change!(name)
|
750
756
|
value&.transform_values! do |_value|
|
751
757
|
field.type.mongoize(_value)
|
752
758
|
end
|
753
759
|
attributes[name] = value
|
754
760
|
end
|
755
|
-
alias_method :"#{meth}_t=", :"#{meth}
|
761
|
+
alias_method :"#{meth}_t=", :"#{meth}#{TRANSLATIONS_SFX}="
|
756
762
|
end
|
757
763
|
end
|
758
764
|
|
@@ -161,11 +161,6 @@ module Mongoid
|
|
161
161
|
# Execute the callbacks of given kind for embedded documents including
|
162
162
|
# around callbacks.
|
163
163
|
#
|
164
|
-
# @note This method is prone to stack overflow errors if the document
|
165
|
-
# has a large number of embedded documents. It is recommended to avoid
|
166
|
-
# using around callbacks for embedded documents until a proper solution
|
167
|
-
# is implemented.
|
168
|
-
#
|
169
164
|
# @param [ Symbol ] kind The type of callback to execute.
|
170
165
|
# @param [ Array<Document> ] children Children to execute callbacks on. If
|
171
166
|
# nil, callbacks will be executed on all cascadable children of
|
@@ -173,17 +168,27 @@ module Mongoid
|
|
173
168
|
#
|
174
169
|
# @api private
|
175
170
|
def _mongoid_run_child_callbacks_with_around(kind, children: nil, &block)
|
176
|
-
|
171
|
+
children = (children || cascadable_children(kind))
|
177
172
|
with_children = !Mongoid::Config.prevent_multiple_calls_of_embedded_callbacks
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
173
|
+
|
174
|
+
return block&.call if children.empty?
|
175
|
+
|
176
|
+
fibers = children.map do |child|
|
177
|
+
Fiber.new do
|
178
|
+
child.run_callbacks(child_callback_type(kind, child), with_children: with_children) do
|
179
|
+
Fiber.yield
|
180
|
+
end
|
185
181
|
end
|
186
182
|
end
|
183
|
+
|
184
|
+
fibers.each do |fiber|
|
185
|
+
fiber.resume
|
186
|
+
raise Mongoid::Errors::InvalidAroundCallback unless fiber.alive?
|
187
|
+
end
|
188
|
+
|
189
|
+
block&.call
|
190
|
+
|
191
|
+
fibers.reverse.each(&:resume)
|
187
192
|
end
|
188
193
|
|
189
194
|
# Execute the callbacks of given kind for embedded documents without
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -294,7 +294,13 @@ module Mongoid
|
|
294
294
|
scope = instance_exec(*args, **kwargs, &scoping[:scope])
|
295
295
|
extension = scoping[:extension]
|
296
296
|
to_merge = scope || queryable
|
297
|
-
|
297
|
+
|
298
|
+
criteria = if Mongoid.allow_scopes_to_unset_default_scope
|
299
|
+
to_merge
|
300
|
+
else
|
301
|
+
to_merge.empty_and_chainable? ? to_merge : with_default_scope.merge(to_merge)
|
302
|
+
end
|
303
|
+
|
298
304
|
criteria.extend(extension)
|
299
305
|
criteria
|
300
306
|
end
|
data/lib/mongoid/touchable.rb
CHANGED
@@ -78,7 +78,7 @@ module Mongoid
|
|
78
78
|
field = database_field_name(field)
|
79
79
|
|
80
80
|
write_attribute(:updated_at, now) if respond_to?("updated_at=")
|
81
|
-
write_attribute(field, now) if field
|
81
|
+
write_attribute(field, now) if field.present?
|
82
82
|
|
83
83
|
touches = _extract_touches_from_atomic_sets(field) || {}
|
84
84
|
touches.merge!(_parent._gather_touch_updates(now) || {}) if _touchable_parent?
|
@@ -212,12 +212,6 @@ module Mongoid
|
|
212
212
|
#
|
213
213
|
# @return [ Symbol ] The method name.
|
214
214
|
def define_relation_touch_method(name, association)
|
215
|
-
relation_classes = if association.polymorphic?
|
216
|
-
association.send(:inverse_association_classes)
|
217
|
-
else
|
218
|
-
[ association.relation_class ]
|
219
|
-
end
|
220
|
-
|
221
215
|
method_name = "touch_#{name}_after_create_or_destroy"
|
222
216
|
association.inverse_class.class_eval do
|
223
217
|
define_method(method_name) do
|
data/lib/mongoid/version.rb
CHANGED
@@ -15,6 +15,20 @@ describe Mongoid::Association do
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
|
+
context "when class_name references an unknown class" do
|
19
|
+
context "when loading" do
|
20
|
+
it "does not raise an exception" do
|
21
|
+
expect do
|
22
|
+
class AssocationSpecModel
|
23
|
+
include Mongoid::Document
|
24
|
+
|
25
|
+
embedded_in :parent, class_name: 'SomethingBogusThatDoesNotExistYet'
|
26
|
+
end
|
27
|
+
end.not_to raise_exception
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
describe "#embedded?" do
|
19
33
|
|
20
34
|
let(:person) do
|
@@ -289,6 +289,22 @@ describe Mongoid::Attributes do
|
|
289
289
|
end
|
290
290
|
end
|
291
291
|
|
292
|
+
context "when given nil" do
|
293
|
+
|
294
|
+
it "returns nil" do
|
295
|
+
expect(person[nil]).to be nil
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
context "when given an empty string" do
|
301
|
+
|
302
|
+
it "returns nil" do
|
303
|
+
expect(person[""]).to be nil
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
292
308
|
context "when the field was not explicitly defined" do
|
293
309
|
|
294
310
|
context "when excluding with only and the field was not excluded" do
|
@@ -570,5 +570,16 @@ describe Mongoid::Contextual::Aggregable::Memory do
|
|
570
570
|
expect(sum).to eq(1500)
|
571
571
|
end
|
572
572
|
end
|
573
|
+
|
574
|
+
context "when provided a block with initial value" do
|
575
|
+
|
576
|
+
let(:sum) do
|
577
|
+
context.sum(500, &:likes)
|
578
|
+
end
|
579
|
+
|
580
|
+
it "returns the sum for the provided block starting from initial value" do
|
581
|
+
expect(sum).to eq(2000)
|
582
|
+
end
|
583
|
+
end
|
573
584
|
end
|
574
585
|
end
|
@@ -515,6 +515,17 @@ describe Mongoid::Contextual::Aggregable::Mongo do
|
|
515
515
|
expect(sum).to eq(1500)
|
516
516
|
end
|
517
517
|
end
|
518
|
+
|
519
|
+
context "when provided a block with initial value" do
|
520
|
+
|
521
|
+
let(:sum) do
|
522
|
+
context.sum(500, &:likes)
|
523
|
+
end
|
524
|
+
|
525
|
+
it "returns the sum for the provided block starting from initial value" do
|
526
|
+
expect(sum).to eq(2000)
|
527
|
+
end
|
528
|
+
end
|
518
529
|
end
|
519
530
|
end
|
520
531
|
|
@@ -3640,6 +3640,75 @@ describe Mongoid::Contextual::Mongo do
|
|
3640
3640
|
expect(new_order.reload.genres).to eq(["electronic"])
|
3641
3641
|
end
|
3642
3642
|
end
|
3643
|
+
|
3644
|
+
context "when operation is $pull" do
|
3645
|
+
context "when pulling single element" do
|
3646
|
+
|
3647
|
+
before do
|
3648
|
+
depeche_mode.update_attribute(:genres, ["electronic", "pop"])
|
3649
|
+
new_order.update_attribute(:genres, ["electronic", "pop"])
|
3650
|
+
context.update_all("$pull" => { genres: "electronic" })
|
3651
|
+
end
|
3652
|
+
|
3653
|
+
it "updates the first matching document" do
|
3654
|
+
expect(depeche_mode.reload.genres).to eq(["pop"])
|
3655
|
+
end
|
3656
|
+
|
3657
|
+
it "updates the last matching document" do
|
3658
|
+
expect(new_order.reload.genres).to eq(["pop"])
|
3659
|
+
end
|
3660
|
+
end
|
3661
|
+
|
3662
|
+
context "when pulling based on condition" do
|
3663
|
+
before do
|
3664
|
+
depeche_mode.update_attribute(:genres, ["electronic", "pop", "dance"])
|
3665
|
+
new_order.update_attribute(:genres, ["electronic", "pop", "dance"])
|
3666
|
+
context.update_all("$pull" => { genres: { '$in' => ["electronic", "pop"] } })
|
3667
|
+
end
|
3668
|
+
|
3669
|
+
it "updates the first matching document" do
|
3670
|
+
expect(depeche_mode.reload.genres).to eq(["dance"])
|
3671
|
+
end
|
3672
|
+
|
3673
|
+
it "updates the last matching document" do
|
3674
|
+
expect(new_order.reload.genres).to eq(["dance"])
|
3675
|
+
end
|
3676
|
+
end
|
3677
|
+
end
|
3678
|
+
|
3679
|
+
context "when operation is $pop" do
|
3680
|
+
|
3681
|
+
before do
|
3682
|
+
depeche_mode.update_attribute(:genres, ["pop", "electronic"])
|
3683
|
+
end
|
3684
|
+
|
3685
|
+
it "removes first element in array" do
|
3686
|
+
context.update_all("$pop" => { genres: -1 })
|
3687
|
+
expect(depeche_mode.reload.genres).to eq(["electronic"])
|
3688
|
+
end
|
3689
|
+
|
3690
|
+
it "removes last element in array" do
|
3691
|
+
context.update_all("$pop" => { genres: 1 })
|
3692
|
+
expect(depeche_mode.reload.genres).to eq(["pop"])
|
3693
|
+
end
|
3694
|
+
end
|
3695
|
+
|
3696
|
+
context "when operation is $pullAll" do
|
3697
|
+
|
3698
|
+
before do
|
3699
|
+
depeche_mode.update_attribute(:genres, ["pop", "electronic", "dance", "pop" ])
|
3700
|
+
new_order.update_attribute(:genres, ["electronic", "pop", "electronic", "dance"])
|
3701
|
+
context.update_all("$pullAll" => { genres: ["pop", "electronic"] })
|
3702
|
+
end
|
3703
|
+
|
3704
|
+
it "updates the first matching document" do
|
3705
|
+
expect(depeche_mode.reload.genres).to eq(["dance"])
|
3706
|
+
end
|
3707
|
+
|
3708
|
+
it "updates the last matching document" do
|
3709
|
+
expect(new_order.reload.genres).to eq(["dance"])
|
3710
|
+
end
|
3711
|
+
end
|
3643
3712
|
end
|
3644
3713
|
|
3645
3714
|
context 'when using aliased field names' do
|
@@ -3659,15 +3728,15 @@ describe Mongoid::Contextual::Mongo do
|
|
3659
3728
|
context "when the attributes must be mongoized" do
|
3660
3729
|
|
3661
3730
|
before do
|
3662
|
-
context.update_all("$set" => {
|
3731
|
+
context.update_all("$set" => { location: LatLng.new(52.30, 13.25) })
|
3663
3732
|
end
|
3664
3733
|
|
3665
3734
|
it "updates the first matching document" do
|
3666
|
-
expect(depeche_mode.reload.
|
3735
|
+
expect(depeche_mode.reload.location).to eq(LatLng.new(52.30, 13.25))
|
3667
3736
|
end
|
3668
3737
|
|
3669
3738
|
it "updates the last matching document" do
|
3670
|
-
expect(new_order.reload.
|
3739
|
+
expect(new_order.reload.location).to eq(LatLng.new(52.30, 13.25))
|
3671
3740
|
end
|
3672
3741
|
end
|
3673
3742
|
end
|
data/spec/mongoid/fields_spec.rb
CHANGED
@@ -1871,12 +1871,12 @@ describe Mongoid::Fields do
|
|
1871
1871
|
|
1872
1872
|
context 'given nil' do
|
1873
1873
|
subject { Person.database_field_name(nil) }
|
1874
|
-
it { is_expected.to eq
|
1874
|
+
it { is_expected.to eq '' }
|
1875
1875
|
end
|
1876
1876
|
|
1877
1877
|
context 'given an empty String' do
|
1878
1878
|
subject { Person.database_field_name('') }
|
1879
|
-
it { is_expected.to eq
|
1879
|
+
it { is_expected.to eq '' }
|
1880
1880
|
end
|
1881
1881
|
|
1882
1882
|
context 'given a String' do
|