mongoid 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.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
|