mongoid 7.2.6 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +16 -0
  5. data/lib/config/locales/en.yml +2 -15
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +11 -4
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +7 -2
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  18. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  19. data/lib/mongoid/association/relatable.rb +0 -2
  20. data/lib/mongoid/attributes/projector.rb +120 -0
  21. data/lib/mongoid/attributes.rb +24 -13
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients/factory.rb +22 -8
  24. data/lib/mongoid/clients.rb +1 -1
  25. data/lib/mongoid/config/environment.rb +1 -9
  26. data/lib/mongoid/config.rb +19 -2
  27. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  28. data/lib/mongoid/contextual/atomic.rb +2 -7
  29. data/lib/mongoid/contextual/none.rb +0 -3
  30. data/lib/mongoid/copyable.rb +1 -1
  31. data/lib/mongoid/criteria/findable.rb +1 -1
  32. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  33. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  34. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  35. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  36. data/lib/mongoid/criteria/queryable/selectable.rb +10 -10
  37. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  38. data/lib/mongoid/criteria.rb +5 -6
  39. data/lib/mongoid/document.rb +3 -18
  40. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors.rb +0 -2
  43. data/lib/mongoid/evolvable.rb +1 -1
  44. data/lib/mongoid/extensions/boolean.rb +1 -2
  45. data/lib/mongoid/extensions/false_class.rb +1 -1
  46. data/lib/mongoid/extensions/hash.rb +2 -2
  47. data/lib/mongoid/extensions/true_class.rb +1 -1
  48. data/lib/mongoid/fields.rb +43 -5
  49. data/lib/mongoid/inspectable.rb +1 -1
  50. data/lib/mongoid/interceptable.rb +1 -1
  51. data/lib/mongoid/matcher/bits.rb +41 -0
  52. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  53. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  54. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  55. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  56. data/lib/mongoid/matcher/expression.rb +4 -0
  57. data/lib/mongoid/matcher/field_operator.rb +6 -0
  58. data/lib/mongoid/matcher/mod.rb +17 -0
  59. data/lib/mongoid/matcher/type.rb +99 -0
  60. data/lib/mongoid/matcher.rb +7 -0
  61. data/lib/mongoid/persistable/deletable.rb +1 -2
  62. data/lib/mongoid/persistable/destroyable.rb +8 -2
  63. data/lib/mongoid/persistable/updatable.rb +27 -2
  64. data/lib/mongoid/persistence_context.rb +1 -3
  65. data/lib/mongoid/query_cache.rb +36 -40
  66. data/lib/mongoid/selectable.rb +5 -7
  67. data/lib/mongoid/shardable.rb +21 -5
  68. data/lib/mongoid/tasks/database.rb +1 -1
  69. data/lib/mongoid/touchable.rb +23 -4
  70. data/lib/mongoid/validatable/associated.rb +1 -1
  71. data/lib/mongoid/validatable/presence.rb +3 -3
  72. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  73. data/lib/mongoid/version.rb +1 -1
  74. data/lib/mongoid.rb +0 -1
  75. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  76. data/spec/integration/app_spec.rb +0 -3
  77. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  78. data/spec/integration/associations/has_one_spec.rb +48 -0
  79. data/spec/integration/criteria/date_field_spec.rb +1 -1
  80. data/spec/integration/document_spec.rb +9 -0
  81. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  82. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  83. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  84. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  85. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  86. data/spec/integration/matcher_operator_data/in.yml +16 -0
  87. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  88. data/spec/integration/matcher_operator_data/type.yml +70 -0
  89. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  90. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  91. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  92. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  94. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  95. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  96. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  97. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  98. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  100. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  102. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  104. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  105. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  106. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  107. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  108. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  109. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  110. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  111. data/spec/lite_spec_helper.rb +2 -0
  112. data/spec/mongoid/association/depending_spec.rb +391 -352
  113. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4 -17
  114. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  115. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -25
  116. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +0 -20
  117. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  118. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  119. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  120. data/spec/mongoid/association/referenced/has_many_models.rb +0 -17
  121. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  122. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  123. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  124. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  125. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  126. data/spec/mongoid/attributes_spec.rb +98 -6
  127. data/spec/mongoid/clients/factory_spec.rb +51 -9
  128. data/spec/mongoid/clients/options_spec.rb +3 -11
  129. data/spec/mongoid/config/environment_spec.rb +8 -86
  130. data/spec/mongoid/config_spec.rb +32 -0
  131. data/spec/mongoid/contextual/atomic_spec.rb +25 -64
  132. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  133. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  134. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  135. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  136. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  137. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  138. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  139. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  140. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  141. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  142. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  143. data/spec/mongoid/criteria_spec.rb +0 -279
  144. data/spec/mongoid/document_query_spec.rb +0 -51
  145. data/spec/mongoid/document_spec.rb +14 -34
  146. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  147. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -20
  148. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  149. data/spec/mongoid/extensions/string_spec.rb +5 -5
  150. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  151. data/spec/mongoid/fields/localized_spec.rb +4 -4
  152. data/spec/mongoid/fields_spec.rb +4 -4
  153. data/spec/mongoid/inspectable_spec.rb +12 -4
  154. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  155. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  156. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  157. data/spec/mongoid/persistable/updatable_spec.rb +0 -2
  158. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  159. data/spec/mongoid/persistable_spec.rb +2 -2
  160. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  161. data/spec/mongoid/query_cache_spec.rb +0 -24
  162. data/spec/mongoid/reloadable_spec.rb +18 -1
  163. data/spec/mongoid/shardable_spec.rb +44 -0
  164. data/spec/mongoid/touchable_spec.rb +104 -16
  165. data/spec/mongoid/touchable_spec_models.rb +52 -0
  166. data/spec/mongoid/validatable_spec.rb +1 -1
  167. data/spec/shared/lib/mrss/cluster_config.rb +3 -8
  168. data/spec/shared/lib/mrss/constraints.rb +10 -41
  169. data/spec/shared/lib/mrss/docker_runner.rb +1 -7
  170. data/spec/shared/lib/mrss/server_version_registry.rb +12 -17
  171. data/spec/shared/lib/mrss/spec_organizer.rb +1 -18
  172. data/spec/shared/share/Dockerfile.erb +33 -125
  173. data/spec/shared/shlib/server.sh +23 -100
  174. data/spec/shared/shlib/set_env.sh +1 -4
  175. data/spec/spec_helper.rb +7 -3
  176. data/spec/support/client_registry.rb +9 -0
  177. data/spec/support/models/address.rb +0 -4
  178. data/spec/support/models/bolt.rb +8 -0
  179. data/spec/support/models/hole.rb +13 -0
  180. data/spec/support/models/mop.rb +0 -1
  181. data/spec/support/models/nut.rb +8 -0
  182. data/spec/support/models/person.rb +6 -9
  183. data/spec/support/models/sealer.rb +8 -0
  184. data/spec/support/models/shirt.rb +12 -0
  185. data/spec/support/models/spacer.rb +8 -0
  186. data/spec/support/models/threadlocker.rb +8 -0
  187. data/spec/support/models/washer.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +609 -545
  190. metadata.gz.sig +0 -0
  191. data/lib/mongoid/errors/empty_config_file.rb +0 -26
  192. data/lib/mongoid/errors/invalid_config_file.rb +0 -26
  193. data/spec/integration/contextual/empty_spec.rb +0 -142
  194. data/spec/mongoid/errors/invalid_config_file_spec.rb +0 -32
  195. data/spec/shared/bin/s3-copy +0 -45
  196. data/spec/shared/bin/s3-upload +0 -69
  197. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  198. data/spec/shared/share/haproxy-1.conf +0 -16
  199. data/spec/shared/share/haproxy-2.conf +0 -17
  200. data/spec/support/cluster_config.rb +0 -158
@@ -0,0 +1,411 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Criteria do
7
+
8
+ describe "#only" do
9
+
10
+ let!(:band) do
11
+ Band.create(name: "Depeche Mode", likes: 3, views: 10)
12
+ end
13
+
14
+ context "when not using inheritance" do
15
+
16
+ context "when passing splat args" do
17
+
18
+ let(:criteria) do
19
+ Band.only(:_id)
20
+ end
21
+
22
+ it "limits the returned fields" do
23
+ expect {
24
+ criteria.first.name
25
+ }.to raise_error(ActiveModel::MissingAttributeError)
26
+ end
27
+
28
+ it "does not add _type to the fields" do
29
+ expect(criteria.options[:fields]["_type"]).to be_nil
30
+ end
31
+ end
32
+
33
+ context "when not including id" do
34
+
35
+ let(:criteria) do
36
+ Band.only(:name)
37
+ end
38
+
39
+ it "responds to id anyway" do
40
+ expect {
41
+ criteria.first.id
42
+ }.to_not raise_error
43
+ end
44
+ end
45
+
46
+ context "when passing an array" do
47
+
48
+ let(:criteria) do
49
+ Band.only([ :name, :likes ])
50
+ end
51
+
52
+ it "includes the limited fields" do
53
+ expect(criteria.first.name).to_not be_nil
54
+ end
55
+
56
+ it "excludes the non included fields" do
57
+ expect {
58
+ criteria.first.active
59
+ }.to raise_error(ActiveModel::MissingAttributeError)
60
+ end
61
+
62
+ it "does not add _type to the fields" do
63
+ expect(criteria.options[:fields]["_type"]).to be_nil
64
+ end
65
+ end
66
+
67
+ context "when instantiating a class of another type inside the iteration" do
68
+
69
+ let(:criteria) do
70
+ Band.only(:name)
71
+ end
72
+
73
+ it "only limits the fields on the correct model" do
74
+ criteria.each do |band|
75
+ expect(Person.new.age).to eq(100)
76
+ end
77
+ end
78
+ end
79
+
80
+ context "when instantiating a document not in the result set" do
81
+
82
+ let(:criteria) do
83
+ Band.only(:name)
84
+ end
85
+
86
+ it "only limits the fields on the correct criteria" do
87
+ criteria.each do |band|
88
+ expect(Band.new.active).to be true
89
+ end
90
+ end
91
+ end
92
+
93
+ context "when nesting a criteria within a criteria" do
94
+
95
+ let(:criteria) do
96
+ Band.only(:name)
97
+ end
98
+
99
+ it "only limits the fields on the correct criteria" do
100
+ criteria.each do |band|
101
+ Band.all.each do |b|
102
+ expect(b.active).to be true
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ context "when using inheritance" do
110
+ context "when using the default discriminator key" do
111
+ let(:criteria) do
112
+ Doctor.only(:_id)
113
+ end
114
+
115
+ it "adds _type to the fields" do
116
+ expect(criteria.options[:fields]).to include("_type")
117
+ end
118
+ end
119
+
120
+ context "when setting a custom discriminator key" do
121
+ before do
122
+ Person.discriminator_key = "dkey"
123
+ end
124
+
125
+ after do
126
+ Person.discriminator_key = nil
127
+ end
128
+
129
+ let(:criteria) do
130
+ Doctor.only(:_id)
131
+ end
132
+
133
+ it "adds custom discriminator key to the fields" do
134
+ expect(criteria.options[:fields]).to include("dkey")
135
+ end
136
+
137
+ it "does not add _type to the fields" do
138
+ expect(criteria.options[:fields]).to_not include("_type")
139
+ end
140
+ end
141
+ end
142
+
143
+ context "when limiting to embedded documents" do
144
+
145
+ context "when the embedded documents are aliased" do
146
+
147
+ let(:criteria) do
148
+ Person.only(:phones)
149
+ end
150
+
151
+ it "properly uses the database field name" do
152
+ expect(criteria.options).to eq(fields: { "_id" => 1, "mobile_phones" => 1 })
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'when the field is localized' do
158
+
159
+ before do
160
+ I18n.locale = :en
161
+ d = Dictionary.create(description: 'english-text')
162
+ I18n.locale = :de
163
+ d.description = 'deutsch-text'
164
+ d.save
165
+ end
166
+
167
+ after do
168
+ I18n.locale = :en
169
+ end
170
+
171
+ context 'when entire field is included' do
172
+
173
+ let(:dictionary) do
174
+ Dictionary.only(:description).first
175
+
176
+ end
177
+
178
+ it 'loads all translations' do
179
+ expect(dictionary.description_translations.keys).to include('de', 'en')
180
+ end
181
+
182
+ it 'returns the field value for the current locale' do
183
+ I18n.locale = :en
184
+ expect(dictionary.description).to eq('english-text')
185
+ I18n.locale = :de
186
+ expect(dictionary.description).to eq('deutsch-text')
187
+ end
188
+ end
189
+
190
+ context 'when a specific locale is included' do
191
+
192
+ let(:dictionary) do
193
+ Dictionary.only(:'description.de').first
194
+ end
195
+
196
+ it 'loads translations only for the included locale' do
197
+ expect(dictionary.description_translations.keys).to include('de')
198
+ expect(dictionary.description_translations.keys).to_not include('en')
199
+ end
200
+
201
+ it 'returns the field value for the included locale' do
202
+ I18n.locale = :en
203
+ expect(dictionary.description).to be_nil
204
+ I18n.locale = :de
205
+ expect(dictionary.description).to eq('deutsch-text')
206
+ end
207
+ end
208
+
209
+ context 'when entire field is excluded' do
210
+
211
+ let(:dictionary) do
212
+ Dictionary.without(:description).first
213
+ end
214
+
215
+ it 'does not load all translations' do
216
+ expect(dictionary.description_translations.keys).to_not include('de', 'en')
217
+ end
218
+
219
+ it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
220
+ expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
221
+ end
222
+ end
223
+
224
+ context 'when a specific locale is excluded' do
225
+
226
+ let(:dictionary) do
227
+ Dictionary.without(:'description.de').first
228
+ end
229
+
230
+ it 'does not load excluded translations' do
231
+ expect(dictionary.description_translations.keys).to_not include('de')
232
+ expect(dictionary.description_translations.keys).to include('en')
233
+ end
234
+
235
+ it 'returns nil for excluded translations' do
236
+ I18n.locale = :en
237
+ expect(dictionary.description).to eq('english-text')
238
+ I18n.locale = :de
239
+ expect(dictionary.description).to be_nil
240
+ end
241
+ end
242
+ end
243
+
244
+ context 'when restricting to id' do
245
+
246
+ context 'when id is aliased to _id' do
247
+ shared_examples 'requests _id field' do
248
+ it 'requests _id field' do
249
+ criteria.options[:fields].should == {'_id' => 1}
250
+ end
251
+ end
252
+
253
+ ['id', '_id', :id, :_id].each do |field|
254
+ context "using #{field.inspect}" do
255
+ let(:criteria) do
256
+ Band.where.only(field)
257
+ end
258
+
259
+ include_examples 'requests _id field'
260
+ end
261
+ end
262
+
263
+ context 'using a content field' do
264
+ let(:criteria) do
265
+ Band.where.only(:name)
266
+ end
267
+
268
+ it 'requests content field and _id field' do
269
+ criteria.options[:fields].should == {'_id' => 1, 'name' => 1}
270
+ end
271
+ end
272
+ end
273
+
274
+ context 'when id is not aliased to _id' do
275
+ shared_examples 'requests _id field' do
276
+ it 'requests _id field' do
277
+ criteria.options[:fields].should == {'_id' => 1}
278
+ end
279
+ end
280
+
281
+ shared_examples 'requests id field and _id field' do
282
+ it 'requests id field and _id field' do
283
+ criteria.options[:fields].should == {'_id' => 1, 'id' => 1}
284
+ end
285
+ end
286
+
287
+ ['_id', :_id].each do |field|
288
+ context "using #{field.inspect}" do
289
+ let(:criteria) do
290
+ Shirt.where.only(field)
291
+ end
292
+
293
+ include_examples 'requests _id field'
294
+ end
295
+ end
296
+
297
+ ['id', :id].each do |field|
298
+ context "using #{field.inspect}" do
299
+ let(:criteria) do
300
+ Shirt.where.only(field)
301
+ end
302
+
303
+ include_examples 'requests id field and _id field'
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+
310
+ describe "#without" do
311
+
312
+ let!(:person) do
313
+ Person.create!(username: "davinci", age: 50, pets: false)
314
+ end
315
+
316
+ context "when omitting to embedded documents" do
317
+
318
+ context "when the embedded documents are aliased" do
319
+
320
+ let(:criteria) do
321
+ Person.without(:phones)
322
+ end
323
+
324
+ it "properly uses the database field name" do
325
+ expect(criteria.options).to eq(fields: { "mobile_phones" => 0 })
326
+ end
327
+ end
328
+ end
329
+
330
+ context "when excluding id fields" do
331
+
332
+ shared_examples 'does not raise error' do
333
+ it "does not raise error" do
334
+ expect {
335
+ criteria.first._id
336
+ }.to_not raise_error
337
+ end
338
+ end
339
+
340
+ shared_examples 'does not unproject _id' do
341
+ it 'does not unproject _id' do
342
+ criteria.options[:fields].should be nil
343
+ end
344
+
345
+ it "returns id anyway" do
346
+ expect(criteria.first.id).to_not be_nil
347
+ end
348
+ end
349
+
350
+ shared_examples 'unprojects id' do
351
+ it 'does not unproject _id' do
352
+ criteria.options[:fields].should == {'id' => 0}
353
+ end
354
+
355
+ let(:instance) { criteria.first }
356
+
357
+ it "returns _id" do
358
+ instance._id.should == 'foo'
359
+ end
360
+
361
+ it 'does not return id' do
362
+ lambda do
363
+ instance.id
364
+ end.should raise_error(ActiveModel::MissingAttributeError)
365
+ end
366
+ end
367
+
368
+ context 'model with id aliased to _id' do
369
+ context 'id field' do
370
+ let(:criteria) do
371
+ Person.without(:id, "id")
372
+ end
373
+
374
+ include_examples 'does not raise error'
375
+ include_examples 'does not unproject _id'
376
+ end
377
+
378
+ context '_id field' do
379
+ let(:criteria) do
380
+ Person.without(:_id, "_id")
381
+ end
382
+
383
+ include_examples 'does not raise error'
384
+ include_examples 'does not unproject _id'
385
+ end
386
+ end
387
+
388
+ context 'model without id aliased to _id' do
389
+ let!(:shirt) { Shirt.create!(id: 1, _id: 'foo') }
390
+
391
+ context 'id field' do
392
+ let(:criteria) do
393
+ Shirt.without(:id, "id")
394
+ end
395
+
396
+ include_examples 'does not raise error'
397
+ include_examples 'unprojects id'
398
+ end
399
+
400
+ context '_id field' do
401
+ let(:criteria) do
402
+ Shirt.without(:_id, "_id")
403
+ end
404
+
405
+ include_examples 'does not raise error'
406
+ include_examples 'does not unproject _id'
407
+ end
408
+ end
409
+ end
410
+ end
411
+ end
@@ -2762,243 +2762,6 @@ describe Mongoid::Criteria do
2762
2762
  end
2763
2763
  end
2764
2764
 
2765
- describe "#only" do
2766
-
2767
- let!(:band) do
2768
- Band.create(name: "Depeche Mode", likes: 3, views: 10)
2769
- end
2770
-
2771
- context "when not using inheritance" do
2772
-
2773
- context "when passing splat args" do
2774
-
2775
- let(:criteria) do
2776
- Band.only(:_id)
2777
- end
2778
-
2779
- it "limits the returned fields" do
2780
- expect {
2781
- criteria.first.name
2782
- }.to raise_error(ActiveModel::MissingAttributeError)
2783
- end
2784
-
2785
- it "does not add _type to the fields" do
2786
- expect(criteria.options[:fields]["_type"]).to be_nil
2787
- end
2788
- end
2789
-
2790
- context "when not including id" do
2791
-
2792
- let(:criteria) do
2793
- Band.only(:name)
2794
- end
2795
-
2796
- it "responds to id anyway" do
2797
- expect {
2798
- criteria.first.id
2799
- }.to_not raise_error
2800
- end
2801
- end
2802
-
2803
- context "when passing an array" do
2804
-
2805
- let(:criteria) do
2806
- Band.only([ :name, :likes ])
2807
- end
2808
-
2809
- it "includes the limited fields" do
2810
- expect(criteria.first.name).to_not be_nil
2811
- end
2812
-
2813
- it "excludes the non included fields" do
2814
- expect {
2815
- criteria.first.active
2816
- }.to raise_error(ActiveModel::MissingAttributeError)
2817
- end
2818
-
2819
- it "does not add _type to the fields" do
2820
- expect(criteria.options[:fields]["_type"]).to be_nil
2821
- end
2822
- end
2823
-
2824
- context "when instantiating a class of another type inside the iteration" do
2825
-
2826
- let(:criteria) do
2827
- Band.only(:name)
2828
- end
2829
-
2830
- it "only limits the fields on the correct model" do
2831
- criteria.each do |band|
2832
- expect(Person.new.age).to eq(100)
2833
- end
2834
- end
2835
- end
2836
-
2837
- context "when instantiating a document not in the result set" do
2838
-
2839
- let(:criteria) do
2840
- Band.only(:name)
2841
- end
2842
-
2843
- it "only limits the fields on the correct criteria" do
2844
- criteria.each do |band|
2845
- expect(Band.new.active).to be true
2846
- end
2847
- end
2848
- end
2849
-
2850
- context "when nesting a criteria within a criteria" do
2851
-
2852
- let(:criteria) do
2853
- Band.only(:name)
2854
- end
2855
-
2856
- it "only limits the fields on the correct criteria" do
2857
- criteria.each do |band|
2858
- Band.all.each do |b|
2859
- expect(b.active).to be true
2860
- end
2861
- end
2862
- end
2863
- end
2864
- end
2865
-
2866
- context "when using inheritance" do
2867
- context "when using the default discriminator key" do
2868
- let(:criteria) do
2869
- Doctor.only(:_id)
2870
- end
2871
-
2872
- it "adds _type to the fields" do
2873
- expect(criteria.options[:fields]).to include("_type")
2874
- end
2875
- end
2876
-
2877
- context "when setting a custom discriminator key" do
2878
- before do
2879
- Person.discriminator_key = "dkey"
2880
- end
2881
-
2882
- after do
2883
- Person.discriminator_key = nil
2884
- end
2885
-
2886
- let(:criteria) do
2887
- Doctor.only(:_id)
2888
- end
2889
-
2890
- it "adds custom discriminator key to the fields" do
2891
- expect(criteria.options[:fields]).to include("dkey")
2892
- end
2893
-
2894
- it "does not add _type to the fields" do
2895
- expect(criteria.options[:fields]).to_not include("_type")
2896
- end
2897
- end
2898
- end
2899
-
2900
- context "when limiting to embedded documents" do
2901
-
2902
- context "when the embedded documents are aliased" do
2903
-
2904
- let(:criteria) do
2905
- Person.only(:phones)
2906
- end
2907
-
2908
- it "properly uses the database field name" do
2909
- expect(criteria.options).to eq(fields: { "_id" => 1, "mobile_phones" => 1 })
2910
- end
2911
- end
2912
- end
2913
-
2914
- context 'when the field is localized' do
2915
-
2916
- before do
2917
- I18n.locale = :en
2918
- d = Dictionary.create(description: 'english-text')
2919
- I18n.locale = :de
2920
- d.description = 'deutsch-text'
2921
- d.save
2922
- end
2923
-
2924
- after do
2925
- I18n.locale = :en
2926
- end
2927
-
2928
- context 'when entire field is included' do
2929
-
2930
- let(:dictionary) do
2931
- Dictionary.only(:description).first
2932
-
2933
- end
2934
-
2935
- it 'loads all translations' do
2936
- expect(dictionary.description_translations.keys).to include('de', 'en')
2937
- end
2938
-
2939
- it 'returns the field value for the current locale' do
2940
- I18n.locale = :en
2941
- expect(dictionary.description).to eq('english-text')
2942
- I18n.locale = :de
2943
- expect(dictionary.description).to eq('deutsch-text')
2944
- end
2945
- end
2946
-
2947
- context 'when a specific locale is included' do
2948
-
2949
- let(:dictionary) do
2950
- Dictionary.only(:'description.de').first
2951
- end
2952
-
2953
- it 'loads translations only for the included locale' do
2954
- expect(dictionary.description_translations.keys).to include('de')
2955
- expect(dictionary.description_translations.keys).to_not include('en')
2956
- end
2957
-
2958
- it 'returns the field value for the included locale' do
2959
- I18n.locale = :en
2960
- expect(dictionary.description).to be_nil
2961
- I18n.locale = :de
2962
- expect(dictionary.description).to eq('deutsch-text')
2963
- end
2964
- end
2965
-
2966
- context 'when entire field is excluded' do
2967
-
2968
- let(:dictionary) do
2969
- Dictionary.without(:description).first
2970
- end
2971
-
2972
- it 'does not load all translations' do
2973
- expect(dictionary.description_translations.keys).to_not include('de', 'en')
2974
- end
2975
-
2976
- it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
2977
- expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
2978
- end
2979
- end
2980
-
2981
- context 'when a specific locale is excluded' do
2982
-
2983
- let(:dictionary) do
2984
- Dictionary.without(:'description.de').first
2985
- end
2986
-
2987
- it 'does not load excluded translations' do
2988
- expect(dictionary.description_translations.keys).to_not include('de')
2989
- expect(dictionary.description_translations.keys).to include('en')
2990
- end
2991
-
2992
- it 'returns nil for excluded translations' do
2993
- I18n.locale = :en
2994
- expect(dictionary.description).to eq('english-text')
2995
- I18n.locale = :de
2996
- expect(dictionary.description).to be_nil
2997
- end
2998
- end
2999
- end
3000
- end
3001
-
3002
2765
  [ :or, :any_of ].each do |method|
3003
2766
 
3004
2767
  describe "\##{method}" do
@@ -3769,14 +3532,10 @@ describe Mongoid::Criteria do
3769
3532
 
3770
3533
  before do
3771
3534
  expect(Person).to receive(:minor).and_call_original
3772
- expect(Person).to receive(:older_than).and_call_original
3773
3535
  end
3774
3536
 
3775
3537
  it "calls the method on the class" do
3776
3538
  expect(criteria.minor).to be_empty
3777
- expect do
3778
- criteria.older_than(age: 25)
3779
- end.not_to raise_error
3780
3539
  end
3781
3540
  end
3782
3541
 
@@ -3921,44 +3680,6 @@ describe Mongoid::Criteria do
3921
3680
  end
3922
3681
  end
3923
3682
 
3924
- describe "#without" do
3925
-
3926
- let!(:person) do
3927
- Person.create!(username: "davinci", age: 50, pets: false)
3928
- end
3929
-
3930
- context "when omitting to embedded documents" do
3931
-
3932
- context "when the embedded documents are aliased" do
3933
-
3934
- let(:criteria) do
3935
- Person.without(:phones)
3936
- end
3937
-
3938
- it "properly uses the database field name" do
3939
- expect(criteria.options).to eq(fields: { "mobile_phones" => 0 })
3940
- end
3941
- end
3942
- end
3943
-
3944
- context "when excluding id" do
3945
-
3946
- let(:criteria) do
3947
- Person.without(:_id, :id, "_id", "id")
3948
- end
3949
-
3950
- it "does not raise error" do
3951
- expect {
3952
- criteria.first.id
3953
- }.to_not raise_error
3954
- end
3955
-
3956
- it "returns id anyway" do
3957
- expect(criteria.first.id).to_not be_nil
3958
- end
3959
- end
3960
- end
3961
-
3962
3683
  describe "#type_selection" do
3963
3684
  context "when using the default discriminator_key" do
3964
3685
  context "when only one subclass exists" do