mongoid 5.0.0 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CHANGELOG.md +54 -2
- data/lib/config/locales/en.yml +1 -1
- data/lib/mongoid/attributes.rb +1 -1
- data/lib/mongoid/clients.rb +7 -4
- data/lib/mongoid/clients/options.rb +2 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +2 -1
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +4 -1
- data/lib/mongoid/contextual/mongo.rb +4 -5
- data/lib/mongoid/document.rb +1 -0
- data/lib/mongoid/indexable/specification.rb +3 -5
- data/lib/mongoid/indexable/validators/options.rb +7 -1
- data/lib/mongoid/matchable/exists.rb +1 -1
- data/lib/mongoid/persistable.rb +2 -1
- data/lib/mongoid/persistable/creatable.rb +1 -1
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/positional.rb +75 -0
- data/lib/mongoid/relations/counter_cache.rb +19 -0
- data/lib/mongoid/relations/eager/base.rb +4 -2
- data/lib/mongoid/relations/embedded/batchable.rb +10 -3
- data/lib/mongoid/relations/proxy.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +6 -5
- data/lib/mongoid/selectable.rb +36 -1
- data/lib/mongoid/threaded.rb +34 -2
- data/lib/mongoid/timestamps/created.rb +1 -2
- data/lib/mongoid/timestamps/timeless.rb +19 -2
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -1
- data/spec/app/models/account.rb +8 -0
- data/spec/app/models/answer.rb +2 -0
- data/spec/app/models/article.rb +2 -0
- data/spec/app/models/author.rb +2 -0
- data/spec/app/models/baby.rb +4 -0
- data/spec/app/models/book.rb +2 -0
- data/spec/app/models/consumption_period.rb +7 -0
- data/spec/app/models/exhibitor.rb +1 -0
- data/spec/app/models/kaleidoscope.rb +6 -0
- data/spec/app/models/kangaroo.rb +4 -0
- data/spec/app/models/note.rb +3 -0
- data/spec/app/models/page.rb +11 -0
- data/spec/app/models/simple.rb +5 -0
- data/spec/config/mongoid.yml +3 -1
- data/spec/mongoid/atomic/paths_spec.rb +17 -10
- data/spec/mongoid/attributes_spec.rb +2 -2
- data/spec/mongoid/clients/options_spec.rb +15 -0
- data/spec/mongoid/clients_spec.rb +6 -2
- data/spec/mongoid/config_spec.rb +3 -2
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +25 -2
- data/spec/mongoid/contextual/atomic_spec.rb +6 -6
- data/spec/mongoid/contextual/mongo_spec.rb +28 -75
- data/spec/mongoid/criteria_spec.rb +54 -0
- data/spec/mongoid/fields/standard_spec.rb +1 -1
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/indexable/specification_spec.rb +1 -1
- data/spec/mongoid/indexable_spec.rb +7 -7
- data/spec/mongoid/interceptable_spec.rb +55 -0
- data/spec/mongoid/persistable/creatable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +50 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +56 -4
- data/spec/mongoid/persistable/pushable_spec.rb +11 -0
- data/spec/mongoid/persistable/savable_spec.rb +20 -2
- data/spec/mongoid/positional_spec.rb +221 -0
- data/spec/mongoid/query_cache_spec.rb +19 -0
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +1 -1
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -11
- data/spec/mongoid/relations/eager/has_many_spec.rb +37 -0
- data/spec/mongoid/relations/eager_spec.rb +11 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +38 -9
- data/spec/mongoid/relations/embedded/one_spec.rb +1 -1
- data/spec/mongoid/relations/proxy_spec.rb +22 -0
- data/spec/mongoid/relations/reflections_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +160 -19
- data/spec/mongoid/selectable_spec.rb +16 -6
- data/spec/mongoid/timestamps/timeless_spec.rb +17 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +17 -0
- metadata +40 -5
- metadata.gz.sig +3 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8dff7445e398ee462ff1e26c6baaa5684ee9318d
|
4
|
+
data.tar.gz: beb9a64681e530861fcece3129d5347484342344
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d86170a4c56e57d6d5e11d89003307e9a7c8f2e45d2c75d7cb98ef81781b66a05b69ba8a71701161c0ef800a2284a322beaff08c6a3a70d03014d7313f7f8205
|
7
|
+
data.tar.gz: d8615708189aee7700312ac743c8ae63d69d092f45788f4137c9ec3e931985a876d38ec08819359b960e3a64a333c981535b1da8f6405ab55d2dc6d591d15d37
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
data/CHANGELOG.md
CHANGED
@@ -3,7 +3,59 @@
|
|
3
3
|
For instructions on upgrading to newer versions, visit
|
4
4
|
[mongoid.org](http://mongoid.org/en/mongoid/docs/upgrading.html).
|
5
5
|
|
6
|
-
## 5.0.
|
6
|
+
## 5.0.1
|
7
|
+
|
8
|
+
### Resolved Issues
|
9
|
+
|
10
|
+
* [MONGOID-3020](https://jira.mongodb.org/browse/MONGOID-3020) Test added to show it's no longer an issue.
|
11
|
+
* [MONGOID-3025](https://jira.mongodb.org/browse/MONGOID-3025) Test added to show it's no longer an issue.
|
12
|
+
* [MONGOID-3061](https://jira.mongodb.org/browse/MONGOID-3061) No longer an issue.
|
13
|
+
* [MONGOID-3073](https://jira.mongodb.org/browse/MONGOID-3073) Test added to show it's no longer an issue.
|
14
|
+
* [MONGOID-3085](https://jira.mongodb.org/browse/MONGOID-3085) Test added to show it's no longer an issue.
|
15
|
+
* [MONGOID-3101](https://jira.mongodb.org/browse/MONGOID-3101) No longer an issue.
|
16
|
+
* [MONGOID-3160](https://jira.mongodb.org/browse/MONGOID-3160) No longer an issue.
|
17
|
+
* [MONGOID-3176](https://jira.mongodb.org/browse/MONGOID-3176) No longer an issue.
|
18
|
+
* [MONGOID-3214](https://jira.mongodb.org/browse/MONGOID-3214) Test added to show it's no longer an issue.
|
19
|
+
* [MONGOID-3296](https://jira.mongodb.org/browse/MONGOID-3296) Add update callback for counter_cache.
|
20
|
+
* [MONGOID-3326](https://jira.mongodb.org/browse/MONGOID-3326) Test added to show it's no longer an issue.
|
21
|
+
* [MONGOID-3361](https://jira.mongodb.org/browse/MONGOID-3361) No longer an issue.
|
22
|
+
* [MONGOID-3365](https://jira.mongodb.org/browse/MONGOID-3365) Test added to show it's no longer an issue.
|
23
|
+
* [MONGOID-3402](https://jira.mongodb.org/browse/MONGOID-3402) Apply persistence options to parent.
|
24
|
+
* [MONGOID-3524](https://jira.mongodb.org/browse/MONGOID-3524) No longer an issue.
|
25
|
+
* [MONGOID-3529](https://jira.mongodb.org/browse/MONGOID-3529) Test exists already showing it's not an issue.
|
26
|
+
* [MONGOID-3543](https://jira.mongodb.org/browse/MONGOID-3543) Test exists already showing it's not an issue.
|
27
|
+
* [MONGOID-3611](https://jira.mongodb.org/browse/MONGOID-3611) Test added to show it's no longer an issue.
|
28
|
+
* [MONGOID-3650](https://jira.mongodb.org/browse/MONGOID-3650) No longer an issue.
|
29
|
+
* [MONGOID-3826](https://jira.mongodb.org/browse/MONGOID-3826), [MONGOID-4109](https://jira.mongodb.org/browse/MONGOID-4109) Fix Timelessness leaks.
|
30
|
+
* [MONGOID-3946](https://jira.mongodb.org/browse/MONGOID-3946) Test added to show it's no longer an issue.
|
31
|
+
* [MONGOID-3969](https://jira.mongodb.org/browse/MONGOID-3969) Test added to show it's no longer an issue.
|
32
|
+
* [MONGOID-3971](https://jira.mongodb.org/browse/MONGOID-3971) Not an issue.
|
33
|
+
* [MONGOID-3979](https://jira.mongodb.org/browse/MONGOID-3979) Not an issue, tests exist already.
|
34
|
+
* [MONGOID-3985](https://jira.mongodb.org/browse/MONGOID-3985) Not an issue.
|
35
|
+
* [MONGOID-4078](https://jira.mongodb.org/browse/MONGOID-4078) Behavior is intended.
|
36
|
+
* [MONGOID-4079](https://jira.mongodb.org/browse/MONGOID-4079) Not an issue.
|
37
|
+
* [MONGOID-4088](https://jira.mongodb.org/browse/MONGOID-4088) Account for sub-document dot notation with #pluck results.
|
38
|
+
* [MONGOID-4098](https://jira.mongodb.org/browse/MONGOID-4098) Fixed by a change to the Ruby driver. See RUBY-1029.
|
39
|
+
* [MONGOID-4101](https://jira.mongodb.org/browse/MONGOID-4101) Not an issue.
|
40
|
+
* [MONGOID-4106](https://jira.mongodb.org/browse/MONGOID-4106) Not an issue.
|
41
|
+
* [MONGOID-4110](https://jira.mongodb.org/browse/MONGOID-4110) Not an issue.
|
42
|
+
* [MONGOID-4119](https://jira.mongodb.org/browse/MONGOID-4119) Ensure that criteria selector becomes pipeline operator value.
|
43
|
+
* [MONGOID-4121](https://jira.mongodb.org/browse/MONGOID-4121) Not an issue.
|
44
|
+
* [MONGOID-4123](https://jira.mongodb.org/browse/MONGOID-4123) Fixed as a result of MONGOID-4159.
|
45
|
+
* [MONGOID-4125](https://jira.mongodb.org/browse/MONGOID-4125) Make sure none scopes referenced in procs are applied.
|
46
|
+
* [MONGOID-4132](https://jira.mongodb.org/browse/MONGOID-4132) Not an issue.
|
47
|
+
* [MONGOID-4157](https://jira.mongodb.org/browse/MONGOID-4157) Fixed by version 2.1.2 of the Ruby driver.
|
48
|
+
* [MONGOID-4162](https://jira.mongodb.org/browse/MONGOID-4162) Adapt index option mappings to new driver. (@Nielsomat)
|
49
|
+
* [MONGOID-3737](https://jira.mongodb.org/browse/MONGOID-3737) Test added to show it's no longer an issue.
|
50
|
+
* [MONGOID-3621](https://jira.mongodb.org/browse/MONGOID-3621) Not an issue.
|
51
|
+
* [MONGOID-3551](https://jira.mongodb.org/browse/MONGOID-3551) Not an issue.
|
52
|
+
* [MONGOID-3696](https://jira.mongodb.org/browse/MONGOID-3696) Test added to show it's no longer an issue.
|
53
|
+
* [MONGOID-3858](https://jira.mongodb.org/browse/MONGOID-3858) Test added to show it's no longer an issue.
|
54
|
+
* [MONGOID-3672](https://jira.mongodb.org/browse/MONGOID-3672) Not an issue.
|
55
|
+
* [MONGOID-4172](https://jira.mongodb.org/browse/MONGOID-4172) Use positional operator only on 1 level deep nesting.
|
56
|
+
* Added public cert to repo and sign gem if private key is present
|
57
|
+
|
58
|
+
## 5.0.0
|
7
59
|
|
8
60
|
### Major Changes (Backwards Incompatible)
|
9
61
|
|
@@ -2955,7 +3007,7 @@ child elements.
|
|
2955
3007
|
|
2956
3008
|
* \#1394 Fix exists? to work when count is greater than 1. (Nick Hoffman)
|
2957
3009
|
|
2958
|
-
* \#1392 Return 0 on aggregation functions where field is
|
3010
|
+
* \#1392 Return 0 on aggregation functions where field is nonexistent.
|
2959
3011
|
|
2960
3012
|
* \#1391 Uniqueness validation now works properly on embedded documents that are
|
2961
3013
|
using primary key definitions.
|
data/lib/config/locales/en.yml
CHANGED
@@ -447,7 +447,7 @@ en:
|
|
447
447
|
summary: "You cannot call create or create! through the
|
448
448
|
relation (%{document}) whose parent (%{base}) is
|
449
449
|
not already saved. This would cause the database to be out of sync
|
450
|
-
since the child could potentially reference a
|
450
|
+
since the child could potentially reference a nonexistent parent."
|
451
451
|
resolution: "Make sure to only use create or create! when the parent
|
452
452
|
document %{base} is persisted."
|
453
453
|
unsupported_javascript:
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -294,7 +294,7 @@ module Mongoid
|
|
294
294
|
module ClassMethods
|
295
295
|
|
296
296
|
# Alias the provided name to the original field. This will provide an
|
297
|
-
# aliased getter, setter,
|
297
|
+
# aliased getter, setter, existence check, and all dirty attribute
|
298
298
|
# methods.
|
299
299
|
#
|
300
300
|
# @example Alias the attribute.
|
data/lib/mongoid/clients.rb
CHANGED
@@ -115,10 +115,13 @@ module Mongoid
|
|
115
115
|
#
|
116
116
|
# @since 3.0.0
|
117
117
|
def mongo_client
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
118
|
+
client = Clients.with_name(client_name)
|
119
|
+
opts = self.persistence_options ? self.persistence_options.dup : {}
|
120
|
+
if defined?(Mongo::Client::VALID_OPTIONS)
|
121
|
+
opts.reject! { |k, v| !Mongo::Client::VALID_OPTIONS.include?(k.to_sym) }
|
122
|
+
end
|
123
|
+
opts.merge!(database: database_name) unless client.database.name.to_sym == database_name.to_sym
|
124
|
+
client.with(opts)
|
122
125
|
end
|
123
126
|
alias :mongo_session :mongo_client
|
124
127
|
deprecate :mongo_session, :mongo_client, 2015, 12
|
@@ -5,7 +5,7 @@ module Mongoid
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
extend Gem::Deprecate
|
7
7
|
|
8
|
-
# Tell the next
|
8
|
+
# Tell the next persistence operation to store in a specific collection,
|
9
9
|
# database or client.
|
10
10
|
#
|
11
11
|
# @example Save the current document to a different collection.
|
@@ -125,7 +125,7 @@ module Mongoid
|
|
125
125
|
super
|
126
126
|
end
|
127
127
|
|
128
|
-
# Tell the next
|
128
|
+
# Tell the next persistence operation to store in a specific collection,
|
129
129
|
# database or client.
|
130
130
|
#
|
131
131
|
# @example Create a document in a different collection.
|
@@ -124,7 +124,8 @@ module Mongoid
|
|
124
124
|
def pipeline(field)
|
125
125
|
db_field = "$#{database_field_name(field)}"
|
126
126
|
pipeline = []
|
127
|
-
pipeline << { "$match" => criteria.
|
127
|
+
pipeline << { "$match" => criteria.selector }
|
128
|
+
pipeline << { "$match" => criteria.exists(field => true).selector }
|
128
129
|
pipeline << { "$sort" => criteria.options[:sort] } if criteria.options[:sort]
|
129
130
|
pipeline << { "$skip" => criteria.options[:skip] } if criteria.options[:skip]
|
130
131
|
pipeline << { "$limit" => criteria.options[:limit] } if criteria.options[:limit]
|
@@ -9,6 +9,7 @@ module Mongoid
|
|
9
9
|
include Aggregable::Memory
|
10
10
|
include Relations::Eager
|
11
11
|
include Queryable
|
12
|
+
include Positional
|
12
13
|
|
13
14
|
# @attribute [r] root The root document.
|
14
15
|
# @attribute [r] path The atomic path.
|
@@ -46,7 +47,9 @@ module Mongoid
|
|
46
47
|
doc.as_document
|
47
48
|
end
|
48
49
|
unless removed.empty?
|
49
|
-
collection.find(selector).update_one(
|
50
|
+
collection.find(selector).update_one(
|
51
|
+
positionally(selector, "$pullAll" => { path => removed })
|
52
|
+
)
|
50
53
|
end
|
51
54
|
deleted
|
52
55
|
end
|
@@ -402,12 +402,11 @@ module Mongoid
|
|
402
402
|
hash
|
403
403
|
end
|
404
404
|
|
405
|
-
view.projection(normalized_select).
|
406
|
-
|
407
|
-
doc[
|
408
|
-
else
|
409
|
-
normalized_select.keys.map { |n| doc[n] }
|
405
|
+
view.projection(normalized_select).reduce([]) do |plucked, doc|
|
406
|
+
values = normalized_select.keys.map do |n|
|
407
|
+
n =~ /\./ ? doc[n.partition('.')[0]] : doc[n]
|
410
408
|
end
|
409
|
+
plucked << (values.size == 1 ? values.first : values)
|
411
410
|
end
|
412
411
|
end
|
413
412
|
|
data/lib/mongoid/document.rb
CHANGED
@@ -7,14 +7,12 @@ module Mongoid
|
|
7
7
|
# @since 4.0.0
|
8
8
|
class Specification
|
9
9
|
|
10
|
-
# The mappings of nice Ruby-style names to the corresponding
|
11
|
-
# name.
|
10
|
+
# The mappings of nice Ruby-style names to the corresponding driver
|
11
|
+
# option name.
|
12
12
|
#
|
13
13
|
# @since 4.0.0
|
14
14
|
MAPPINGS = {
|
15
|
-
|
16
|
-
drop_dups: :dropDups,
|
17
|
-
expire_after_seconds: :expireAfterSeconds
|
15
|
+
expire_after_seconds: :expire_after
|
18
16
|
}
|
19
17
|
|
20
18
|
# @!attribute klass
|
@@ -11,6 +11,7 @@ module Mongoid
|
|
11
11
|
:background,
|
12
12
|
:database,
|
13
13
|
:default_language,
|
14
|
+
:language_override,
|
14
15
|
:drop_dups,
|
15
16
|
:name,
|
16
17
|
:sparse,
|
@@ -20,7 +21,12 @@ module Mongoid
|
|
20
21
|
:bits,
|
21
22
|
:bucket_size,
|
22
23
|
:expire_after_seconds,
|
23
|
-
:weights
|
24
|
+
:weights,
|
25
|
+
:storage_engine,
|
26
|
+
:key,
|
27
|
+
:sphere_version,
|
28
|
+
:text_version,
|
29
|
+
:version
|
24
30
|
]
|
25
31
|
|
26
32
|
VALID_TYPES = [
|
data/lib/mongoid/persistable.rb
CHANGED
@@ -27,6 +27,7 @@ module Mongoid
|
|
27
27
|
include Incrementable
|
28
28
|
include Logical
|
29
29
|
include Poppable
|
30
|
+
include Positional
|
30
31
|
include Pullable
|
31
32
|
include Pushable
|
32
33
|
include Renamable
|
@@ -208,7 +209,7 @@ module Mongoid
|
|
208
209
|
def persist_atomic_operations(operations)
|
209
210
|
if persisted?
|
210
211
|
selector = atomic_selector
|
211
|
-
_root.collection.find(selector).update_one(operations)
|
212
|
+
_root.collection.find(selector).update_one(positionally(selector, operations))
|
212
213
|
end
|
213
214
|
end
|
214
215
|
end
|
@@ -62,7 +62,7 @@ module Mongoid
|
|
62
62
|
_parent.remove_child(self) if notifying_parent?(options)
|
63
63
|
if _parent.persisted?
|
64
64
|
selector = _parent.atomic_selector
|
65
|
-
_root.collection.find(selector).update_one(atomic_deletes)
|
65
|
+
_root.collection.find(selector).update_one(positionally(selector, atomic_deletes))
|
66
66
|
end
|
67
67
|
true
|
68
68
|
end
|
@@ -141,9 +141,9 @@ module Mongoid
|
|
141
141
|
unless updates.empty?
|
142
142
|
coll = _root.collection
|
143
143
|
selector = atomic_selector
|
144
|
-
coll.find(selector).update_one(updates)
|
144
|
+
coll.find(selector).update_one(positionally(selector, updates))
|
145
145
|
conflicts.each_pair do |key, value|
|
146
|
-
coll.find(selector).update_one({ key => value })
|
146
|
+
coll.find(selector).update_one(positionally(selector, { key => value }))
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
|
4
|
+
# This module is responsible for taking update selectors and switching out
|
5
|
+
# the indexes for the $ positional operator where appropriate.
|
6
|
+
#
|
7
|
+
# @since 4.0.0
|
8
|
+
module Positional
|
9
|
+
|
10
|
+
# Takes the provided selector and atomic operations and replaces the
|
11
|
+
# indexes of the embedded documents with the positional operator when
|
12
|
+
# needed.
|
13
|
+
#
|
14
|
+
# @note The only time we can accurately know when to use the positional
|
15
|
+
# operator is at the exact time we are going to persist something. So
|
16
|
+
# we can tell by the selector that we are sending if it is actually
|
17
|
+
# possible to use the positional operator at all. For example, if the
|
18
|
+
# selector is: { "_id" => 1 }, then we could not use the positional
|
19
|
+
# operator for updating embedded documents since there would never be a
|
20
|
+
# match - we base whether we can based on the number of levels deep the
|
21
|
+
# selector goes, and if the id values are not nil.
|
22
|
+
#
|
23
|
+
# @example Process the operations.
|
24
|
+
# positionally(
|
25
|
+
# { "_id" => 1, "addresses._id" => 2 },
|
26
|
+
# { "$set" => { "addresses.0.street" => "hobrecht" }}
|
27
|
+
# )
|
28
|
+
#
|
29
|
+
# @param [ Hash ] selector The selector.
|
30
|
+
# @param [ Hash ] operations The update operations.
|
31
|
+
# @param [ Hash ] processed The processed update operations.
|
32
|
+
#
|
33
|
+
# @return [ Hash ] The new operations.
|
34
|
+
#
|
35
|
+
# @since 3.1.0
|
36
|
+
def positionally(selector, operations, processed = {})
|
37
|
+
if selector.size == 1 || selector.values.any? { |val| val.nil? }
|
38
|
+
return operations
|
39
|
+
end
|
40
|
+
keys = selector.keys.map{ |m| m.sub('._id','') } - ['_id']
|
41
|
+
keys = keys.sort_by { |s| s.length*-1 }
|
42
|
+
process_operations(keys, operations, processed)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def process_operations(keys, operations, processed)
|
48
|
+
operations.each_pair do |operation, update|
|
49
|
+
processed[operation] = process_updates(keys, update)
|
50
|
+
end
|
51
|
+
processed
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_updates(keys, update, updates = {})
|
55
|
+
update.each_pair do |position, value|
|
56
|
+
updates[replace_index(keys, position)] = value
|
57
|
+
end
|
58
|
+
updates
|
59
|
+
end
|
60
|
+
|
61
|
+
def replace_index(keys, position)
|
62
|
+
# replace index with $ only if that key is in the selector and it is only
|
63
|
+
# nested a single level deep.
|
64
|
+
matches = position.scan(/\.\d+\./)
|
65
|
+
if matches.size == 1
|
66
|
+
keys.each do |kk|
|
67
|
+
if position =~ /^#{kk}\.\d+\.(.*)/
|
68
|
+
return "#{kk}.$.#{$1}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
position
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -103,6 +103,25 @@ module Mongoid
|
|
103
103
|
name = meta.name
|
104
104
|
cache_column = meta.counter_cache_column_name.to_sym
|
105
105
|
|
106
|
+
after_update do
|
107
|
+
if record = __send__(name)
|
108
|
+
id_field = "#{name}_id"
|
109
|
+
|
110
|
+
if attribute_changed?(id_field)
|
111
|
+
original, current = attribute_change(id_field)
|
112
|
+
|
113
|
+
unless original.nil?
|
114
|
+
record.class.decrement_counter(cache_column, original)
|
115
|
+
end
|
116
|
+
|
117
|
+
unless current.nil?
|
118
|
+
record[cache_column] = (record[cache_column] || 0) + 1
|
119
|
+
record.class.increment_counter(cache_column, current) if record.persisted?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
106
125
|
after_create do
|
107
126
|
if record = __send__(name)
|
108
127
|
record[cache_column] = (record[cache_column] || 0) + 1
|
@@ -65,12 +65,14 @@ module Mongoid
|
|
65
65
|
|
66
66
|
# Run the preloader.
|
67
67
|
#
|
68
|
-
# @example Iterate over the documents
|
68
|
+
# @example Iterate over the documents loaded for the current relation
|
69
69
|
# loader.each_loaded_document { |doc| }
|
70
70
|
#
|
71
71
|
# @since 4.0.0
|
72
72
|
def each_loaded_document
|
73
|
-
@metadata.klass.any_in(key => keys_from_docs)
|
73
|
+
criteria = @metadata.klass.any_in(key => keys_from_docs)
|
74
|
+
criteria.inclusions = criteria.inclusions - [ @metadata ]
|
75
|
+
criteria.each do |doc|
|
74
76
|
yield doc
|
75
77
|
end
|
76
78
|
end
|
@@ -6,6 +6,7 @@ module Mongoid
|
|
6
6
|
# Contains behaviour for executing operations in batch on embedded
|
7
7
|
# documents.
|
8
8
|
module Batchable
|
9
|
+
include Positional
|
9
10
|
|
10
11
|
# Insert new documents as a batch push ($pushAll). This ensures that
|
11
12
|
# all callbacks are run at the appropriate time and only 1 request is
|
@@ -36,7 +37,9 @@ module Mongoid
|
|
36
37
|
def batch_clear(docs)
|
37
38
|
pre_process_batch_remove(docs, :delete)
|
38
39
|
unless docs.empty?
|
39
|
-
collection.find(selector).update_one(
|
40
|
+
collection.find(selector).update_one(
|
41
|
+
positionally(selector, "$unset" => { path => true })
|
42
|
+
)
|
40
43
|
post_process_batch_remove(docs, :delete)
|
41
44
|
end
|
42
45
|
_unscoped.clear
|
@@ -54,7 +57,9 @@ module Mongoid
|
|
54
57
|
def batch_remove(docs, method = :delete)
|
55
58
|
removals = pre_process_batch_remove(docs, method)
|
56
59
|
if !docs.empty?
|
57
|
-
collection.find(selector).update_one(
|
60
|
+
collection.find(selector).update_one(
|
61
|
+
positionally(selector, "$pullAll" => { path => removals })
|
62
|
+
)
|
58
63
|
post_process_batch_remove(docs, method)
|
59
64
|
end
|
60
65
|
reindex
|
@@ -125,7 +130,9 @@ module Mongoid
|
|
125
130
|
self.inserts_valid = true
|
126
131
|
inserts = pre_process_batch_insert(docs)
|
127
132
|
if insertable?
|
128
|
-
collection.find(selector).update_one(
|
133
|
+
collection.find(selector).update_one(
|
134
|
+
positionally(selector, operation => { path => inserts })
|
135
|
+
)
|
129
136
|
post_process_batch_insert(docs)
|
130
137
|
end
|
131
138
|
inserts
|