mongoid 7.1.0 → 7.1.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 +0 -0
- data/CHANGELOG.md +6 -6
- data/README.md +1 -1
- data/lib/config/locales/en.yml +4 -4
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +38 -2
- data/lib/mongoid/association/referenced/eager.rb +29 -9
- data/lib/mongoid/config.rb +39 -9
- data/lib/mongoid/criteria.rb +16 -3
- data/lib/mongoid/criteria/queryable/pipeline.rb +3 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +94 -7
- data/lib/mongoid/criteria/queryable/storable.rb +104 -99
- data/lib/mongoid/errors/eager_load.rb +2 -0
- data/lib/mongoid/persistable/pushable.rb +7 -1
- data/lib/mongoid/serializable.rb +9 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +32 -23
- data/spec/app/models/coding.rb +4 -0
- data/spec/app/models/coding/pull_request.rb +12 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/publication.rb +5 -0
- data/spec/app/models/publication/encyclopedia.rb +12 -0
- data/spec/app/models/publication/review.rb +14 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +193 -10
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +504 -127
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/storable_spec.rb +80 -2
- data/spec/mongoid/criteria_spec.rb +32 -0
- data/spec/mongoid/persistable/pushable_spec.rb +55 -1
- data/spec/mongoid/serializable_spec.rb +129 -18
- data/spec/spec_helper.rb +2 -0
- data/spec/support/expectations.rb +3 -1
- data/spec/support/helpers.rb +11 -0
- metadata +504 -490
- metadata.gz.sig +0 -0
@@ -24,7 +24,13 @@ module Mongoid
|
|
24
24
|
def add_to_set(adds)
|
25
25
|
prepare_atomic_operation do |ops|
|
26
26
|
process_atomic_operations(adds) do |field, value|
|
27
|
-
existing = send(field) ||
|
27
|
+
existing = send(field) || attributes[field]
|
28
|
+
if existing.nil?
|
29
|
+
attributes[field] = []
|
30
|
+
# Read the value out of attributes:
|
31
|
+
# https://jira.mongodb.org/browse/MONGOID-4874
|
32
|
+
existing = attributes[field]
|
33
|
+
end
|
28
34
|
values = [ value ].flatten(1)
|
29
35
|
values.each do |val|
|
30
36
|
existing.push(val) unless existing.include?(val)
|
data/lib/mongoid/serializable.rb
CHANGED
@@ -13,10 +13,16 @@ module Mongoid
|
|
13
13
|
# We need to redefine where the JSON configuration is getting defined,
|
14
14
|
# similar to +ActiveRecord+.
|
15
15
|
included do
|
16
|
-
extend Forwardable
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
class << self
|
18
|
+
# Note that this intentionally only delegates :include_root_in_json
|
19
|
+
# and not :include_root_in_json? - delegating the latter produces
|
20
|
+
# wrong behavior.
|
21
|
+
# Also note that this intentionally uses the ActiveSupport delegation
|
22
|
+
# functionality and not the Ruby standard library one.
|
23
|
+
# See https://jira.mongodb.org/browse/MONGOID-4849.
|
24
|
+
delegate :include_root_in_json, to: ::Mongoid
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
28
|
# Gets the document as a serializable hash, used by ActiveModel's JSON
|
data/lib/mongoid/version.rb
CHANGED
@@ -114,12 +114,37 @@ development:
|
|
114
114
|
|
115
115
|
# Configure Mongoid specific options. (optional)
|
116
116
|
options:
|
117
|
-
#
|
117
|
+
# Application name that is printed to the mongodb logs upon establishing
|
118
|
+
# a connection in server versions >= 3.4. Note that the name cannot
|
119
|
+
# exceed 128 bytes. It is also used as the database name if the
|
120
|
+
# database name is not explicitly defined. (default: nil)
|
121
|
+
# app_name: MyApplicationName
|
122
|
+
|
123
|
+
# Create indexes in background by default. (default: false)
|
124
|
+
# background_indexing: false
|
125
|
+
|
126
|
+
# Mark belongs_to associations as required by default, so that saving a
|
127
|
+
# model with a missing belongs_to association will trigger a validation
|
128
|
+
# error. (default: true)
|
129
|
+
# belongs_to_required_by_default: true
|
130
|
+
|
131
|
+
# Raise an exception when a field is redefined. (default: false)
|
132
|
+
# duplicate_fields_exception: false
|
133
|
+
|
134
|
+
# Include the root model name in json serialization. (default: false)
|
118
135
|
# include_root_in_json: false
|
119
136
|
|
120
137
|
# Include the _type field in serialization. (default: false)
|
121
138
|
# include_type_for_serialization: false
|
122
139
|
|
140
|
+
# Whether to join nested persistence contexts for atomic operations
|
141
|
+
# to parent contexts by default. (default: false)
|
142
|
+
# join_contexts: false
|
143
|
+
|
144
|
+
# Set the Mongoid and Ruby driver log levels when Mongoid is not using
|
145
|
+
# Ruby on Rails logger instance. (default: :info)
|
146
|
+
# log_level: :info
|
147
|
+
|
123
148
|
# Preload all models in development, needed when models use
|
124
149
|
# inheritance. (default: false)
|
125
150
|
# preload_models: false
|
@@ -132,32 +157,16 @@ development:
|
|
132
157
|
# existing method. (default: false)
|
133
158
|
# scope_overwrite_exception: false
|
134
159
|
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
|
139
|
-
# Use Active Support's time zone in conversions. (default: true)
|
160
|
+
# Use ActiveSupport's time zone in time operations instead of
|
161
|
+
# the Ruby default time zone. See the time zone section below for
|
162
|
+
# further information. (default: true)
|
140
163
|
# use_activesupport_time_zone: true
|
141
164
|
|
142
|
-
#
|
165
|
+
# Return stored times as UTC. See the time zone section below for
|
166
|
+
# further information. Most applications should not use this option.
|
167
|
+
# (default: false)
|
143
168
|
# use_utc: false
|
144
169
|
|
145
|
-
# Set the Mongoid and Ruby driver log levels when not in a Rails
|
146
|
-
# environment. The Mongoid logger will be set to the Rails logger
|
147
|
-
# otherwise.(default: :info)
|
148
|
-
# log_level: :info
|
149
|
-
|
150
|
-
# Control whether `belongs_to` association is required. By default
|
151
|
-
# `belongs_to` will trigger a validation error if the association
|
152
|
-
# is not present. (default: true)
|
153
|
-
# belongs_to_required_by_default: true
|
154
|
-
|
155
|
-
# Application name that is printed to the mongodb logs upon establishing a
|
156
|
-
# connection in server versions >= 3.4. Note that the name cannot exceed 128 bytes.
|
157
|
-
# app_name: MyApplicationName
|
158
|
-
|
159
|
-
# Use background indexes by default if `background` option not specified. (default: false)
|
160
|
-
# background_indexing: false
|
161
170
|
test:
|
162
171
|
clients:
|
163
172
|
default:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
class DelegatingPatient
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
embeds_one :email
|
8
|
+
|
9
|
+
# Instance level delegation
|
10
|
+
delegate :address, to: :email
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Class level delegation
|
14
|
+
delegate :default_client, to: ::Mongoid
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
module Publication
|
5
|
+
class Review
|
6
|
+
include Mongoid::Document
|
7
|
+
|
8
|
+
field :summary
|
9
|
+
|
10
|
+
belongs_to :reviewable, polymorphic: true
|
11
|
+
belongs_to :reviewer, polymorphic: true
|
12
|
+
belongs_to :template
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe Mongoid::Document do
|
7
|
+
context 'when including class uses delegate' do
|
8
|
+
let(:patient) do
|
9
|
+
DelegatingPatient.new(
|
10
|
+
email: Email.new(address: 'test@example.com'),
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'works for instance level delegation' do
|
15
|
+
patient.address.should == 'test@example.com'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'works for class level delegation' do
|
19
|
+
DelegatingPatient.default_client.should be Mongoid.default_client
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -114,13 +114,13 @@ describe Mongoid::Association::Referenced::BelongsTo::Eager do
|
|
114
114
|
end
|
115
115
|
|
116
116
|
it "does not query when touching the association" do
|
117
|
-
|
117
|
+
expect_no_queries do
|
118
118
|
expect(eager.person).to eq(person)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
122
|
it "does not query when updating the association" do
|
123
|
-
|
123
|
+
expect_no_queries do
|
124
124
|
eager.person.username = "arthurnn"
|
125
125
|
end
|
126
126
|
end
|
@@ -146,18 +146,201 @@ describe Mongoid::Association::Referenced::BelongsTo::Eager do
|
|
146
146
|
|
147
147
|
context "when the association is polymorphic" do
|
148
148
|
|
149
|
-
|
150
|
-
|
149
|
+
context "without namespaces" do
|
150
|
+
|
151
|
+
let!(:stand_alone_rating) do
|
152
|
+
Rating.create(value: 7)
|
153
|
+
end
|
154
|
+
|
155
|
+
let!(:bar) do
|
156
|
+
Bar.create(name: "FooBar")
|
157
|
+
end
|
158
|
+
|
159
|
+
let(:bar_rating) do
|
160
|
+
bar.create_rating(value: 5)
|
161
|
+
end
|
162
|
+
|
163
|
+
let!(:movie) do
|
164
|
+
Movie.create(name: "Bladerunner")
|
165
|
+
end
|
166
|
+
|
167
|
+
let(:movie_rating) do
|
168
|
+
movie.ratings.create(value: 10)
|
169
|
+
end
|
170
|
+
|
171
|
+
let(:eager) do
|
172
|
+
Rating.includes(:ratable).entries
|
173
|
+
end
|
174
|
+
|
175
|
+
context "when the eager load has returned documents" do
|
176
|
+
|
177
|
+
before do
|
178
|
+
bar_rating
|
179
|
+
movie_rating
|
180
|
+
eager
|
181
|
+
end
|
182
|
+
|
183
|
+
it "puts the documents in the parent document" do
|
184
|
+
expect(eager.map { |e| e.ivar(:ratable) }).to eq([nil, bar, movie])
|
185
|
+
end
|
186
|
+
|
187
|
+
it "does not query when touching the association" do
|
188
|
+
expect_no_queries do
|
189
|
+
expect(eager.map(&:ratable)).to eq([nil, bar, movie])
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
it "does not query when updating the association" do
|
194
|
+
expect_no_queries do
|
195
|
+
eager.last.ratable.name = "Easy rider"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context "when the eager load has not returned documents" do
|
201
|
+
|
202
|
+
before { eager }
|
203
|
+
|
204
|
+
it "does not set anything on the parent" do
|
205
|
+
expect(eager.map { |e| e.ivar(:ratable) }).to all(be nil)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "has a nil association" do
|
209
|
+
expect(eager.map(&:ratable)).to all(be nil)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "with namespaces" do
|
215
|
+
|
216
|
+
let!(:stand_alone_review) do
|
217
|
+
Publication::Review.create(summary: "awful")
|
218
|
+
end
|
219
|
+
|
220
|
+
let!(:encyclopedia) do
|
221
|
+
Publication::Encyclopedia.create(title: "Encyclopedia Britannica")
|
222
|
+
end
|
223
|
+
|
224
|
+
let(:encyclopedia_review) do
|
225
|
+
encyclopedia.reviews.create(summary: "inspiring")
|
226
|
+
end
|
227
|
+
|
228
|
+
let!(:pull_request) do
|
229
|
+
Coding::PullRequest.create(title: "Add eager loading for polymorphic belongs_to associations")
|
230
|
+
end
|
231
|
+
|
232
|
+
let(:pull_request_review) do
|
233
|
+
pull_request.reviews.create(summary: "Looks good to me")
|
234
|
+
end
|
235
|
+
|
236
|
+
let(:eager) do
|
237
|
+
Publication::Review.includes(:reviewable).entries
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when the eager load has returned documents" do
|
241
|
+
|
242
|
+
before do
|
243
|
+
encyclopedia_review
|
244
|
+
pull_request_review
|
245
|
+
eager
|
246
|
+
end
|
247
|
+
|
248
|
+
it "puts the documents in the parent document" do
|
249
|
+
expect(eager.map { |e| e.ivar(:reviewable) }).to eq([nil, encyclopedia, pull_request])
|
250
|
+
end
|
251
|
+
|
252
|
+
it "does not query when touching the association" do
|
253
|
+
expect_no_queries do
|
254
|
+
expect(eager.map(&:reviewable)).to eq([nil, encyclopedia, pull_request])
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
it "does not query when updating the association" do
|
259
|
+
expect_no_queries do
|
260
|
+
eager.last.reviewable.title = "Load stuff eagerly"
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context "when the eager load has not returned documents" do
|
266
|
+
|
267
|
+
before { eager }
|
268
|
+
|
269
|
+
it "does not set anything on the parent" do
|
270
|
+
expect(eager.map { |e| e.ivar(:reviewable) }).to all(be nil)
|
271
|
+
end
|
272
|
+
|
273
|
+
it "has a nil association" do
|
274
|
+
expect(eager.map(&:reviewable)).to all(be nil)
|
275
|
+
end
|
276
|
+
end
|
151
277
|
end
|
152
278
|
|
153
|
-
|
154
|
-
|
279
|
+
context 'when eager loading multiple associations' do
|
280
|
+
let(:reviewable) do
|
281
|
+
Publication::Encyclopedia.create!(title: "Encyclopedia Britannica")
|
282
|
+
end
|
283
|
+
|
284
|
+
let!(:reviewable_review) do
|
285
|
+
Publication::Review.create!(summary: "awful",
|
286
|
+
reviewable: reviewable)
|
287
|
+
end
|
288
|
+
|
289
|
+
let(:reviewer) do
|
290
|
+
Dog.create!
|
291
|
+
end
|
292
|
+
|
293
|
+
let!(:reviewer_review) do
|
294
|
+
Publication::Review.create(summary: "okay",
|
295
|
+
reviewer: reviewer)
|
296
|
+
end
|
297
|
+
|
298
|
+
let(:template) do
|
299
|
+
Template.create!
|
300
|
+
end
|
301
|
+
|
302
|
+
let!(:template_review) do
|
303
|
+
Publication::Review.create(summary: "Looks good to me",
|
304
|
+
template: template)
|
305
|
+
end
|
306
|
+
|
307
|
+
let(:eager) do
|
308
|
+
Publication::Review.includes(:reviewable, :reviewer, :template).entries
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'loads all associations eagerly' do
|
312
|
+
loaded = expect_query(4) do
|
313
|
+
eager
|
314
|
+
end
|
315
|
+
|
316
|
+
expect_no_queries do
|
317
|
+
eager.map(&:reviewable).compact.should == [reviewable]
|
318
|
+
end
|
319
|
+
|
320
|
+
expect_no_queries do
|
321
|
+
eager.map(&:reviewer).compact.should == [reviewer]
|
322
|
+
end
|
323
|
+
|
324
|
+
expect_no_queries do
|
325
|
+
eager.map(&:template).compact.should == [template]
|
326
|
+
end
|
327
|
+
end
|
155
328
|
end
|
156
329
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
330
|
+
context 'when eager loading an association that has type but not value set' do
|
331
|
+
|
332
|
+
let!(:reviewer_review) do
|
333
|
+
Publication::Review.create(summary: "okay",
|
334
|
+
reviewer_type: 'Dog')
|
335
|
+
end
|
336
|
+
|
337
|
+
let(:eager) do
|
338
|
+
Publication::Review.includes(:reviewable, :reviewer, :template).entries
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'does not error' do
|
342
|
+
eager.map(&:reviewer).should == [nil]
|
343
|
+
end
|
161
344
|
end
|
162
345
|
end
|
163
346
|
|