mongoid 7.5.4 → 8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (298) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +0 -25
  5. data/lib/config/locales/en.yml +46 -30
  6. data/lib/mongoid/association/accessors.rb +32 -3
  7. data/lib/mongoid/association/bindable.rb +48 -0
  8. data/lib/mongoid/association/builders.rb +4 -2
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +28 -5
  11. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  12. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  13. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  14. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  15. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  16. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  17. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  18. data/lib/mongoid/association/macros.rb +2 -1
  19. data/lib/mongoid/association/many.rb +5 -0
  20. data/lib/mongoid/association/nested/many.rb +2 -1
  21. data/lib/mongoid/association/proxy.rb +12 -0
  22. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  23. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  24. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  25. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  26. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  28. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  29. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  30. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  31. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  32. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  33. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  34. data/lib/mongoid/association/relatable.rb +38 -4
  35. data/lib/mongoid/attributes/processing.rb +9 -2
  36. data/lib/mongoid/attributes.rb +30 -27
  37. data/lib/mongoid/cacheable.rb +2 -2
  38. data/lib/mongoid/changeable.rb +37 -2
  39. data/lib/mongoid/clients/options.rb +4 -0
  40. data/lib/mongoid/clients/sessions.rb +2 -14
  41. data/lib/mongoid/config.rb +15 -11
  42. data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
  43. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  44. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  45. data/lib/mongoid/contextual/memory.rb +55 -28
  46. data/lib/mongoid/contextual/mongo.rb +173 -262
  47. data/lib/mongoid/contextual/none.rb +33 -15
  48. data/lib/mongoid/copyable.rb +32 -8
  49. data/lib/mongoid/criteria/includable.rb +24 -20
  50. data/lib/mongoid/criteria/marshalable.rb +10 -2
  51. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  52. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  53. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  54. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  55. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  56. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  57. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  58. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  59. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  60. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  62. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  63. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  64. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  65. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  66. data/lib/mongoid/criteria/queryable/selectable.rb +2 -24
  67. data/lib/mongoid/criteria/queryable/selector.rb +90 -5
  68. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  69. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  70. data/lib/mongoid/criteria/queryable.rb +11 -6
  71. data/lib/mongoid/criteria.rb +1 -28
  72. data/lib/mongoid/deprecable.rb +36 -0
  73. data/lib/mongoid/deprecation.rb +25 -0
  74. data/lib/mongoid/document.rb +88 -33
  75. data/lib/mongoid/equality.rb +4 -4
  76. data/lib/mongoid/errors/document_not_found.rb +6 -2
  77. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  78. data/lib/mongoid/errors/invalid_field.rb +5 -1
  79. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  80. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  81. data/lib/mongoid/errors.rb +2 -2
  82. data/lib/mongoid/extensions/array.rb +8 -6
  83. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  84. data/lib/mongoid/extensions/binary.rb +42 -0
  85. data/lib/mongoid/extensions/boolean.rb +8 -2
  86. data/lib/mongoid/extensions/date.rb +26 -20
  87. data/lib/mongoid/extensions/date_time.rb +1 -1
  88. data/lib/mongoid/extensions/float.rb +4 -5
  89. data/lib/mongoid/extensions/hash.rb +12 -5
  90. data/lib/mongoid/extensions/integer.rb +4 -5
  91. data/lib/mongoid/extensions/object.rb +2 -0
  92. data/lib/mongoid/extensions/range.rb +41 -10
  93. data/lib/mongoid/extensions/regexp.rb +11 -4
  94. data/lib/mongoid/extensions/set.rb +11 -4
  95. data/lib/mongoid/extensions/string.rb +2 -13
  96. data/lib/mongoid/extensions/symbol.rb +3 -14
  97. data/lib/mongoid/extensions/time.rb +27 -16
  98. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  99. data/lib/mongoid/extensions.rb +1 -0
  100. data/lib/mongoid/factory.rb +42 -7
  101. data/lib/mongoid/fields/foreign_key.rb +7 -0
  102. data/lib/mongoid/fields/validators/macro.rb +3 -9
  103. data/lib/mongoid/fields.rb +49 -7
  104. data/lib/mongoid/findable.rb +21 -16
  105. data/lib/mongoid/indexable/specification.rb +1 -1
  106. data/lib/mongoid/indexable/validators/options.rb +4 -1
  107. data/lib/mongoid/interceptable.rb +69 -9
  108. data/lib/mongoid/persistable/creatable.rb +14 -5
  109. data/lib/mongoid/persistable/updatable.rb +12 -5
  110. data/lib/mongoid/persistence_context.rb +8 -42
  111. data/lib/mongoid/query_cache.rb +6 -258
  112. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  113. data/lib/mongoid/reloadable.rb +7 -3
  114. data/lib/mongoid/scopable.rb +9 -11
  115. data/lib/mongoid/selectable.rb +1 -2
  116. data/lib/mongoid/shardable.rb +11 -35
  117. data/lib/mongoid/stateful.rb +27 -1
  118. data/lib/mongoid/timestamps/created.rb +1 -1
  119. data/lib/mongoid/timestamps/updated.rb +1 -1
  120. data/lib/mongoid/touchable.rb +2 -3
  121. data/lib/mongoid/traversable.rb +1 -0
  122. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  123. data/lib/mongoid/version.rb +1 -1
  124. data/lib/mongoid/warnings.rb +3 -4
  125. data/lib/mongoid.rb +1 -0
  126. data/spec/config/mongoid.yml +16 -0
  127. data/spec/integration/app_spec.rb +8 -12
  128. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  129. data/spec/integration/associations/embedded_spec.rb +15 -0
  130. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  131. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  132. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  133. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  134. data/spec/integration/associations/has_one_spec.rb +97 -1
  135. data/spec/integration/associations/scope_option_spec.rb +1 -1
  136. data/spec/integration/callbacks_models.rb +95 -1
  137. data/spec/integration/callbacks_spec.rb +226 -4
  138. data/spec/integration/criteria/range_spec.rb +95 -1
  139. data/spec/integration/discriminator_key_spec.rb +115 -76
  140. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  141. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  142. data/spec/integration/matcher_examples_spec.rb +20 -13
  143. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  144. data/spec/integration/matcher_operator_spec.rb +3 -5
  145. data/spec/integration/persistence/range_field_spec.rb +350 -0
  146. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  147. data/spec/mongoid/association/depending_spec.rb +9 -9
  148. data/spec/mongoid/association/eager_spec.rb +2 -1
  149. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  150. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  151. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  152. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  153. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +198 -8
  154. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  155. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  156. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  157. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  158. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  159. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  160. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  161. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  162. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  163. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  164. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  165. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +38 -5
  166. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  167. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  168. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  169. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  170. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +62 -13
  171. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  172. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  173. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  174. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  175. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  176. data/spec/mongoid/association/syncable_spec.rb +14 -0
  177. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  178. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  179. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  180. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  181. data/spec/mongoid/attributes_spec.rb +480 -27
  182. data/spec/mongoid/cacheable_spec.rb +3 -3
  183. data/spec/mongoid/changeable_spec.rb +130 -13
  184. data/spec/mongoid/clients/factory_spec.rb +23 -30
  185. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  186. data/spec/mongoid/clients_spec.rb +2 -2
  187. data/spec/mongoid/config_spec.rb +52 -14
  188. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  189. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  190. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  191. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  192. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  193. data/spec/mongoid/contextual/mongo_spec.rb +566 -416
  194. data/spec/mongoid/contextual/none_spec.rb +11 -19
  195. data/spec/mongoid/copyable_spec.rb +451 -1
  196. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  197. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  198. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  199. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  200. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  201. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  202. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  203. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  204. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  205. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  206. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  207. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  208. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  209. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  210. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  211. data/spec/mongoid/criteria/queryable/selector_spec.rb +16 -77
  212. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  213. data/spec/mongoid/criteria_spec.rb +469 -1201
  214. data/spec/mongoid/document_fields_spec.rb +173 -24
  215. data/spec/mongoid/document_spec.rb +32 -41
  216. data/spec/mongoid/equality_spec.rb +12 -12
  217. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  218. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  219. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  220. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  221. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  222. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  223. data/spec/mongoid/extensions/array_spec.rb +16 -2
  224. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  225. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  226. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  227. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  228. data/spec/mongoid/extensions/date_spec.rb +71 -1
  229. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  230. data/spec/mongoid/extensions/float_spec.rb +48 -76
  231. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  232. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  233. data/spec/mongoid/extensions/range_spec.rb +255 -54
  234. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  235. data/spec/mongoid/extensions/set_spec.rb +106 -0
  236. data/spec/mongoid/extensions/string_spec.rb +53 -25
  237. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  238. data/spec/mongoid/extensions/time_spec.rb +634 -66
  239. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  240. data/spec/mongoid/factory_spec.rb +61 -1
  241. data/spec/mongoid/fields_spec.rb +321 -50
  242. data/spec/mongoid/findable_spec.rb +64 -29
  243. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  244. data/spec/mongoid/indexable_spec.rb +16 -19
  245. data/spec/mongoid/interceptable_spec.rb +584 -5
  246. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  247. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  248. data/spec/mongoid/mongoizable_spec.rb +285 -0
  249. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  250. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  251. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  252. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  253. data/spec/mongoid/persistence_context_spec.rb +24 -0
  254. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  255. data/spec/mongoid/query_cache_spec.rb +0 -154
  256. data/spec/mongoid/reloadable_spec.rb +35 -2
  257. data/spec/mongoid/scopable_spec.rb +36 -34
  258. data/spec/mongoid/shardable_models.rb +0 -14
  259. data/spec/mongoid/shardable_spec.rb +61 -153
  260. data/spec/mongoid/stateful_spec.rb +28 -0
  261. data/spec/mongoid/timestamps_spec.rb +390 -0
  262. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  263. data/spec/mongoid/touchable_spec.rb +116 -0
  264. data/spec/mongoid/touchable_spec_models.rb +12 -8
  265. data/spec/mongoid/traversable_spec.rb +4 -11
  266. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  267. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  268. data/spec/mongoid/warnings_spec.rb +35 -0
  269. data/spec/mongoid_spec.rb +1 -7
  270. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  271. data/spec/rails/mongoid_spec.rb +4 -16
  272. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  273. data/spec/shared/lib/mrss/lite_constraints.rb +0 -8
  274. data/spec/shared/shlib/server.sh +5 -5
  275. data/spec/support/constraints.rb +24 -0
  276. data/spec/support/macros.rb +30 -0
  277. data/spec/support/models/augmentation.rb +12 -0
  278. data/spec/support/models/band.rb +3 -0
  279. data/spec/support/models/catalog.rb +24 -0
  280. data/spec/support/models/circus.rb +3 -0
  281. data/spec/support/models/fanatic.rb +8 -0
  282. data/spec/support/models/implant.rb +9 -0
  283. data/spec/support/models/label.rb +2 -0
  284. data/spec/support/models/passport.rb +9 -0
  285. data/spec/support/models/person.rb +1 -0
  286. data/spec/support/models/player.rb +2 -0
  287. data/spec/support/models/powerup.rb +12 -0
  288. data/spec/support/models/registry.rb +1 -0
  289. data/spec/support/models/school.rb +14 -0
  290. data/spec/support/models/shield.rb +18 -0
  291. data/spec/support/models/student.rb +14 -0
  292. data/spec/support/models/weapon.rb +12 -0
  293. data.tar.gz.sig +0 -0
  294. metadata +689 -657
  295. metadata.gz.sig +0 -0
  296. data/lib/mongoid/errors/eager_load.rb +0 -23
  297. data/lib/mongoid/errors/invalid_value.rb +0 -17
  298. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -383,10 +383,11 @@ describe Mongoid::Criteria do
383
383
  Person.create!
384
384
  end
385
385
 
386
- context "when no eager loading is involved" do
386
+ context "when the query cache is enabled" do
387
+ query_cache_enabled
387
388
 
388
389
  let(:criteria) do
389
- Person.all.cache
390
+ Person.all
390
391
  end
391
392
 
392
393
  before do
@@ -394,17 +395,19 @@ describe Mongoid::Criteria do
394
395
  end
395
396
 
396
397
  it "does not hit the database after first iteration" do
397
- expect(criteria.context.view).to receive(:each).never
398
- criteria.each do |doc|
399
- expect(doc).to eq(person)
398
+ expect_no_queries do
399
+ criteria.each do |doc|
400
+ expect(doc).to eq(person)
401
+ end
400
402
  end
401
403
  end
402
404
  end
403
405
 
404
406
  context "when the criteria is eager loading" do
407
+ query_cache_enabled
405
408
 
406
409
  let(:criteria) do
407
- Person.includes(:posts).cache
410
+ Person.includes(:posts)
408
411
  end
409
412
 
410
413
  before do
@@ -412,9 +415,10 @@ describe Mongoid::Criteria do
412
415
  end
413
416
 
414
417
  it "does not hit the database after first iteration" do
415
- expect(criteria.context.view).to receive(:each).never
416
- criteria.each do |doc|
417
- expect(doc).to eq(person)
418
+ expect_no_queries do
419
+ criteria.each do |doc|
420
+ expect(doc).to eq(person)
421
+ end
418
422
  end
419
423
  end
420
424
  end
@@ -491,17 +495,6 @@ describe Mongoid::Criteria do
491
495
  end
492
496
  end
493
497
 
494
- describe "#cache" do
495
-
496
- let(:criteria) do
497
- Band.where(name: "Depeche Mode")
498
- end
499
-
500
- it "sets the cache option to true" do
501
- expect(criteria.cache).to be_cached
502
- end
503
- end
504
-
505
498
  describe "#context" do
506
499
 
507
500
  context "when the model is embedded" do
@@ -837,8 +830,8 @@ describe Mongoid::Criteria do
837
830
  end
838
831
  end
839
832
 
840
- context "when given a Proc" do
841
- it "behaves as Enumerable" do
833
+ context "when given a Proc without a block" do
834
+ it "raises an error" do
842
835
  lambda do
843
836
  criteria.find(-> {"default"})
844
837
  # Proc is not serializable to a BSON type
@@ -1000,7 +993,7 @@ describe Mongoid::Criteria do
1000
993
  it "deletes the document from the database" do
1001
994
  expect {
1002
995
  depeche.reload
1003
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
996
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1004
997
  end
1005
998
  end
1006
999
  end
@@ -1167,1178 +1160,70 @@ describe Mongoid::Criteria do
1167
1160
  Person.send(method, preference_ids: [ id ])
1168
1161
  end
1169
1162
 
1170
- it "returns the matching documents" do
1171
- expect(criteria).to eq([ match_one ])
1172
- end
1173
- end
1174
-
1175
- context "when providing empty strings" do
1176
-
1177
- let(:criteria) do
1178
- Person.send(method, preference_ids: [ id, "" ])
1179
- end
1180
-
1181
- it "returns the matching documents" do
1182
- expect(criteria).to eq([ match_one ])
1183
- end
1184
- end
1185
-
1186
- context "when providing nils" do
1187
-
1188
- context "when the relation is a many to many" do
1189
-
1190
- let(:criteria) do
1191
- Person.send(method, preference_ids: [ id, nil ])
1192
- end
1193
-
1194
- it "returns the matching documents" do
1195
- expect(criteria).to eq([ match_one ])
1196
- end
1197
- end
1198
-
1199
- context "when the relation is a one to one" do
1200
-
1201
- let!(:game) do
1202
- Game.create!
1203
- end
1204
-
1205
- let(:criteria) do
1206
- Game.send(method, person_id: [ nil ])
1207
- end
1208
-
1209
- it "returns the matching documents" do
1210
- expect(criteria).to eq([ game ])
1211
- end
1212
- end
1213
- end
1214
- end
1215
- end
1216
- end
1217
-
1218
- describe "#initialize" do
1219
-
1220
- let(:criteria) do
1221
- described_class.new(Band)
1222
- end
1223
-
1224
- it "sets the class" do
1225
- expect(criteria.klass).to eq(Band)
1226
- end
1227
-
1228
- it "sets the aliased fields" do
1229
- expect(criteria.aliased_fields).to eq(Band.aliased_fields)
1230
- end
1231
-
1232
- it "sets the serializers" do
1233
- expect(criteria.serializers).to eq(Band.fields)
1234
- end
1235
- end
1236
-
1237
- describe "#includes" do
1238
-
1239
- let!(:person) do
1240
- Person.create!(age: 1)
1241
- end
1242
-
1243
- context "when providing a name that is not a relation" do
1244
-
1245
- it "raises an error" do
1246
- expect {
1247
- Person.includes(:members)
1248
- }.to raise_error(Mongoid::Errors::InvalidIncludes)
1249
- end
1250
- end
1251
-
1252
- context "when providing one association" do
1253
-
1254
- let!(:user) do
1255
- User.create!(posts: [ post1 ])
1256
- end
1257
-
1258
- let!(:post1) do
1259
- Post.create!
1260
- end
1261
-
1262
- let(:result) do
1263
- User.includes(:posts).first
1264
- end
1265
-
1266
- it "executes the query" do
1267
- expect(result).to eq(user)
1268
- end
1269
-
1270
- it "includes the related objects" do
1271
- expect(result.posts).to eq([ post1 ])
1272
- end
1273
- end
1274
-
1275
- context "when providing a list of associations" do
1276
-
1277
- let!(:user) do
1278
- User.create!(posts: [ post1 ], descriptions: [ description1 ])
1279
- end
1280
-
1281
- let!(:post1) do
1282
- Post.create!
1283
- end
1284
-
1285
- let!(:description1) do
1286
- Description.create!(details: 1)
1287
- end
1288
-
1289
- let(:result) do
1290
- User.includes(:posts, :descriptions).first
1291
- end
1292
-
1293
- it "executes the query" do
1294
- expect(result).to eq(user)
1295
- end
1296
-
1297
- it "includes the related objects" do
1298
- expect(result.posts).to eq([ post1 ])
1299
- expect(result.descriptions).to eq([ description1 ])
1300
- end
1301
- end
1302
-
1303
- context "when providing a nested association" do
1304
-
1305
- let!(:user) do
1306
- User.create!
1307
- end
1308
-
1309
- before do
1310
- p = Post.create!(alerts: [ Alert.create! ])
1311
- user.posts = [ p ]
1312
- user.save!
1313
- end
1314
-
1315
- let(:result) do
1316
- User.includes(:posts => [:alerts]).first
1317
- end
1318
-
1319
- it "executes the query" do
1320
- expect(result).to eq(user)
1321
- end
1322
-
1323
- it "includes the related objects" do
1324
- expect(result.posts.size).to eq(1)
1325
- expect(result.posts.first.alerts.size).to eq(1)
1326
- end
1327
- end
1328
-
1329
- context "when providing a deeply nested association" do
1330
-
1331
- let!(:user) do
1332
- User.create!
1333
- end
1334
-
1335
- let(:results) do
1336
- User.includes(:posts => [{ :alerts => :items }]).to_a
1337
- end
1338
-
1339
- it "executes the query" do
1340
- expect(results.first).to eq(user)
1341
- end
1342
- end
1343
-
1344
- context "when the models are inherited" do
1345
-
1346
- before(:all) do
1347
- class A
1348
- include Mongoid::Document
1349
- end
1350
-
1351
- class B < A
1352
- belongs_to :c
1353
- end
1354
-
1355
- class C
1356
- include Mongoid::Document
1357
- has_one :b
1358
- end
1359
- end
1360
-
1361
- after(:all) do
1362
- Object.send(:remove_const, :A)
1363
- Object.send(:remove_const, :B)
1364
- Object.send(:remove_const, :C)
1365
- end
1366
-
1367
- context "when the includes is on the subclass" do
1368
-
1369
- let!(:c_one) do
1370
- C.create!
1371
- end
1372
-
1373
- let!(:c_two) do
1374
- C.create!
1375
- end
1376
-
1377
- let!(:b) do
1378
- B.create!(c: c_two)
1379
- end
1380
-
1381
- let!(:results) do
1382
- C.includes(:b).to_a.detect do |c|
1383
- c.id == c_two.id
1384
- end
1385
- end
1386
-
1387
- it "returns the correct documents" do
1388
- expect(results).to eq(c_two)
1389
- end
1390
-
1391
- it "does not query the db" do
1392
- expect_query(0) do
1393
- results.b
1394
- end
1395
- end
1396
- end
1397
- end
1398
-
1399
- context "when the models are inherited from another one model" do
1400
-
1401
- context "when the relation is a has_one" do
1402
-
1403
- before(:all) do
1404
- class A
1405
- include Mongoid::Document
1406
- end
1407
-
1408
- class B < A
1409
- belongs_to :d
1410
- end
1411
-
1412
- class C < A
1413
- belongs_to :d
1414
- end
1415
-
1416
- class D
1417
- include Mongoid::Document
1418
- has_one :b
1419
- has_one :c
1420
- end
1421
- end
1422
-
1423
- after(:all) do
1424
- Object.send(:remove_const, :A)
1425
- Object.send(:remove_const, :B)
1426
- Object.send(:remove_const, :C)
1427
- Object.send(:remove_const, :D)
1428
- end
1429
-
1430
- context "when the includes is on the several relations" do
1431
-
1432
- let!(:d_one) do
1433
- D.create!
1434
- end
1435
-
1436
- let!(:d_two) do
1437
- D.create!
1438
- end
1439
-
1440
- let!(:b) do
1441
- B.create!(d: d_two)
1442
- end
1443
-
1444
- let!(:c) do
1445
- C.create!(d: d_two)
1446
- end
1447
-
1448
- let!(:results) do
1449
- D.includes(:b, :c).entries.detect do |d|
1450
- d.id == d_two.id
1451
- end
1452
- end
1453
-
1454
- it "returns the correct documents" do
1455
- expect(results).to eq(d_two)
1456
- end
1457
-
1458
- it "does not query the db on b" do
1459
- expect_query(0) do
1460
- results.b
1461
- end
1462
- end
1463
-
1464
- it "does not query the db on c" do
1465
- expect_query(0) do
1466
- results.b
1467
- end
1468
- end
1469
- end
1470
- end
1471
-
1472
- context "when the relation is a has_many" do
1473
-
1474
- before(:all) do
1475
- class A
1476
- include Mongoid::Document
1477
- end
1478
-
1479
- class B < A
1480
- belongs_to :d
1481
- end
1482
-
1483
- class C < A
1484
- belongs_to :d
1485
- end
1486
-
1487
- class D
1488
- include Mongoid::Document
1489
- has_many :b
1490
- has_many :c
1491
- end
1492
- end
1493
-
1494
- after(:all) do
1495
- Object.send(:remove_const, :A)
1496
- Object.send(:remove_const, :B)
1497
- Object.send(:remove_const, :C)
1498
- Object.send(:remove_const, :D)
1499
- end
1500
-
1501
- context "when the includes is on the several relations" do
1502
-
1503
- let!(:d_one) do
1504
- D.create!
1505
- end
1506
-
1507
- let!(:d_two) do
1508
- D.create!
1509
- end
1510
-
1511
- let!(:bs) do
1512
- 2.times.map { B.create!(d: d_two) }
1513
- end
1514
-
1515
- let!(:cs) do
1516
- 2.times.map { C.create!(d: d_two) }
1517
- end
1518
-
1519
- let!(:results) do
1520
- D.includes(:b, :c).entries.detect do |d|
1521
- d.id == d_two.id
1522
- end
1523
- end
1524
-
1525
- it "returns the correct documents" do
1526
- expect(results).to eq(d_two)
1527
- end
1528
-
1529
- it "does not query the db on b" do
1530
- expect_query(0) do
1531
- results.b
1532
- end
1533
- end
1534
-
1535
- it "does not query the db on c" do
1536
- expect_query(0) do
1537
- results.b
1538
- end
1539
- end
1540
- end
1541
- end
1542
- end
1543
-
1544
- context "when including the same association multiple times" do
1545
-
1546
- let(:criteria) do
1547
- Person.all.includes(:posts, :posts).includes(:posts)
1548
- end
1549
-
1550
- let(:association) do
1551
- Person.reflect_on_association(:posts)
1552
- end
1553
-
1554
- it "does not duplicate the association in the inclusions" do
1555
- expect(criteria.inclusions).to eq([ association ])
1556
- end
1557
- end
1558
-
1559
- context "when mapping the results more than once" do
1560
-
1561
- let!(:post) do
1562
- person.posts.create!(title: "one")
1563
- end
1564
-
1565
- let(:criteria) do
1566
- Post.includes(:person)
1567
- end
1568
-
1569
- let!(:results) do
1570
- criteria.map { |doc| doc }
1571
- criteria.map { |doc| doc }
1572
- end
1573
-
1574
- it "returns the proper results" do
1575
- expect(results.first.title).to eq("one")
1576
- end
1577
- end
1578
-
1579
- context "when including a belongs to relation" do
1580
-
1581
- context "when the criteria is from the root" do
1582
-
1583
- let!(:person_two) do
1584
- Person.create!(age: 2)
1585
- end
1586
-
1587
- let!(:post_one) do
1588
- person.posts.create!(title: "one")
1589
- end
1590
-
1591
- let!(:post_two) do
1592
- person_two.posts.create!(title: "two")
1593
- end
1594
-
1595
- context "when calling first" do
1596
-
1597
- let(:criteria) do
1598
- Post.includes(:person)
1599
- end
1600
-
1601
- let!(:document) do
1602
- criteria.first
1603
- end
1604
-
1605
- it "eager loads the first document" do
1606
- expect_query(0) do
1607
- expect(document.person).to eq(person)
1608
- end
1609
- end
1610
-
1611
- it "returns the first document" do
1612
- expect(document).to eq(post_one)
1613
- end
1614
- end
1615
-
1616
- context "when calling last" do
1617
-
1618
- let!(:criteria) do
1619
- Post.asc(:_id).includes(:person)
1620
- end
1621
-
1622
- let!(:document) do
1623
- criteria.last
1624
- end
1625
-
1626
- it "eager loads the last document" do
1627
- expect_query(0) do
1628
- expect(document.person).to eq(person_two)
1629
- end
1630
- end
1631
-
1632
- it "returns the last document" do
1633
- expect(document).to eq(post_two)
1634
- end
1635
- end
1636
- end
1637
-
1638
- context "when the criteria is from an embedded relation" do
1639
-
1640
- let(:peep) do
1641
- Person.create!
1642
- end
1643
-
1644
- let!(:address_one) do
1645
- peep.addresses.create!(street: "rosenthaler")
1646
- end
1647
-
1648
- let!(:address_two) do
1649
- peep.addresses.create!(street: "weinmeister")
1650
- end
1651
-
1652
- let!(:depeche) do
1653
- Band.create!(name: "Depeche Mode")
1654
- end
1655
-
1656
- let!(:tool) do
1657
- Band.create!(name: "Tool")
1658
- end
1659
-
1660
- before do
1661
- address_one.band = depeche
1662
- address_two.band = tool
1663
- address_one.save!
1664
- address_two.save!
1665
- end
1666
-
1667
- context "when calling first" do
1668
-
1669
- let(:criteria) do
1670
- peep.reload.addresses.includes(:band)
1671
- end
1672
-
1673
- let(:context) do
1674
- criteria.context
1675
- end
1676
-
1677
- let!(:document) do
1678
- criteria.first
1679
- end
1680
-
1681
- it "eager loads the first document" do
1682
- expect_query(0) do
1683
- expect(document.band).to eq(depeche)
1684
- end
1685
- end
1686
-
1687
- it "returns the document" do
1688
- expect(document).to eq(address_one)
1689
- end
1690
- end
1691
-
1692
- context "when calling last" do
1693
-
1694
- let(:criteria) do
1695
- peep.reload.addresses.includes(:band)
1696
- end
1697
-
1698
- let(:context) do
1699
- criteria.context
1700
- end
1701
-
1702
- let!(:document) do
1703
- criteria.last
1704
- end
1705
-
1706
- it "eager loads the last document" do
1707
- expect_query(0) do
1708
- expect(document.band).to eq(tool)
1709
- end
1710
- end
1711
-
1712
- it "returns the document" do
1713
- expect(document).to eq(address_two)
1714
- end
1715
- end
1716
-
1717
- context "when iterating all documents" do
1718
-
1719
- let(:criteria) do
1720
- peep.reload.addresses.includes(:band)
1721
- end
1722
-
1723
- let(:context) do
1724
- criteria.context
1725
- end
1726
-
1727
- let!(:documents) do
1728
- criteria.to_a
1729
- end
1730
-
1731
- it "eager loads the first document" do
1732
- expect_query(0) do
1733
- expect(documents.first.band).to eq(depeche)
1734
- end
1735
- end
1736
-
1737
- it "eager loads the last document" do
1738
- expect_query(0) do
1739
- expect(documents.last.band).to eq(tool)
1740
- end
1741
- end
1742
-
1743
- it "returns the documents" do
1744
- expect(documents).to eq([ address_one, address_two ])
1745
- end
1746
- end
1747
- end
1748
- end
1749
-
1750
- context "when providing inclusions to the default scope" do
1751
-
1752
- before do
1753
- Person.default_scope(->{ Person.includes(:posts) })
1754
- end
1755
-
1756
- after do
1757
- Person.default_scoping = nil
1758
- end
1759
-
1760
- let!(:post_one) do
1761
- person.posts.create!(title: "one")
1762
- end
1763
-
1764
- let!(:post_two) do
1765
- person.posts.create!(title: "two")
1766
- end
1767
-
1768
- context "when the criteria has no options" do
1769
-
1770
- let!(:criteria) do
1771
- Person.asc(:age).all
1772
- end
1773
-
1774
- let!(:documents) do
1775
- criteria.entries
1776
- end
1777
-
1778
- it "returns the correct documents" do
1779
- expect(documents).to eq([ person ])
1780
- end
1781
-
1782
- it "eager loads the first document" do
1783
- expect_query(0) do
1784
- expect(documents.first.posts.first).to eq(post_one)
1785
- end
1786
- end
1787
-
1788
- it "eager loads the last document" do
1789
- expect_query(0) do
1790
- expect(documents.first.posts.last).to eq(post_two)
1791
- end
1792
- end
1793
-
1794
- context "when executing the query twice" do
1795
-
1796
- let!(:new_criteria) do
1797
- Person.where(id: person.id)
1798
- end
1799
-
1800
- let!(:new_context) do
1801
- new_criteria.context
1802
- end
1803
-
1804
- before do
1805
- expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
1806
- end
1807
-
1808
- let!(:from_db) do
1809
- new_criteria.first
1810
- end
1811
-
1812
- it "does not duplicate documents in the relation" do
1813
- expect(person.posts.size).to eq(2)
1814
- end
1815
- end
1816
- end
1817
-
1818
- context "when calling first on the criteria" do
1819
-
1820
- let(:criteria) do
1821
- Person.asc(:age).all
1822
- end
1823
-
1824
- let!(:from_db) do
1825
- criteria.first
1826
- end
1827
-
1828
- it "returns the correct documents" do
1829
- expect(from_db).to eq(person)
1830
- end
1831
-
1832
- it "eager loads the first document" do
1833
- expect_query(0) do
1834
- expect(from_db.posts.first).to eq(post_one)
1835
- end
1836
- end
1837
-
1838
- it "eager loads the last document" do
1839
- expect_query(0) do
1840
- expect(from_db.posts.last).to eq(post_two)
1841
- end
1842
- end
1843
- end
1844
-
1845
- context "when calling last on the criteria" do
1846
-
1847
- let(:criteria) do
1848
- Person.asc(:age).all
1849
- end
1850
-
1851
- let!(:context) do
1852
- criteria.context
1853
- end
1854
-
1855
- before do
1856
- expect(context).to receive(:eager_load).with([person]).once.and_call_original
1857
- end
1858
-
1859
- let!(:from_db) do
1860
- criteria.last
1861
- end
1862
-
1863
- it "returns the correct documents" do
1864
- expect(from_db).to eq(person)
1865
- end
1866
-
1867
- it "eager loads the first document" do
1868
- expect_query(0) do
1869
- expect(from_db.posts.first).to eq(post_one)
1870
- end
1871
- end
1872
-
1873
- it "eager loads the last document" do
1874
- expect_query(0) do
1875
- expect(from_db.posts.last).to eq(post_two)
1876
- end
1877
- end
1878
- end
1879
-
1880
- context "when the criteria has limiting options" do
1881
-
1882
- let!(:person_two) do
1883
- Person.create!
1884
- end
1885
-
1886
- let!(:post_three) do
1887
- person_two.posts.create!(title: "three")
1888
- end
1889
-
1890
- let!(:criteria) do
1891
- Person.asc(:age).limit(1)
1892
- end
1893
-
1894
- let!(:documents) do
1895
- criteria.entries
1896
- end
1897
-
1898
- it "returns the correct documents" do
1899
- expect(criteria).to eq([ person ])
1900
- end
1901
-
1902
- it "eager loads the first document" do
1903
- expect_query(0) do
1904
- expect(documents.first.posts.first).to eq(post_one)
1905
- end
1906
- end
1907
-
1908
- it "eager loads the second document" do
1909
- expect_query(0) do
1910
- expect(documents.first.posts.last).to eq(post_two)
1911
- end
1912
- end
1913
- end
1914
- end
1915
-
1916
- context "when including a has and belongs to many" do
1917
-
1918
- let!(:preference_one) do
1919
- person.preferences.create!(name: "one")
1920
- end
1921
-
1922
- let!(:preference_two) do
1923
- person.preferences.create!(name: "two")
1924
- end
1925
-
1926
- context "when one of the related items is deleted" do
1927
-
1928
- before do
1929
- person.preferences = [ preference_one, preference_two ]
1930
- preference_two.delete
1931
- end
1932
-
1933
- let(:criteria) do
1934
- Person.where(id: person.id).includes(:preferences)
1935
- end
1936
-
1937
- it "only loads the existing related items" do
1938
- expect(criteria.entries.first.preferences).to eq([ preference_one ])
1939
- end
1940
- end
1941
-
1942
- context "when the criteria has no options" do
1943
-
1944
- let!(:criteria) do
1945
- Person.asc(:age).includes(:preferences)
1946
- end
1947
-
1948
- let!(:documents) do
1949
- criteria.entries
1950
- end
1951
-
1952
- it "returns the correct documents" do
1953
- expect(documents).to eq([ person ])
1954
- end
1955
-
1956
- it "eager loads the first document" do
1957
- expect_query(0) do
1958
- expect(documents.first.preferences.first).to eq(preference_one)
1959
- end
1960
- end
1961
-
1962
- it "eager loads the last document" do
1963
- expect_query(0) do
1964
- expect(documents.first.preferences.last).to eq(preference_two)
1965
- end
1966
- end
1967
- end
1968
-
1969
- context "when calling first on the criteria" do
1970
-
1971
- let!(:criteria) do
1972
- Person.asc(:age).includes(:preferences)
1973
- end
1974
-
1975
- let!(:from_db) do
1976
- criteria.first
1977
- end
1978
-
1979
- it "returns the correct documents" do
1980
- expect(from_db).to eq(person)
1981
- end
1982
-
1983
- it "eager loads the first document" do
1984
- expect_query(0) do
1985
- expect(from_db.preferences.first).to eq(preference_one)
1986
- end
1987
- end
1988
-
1989
- it "eager loads the last document" do
1990
- expect_query(0) do
1991
- expect(from_db.preferences.last).to eq(preference_two)
1992
- end
1993
- end
1994
- end
1995
-
1996
- context "when calling last on the criteria" do
1997
-
1998
- let!(:criteria) do
1999
- Person.asc(:age).includes(:preferences)
2000
- end
2001
-
2002
- let!(:from_db) do
2003
- criteria.last
2004
- end
2005
-
2006
- it "returns the correct documents" do
2007
- expect(from_db).to eq(person)
2008
- end
2009
-
2010
- it "eager loads the first document" do
2011
- expect_query(0) do
2012
- expect(from_db.preferences.first).to eq(preference_one)
2013
- end
2014
- end
2015
-
2016
- it "eager loads the last document" do
2017
- expect_query(0) do
2018
- expect(from_db.preferences.last).to eq(preference_two)
2019
- end
2020
- end
2021
- end
2022
- end
2023
-
2024
- context "when including a has many" do
2025
-
2026
- let!(:post_one) do
2027
- person.posts.create!(title: "one")
2028
- end
2029
-
2030
- let!(:post_two) do
2031
- person.posts.create!(title: "two")
2032
- end
2033
-
2034
- context "when the criteria has no options" do
2035
-
2036
- let!(:criteria) do
2037
- Person.asc(:age).includes(:posts)
2038
- end
2039
-
2040
- let!(:documents) do
2041
- criteria.entries
2042
- end
2043
-
2044
- it "returns the correct documents" do
2045
- expect(documents).to eq([ person ])
2046
- end
2047
-
2048
- it "eager loads the first document" do
2049
- expect_query(0) do
2050
- expect(documents.first.posts.first).to eq(post_one)
2051
- end
2052
- end
2053
-
2054
- it "eager loads the last document" do
2055
- expect_query(0) do
2056
- expect(documents.first.posts.last).to eq(post_two)
2057
- end
2058
- end
2059
- end
2060
-
2061
- context "when calling first on the criteria" do
2062
-
2063
- let!(:criteria) do
2064
- Person.asc(:age).includes(:posts)
2065
- end
2066
-
2067
- let!(:from_db) do
2068
- criteria.first
2069
- end
2070
-
2071
- it "returns the correct documents" do
2072
- expect(from_db).to eq(person)
2073
- end
2074
-
2075
- context "when subsequently getting all documents" do
2076
-
2077
- let!(:documents) do
2078
- criteria.entries
2079
- end
2080
-
2081
- it "returns the correct documents" do
2082
- expect(documents).to eq([ person ])
2083
- end
2084
- end
2085
- end
2086
-
2087
- context "when calling last on the criteria" do
2088
-
2089
- let!(:criteria) do
2090
- Person.asc(:age).includes(:posts)
2091
- end
2092
-
2093
- let!(:from_db) do
2094
- criteria.last
2095
- end
2096
-
2097
- it "returns the correct documents" do
2098
- expect(from_db).to eq(person)
2099
- end
2100
-
2101
- context "when subsequently getting all documents" do
2102
-
2103
- let!(:documents) do
2104
- criteria.entries
2105
- end
2106
-
2107
- it "returns the correct documents" do
2108
- expect(documents).to eq([ person ])
2109
- end
2110
- end
2111
- end
2112
-
2113
- context "when the criteria has limiting options" do
2114
-
2115
- let!(:person_two) do
2116
- Person.create!
2117
- end
2118
-
2119
- let!(:post_three) do
2120
- person_two.posts.create!(title: "three")
2121
- end
2122
-
2123
- let!(:criteria) do
2124
- Person.includes(:posts).asc(:age).limit(1)
2125
- end
2126
-
2127
- let(:context) do
2128
- criteria.context
2129
- end
2130
-
2131
- before do
2132
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2133
- end
2134
-
2135
- let!(:documents) do
2136
- criteria.entries
2137
- end
2138
-
2139
- it "returns the correct documents" do
2140
- expect(documents).to eq([ person ])
2141
- end
2142
- end
2143
- end
2144
-
2145
- context "when including a has one" do
2146
-
2147
- let!(:game_one) do
2148
- person.create_game(name: "one")
2149
- end
2150
-
2151
- let!(:game_two) do
2152
- person.create_game(name: "two")
2153
- end
2154
-
2155
- context "when the criteria has no options" do
2156
-
2157
- let!(:criteria) do
2158
- Person.asc(:age).includes(:game)
2159
- end
2160
-
2161
- let(:context) do
2162
- criteria.context
2163
- end
2164
-
2165
- before do
2166
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2167
- end
2168
-
2169
- let!(:documents) do
2170
- criteria.entries
2171
- end
2172
-
2173
- it "returns the correct documents" do
2174
- expect(documents).to eq([ person ])
2175
- end
2176
- end
2177
-
2178
- context "when the criteria has limiting options" do
2179
-
2180
- let!(:person_two) do
2181
- Person.create!(age: 2)
2182
- end
2183
-
2184
- let!(:game_three) do
2185
- person_two.create_game(name: "Skyrim")
2186
- end
2187
-
2188
- let!(:criteria) do
2189
- Person.where(id: person.id).includes(:game).asc(:age).limit(1)
2190
- end
2191
-
2192
- let(:context) do
2193
- criteria.context
2194
- end
2195
-
2196
- before do
2197
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2198
- end
2199
-
2200
- let!(:documents) do
2201
- criteria.entries
2202
- end
2203
-
2204
- it "returns the correct documents" do
2205
- expect(documents).to eq([ person ])
2206
- end
2207
- end
2208
- end
2209
-
2210
- context "when including a belongs to" do
2211
-
2212
- let(:person_two) do
2213
- Person.create!(age: 2)
2214
- end
2215
-
2216
- let!(:game_one) do
2217
- person.create_game(name: "one")
2218
- end
2219
-
2220
- let!(:game_two) do
2221
- person_two.create_game(name: "two")
2222
- end
2223
-
2224
- context "when providing no options" do
2225
-
2226
- let!(:criteria) do
2227
- Game.includes(:person)
2228
- end
2229
-
2230
- let(:context) do
2231
- criteria.context
2232
- end
2233
-
2234
- before do
2235
- expect(context).to receive(:preload).twice.and_call_original
2236
- end
2237
-
2238
- let!(:documents) do
2239
- criteria.entries
2240
- end
2241
-
2242
- it "returns the correct documents" do
2243
- expect(criteria).to eq([ game_one, game_two ])
2244
- end
2245
- end
2246
-
2247
- context "when the criteria has limiting options" do
2248
-
2249
- let!(:criteria) do
2250
- Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
2251
- end
2252
-
2253
- let(:context) do
2254
- criteria.context
2255
- end
2256
-
2257
- before do
2258
- expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
2259
- end
2260
-
2261
- let!(:documents) do
2262
- criteria.entries
2263
- end
2264
-
2265
- it "returns the correct documents" do
2266
- expect(documents).to eq([ game_one ])
2267
- end
2268
- end
2269
- end
2270
-
2271
- context "when including multiples in the same criteria" do
2272
-
2273
- let!(:post_one) do
2274
- person.posts.create!(title: "one")
2275
- end
2276
-
2277
- let!(:post_two) do
2278
- person.posts.create!(title: "two")
2279
- end
1163
+ it "returns the matching documents" do
1164
+ expect(criteria).to eq([ match_one ])
1165
+ end
1166
+ end
2280
1167
 
2281
- let!(:game_one) do
2282
- person.create_game(name: "one")
2283
- end
1168
+ context "when providing empty strings" do
2284
1169
 
2285
- let!(:game_two) do
2286
- person.create_game(name: "two")
2287
- end
1170
+ let(:criteria) do
1171
+ Person.send(method, preference_ids: [ id, "" ])
1172
+ end
2288
1173
 
2289
- let!(:criteria) do
2290
- Person.includes(:posts, :game).asc(:age)
2291
- end
1174
+ it "returns the matching documents" do
1175
+ expect(criteria).to eq([ match_one ])
1176
+ end
1177
+ end
2292
1178
 
2293
- let(:context) do
2294
- criteria.context
2295
- end
1179
+ context "when providing nils" do
2296
1180
 
2297
- before do
2298
- expect(context).to receive(:preload).twice.and_call_original
2299
- end
1181
+ context "when the relation is a many to many" do
2300
1182
 
2301
- let!(:documents) do
2302
- criteria.entries
2303
- end
1183
+ let(:criteria) do
1184
+ Person.send(method, preference_ids: [ id, nil ])
1185
+ end
2304
1186
 
2305
- it "returns the correct documents" do
2306
- expect(criteria).to eq([ person ])
2307
- end
2308
- end
2309
- end
1187
+ it "returns the matching documents" do
1188
+ expect(criteria).to eq([ match_one ])
1189
+ end
1190
+ end
2310
1191
 
2311
- describe "#inclusions" do
1192
+ context "when the relation is a one to one" do
2312
1193
 
2313
- let(:criteria) do
2314
- Band.includes(:records)
2315
- end
1194
+ let!(:game) do
1195
+ Game.create!
1196
+ end
2316
1197
 
2317
- let(:association) do
2318
- Band.relations["records"]
2319
- end
1198
+ let(:criteria) do
1199
+ Game.send(method, person_id: [ nil ])
1200
+ end
2320
1201
 
2321
- it "returns the inclusions" do
2322
- expect(criteria.inclusions).to eq([ association ])
1202
+ it "returns the matching documents" do
1203
+ expect(criteria).to eq([ game ])
1204
+ end
1205
+ end
1206
+ end
1207
+ end
2323
1208
  end
2324
1209
  end
2325
1210
 
2326
- describe "#inclusions=" do
1211
+ describe "#initialize" do
2327
1212
 
2328
1213
  let(:criteria) do
2329
- Band.all
1214
+ described_class.new(Band)
2330
1215
  end
2331
1216
 
2332
- let(:association) do
2333
- Band.relations["records"]
1217
+ it "sets the class" do
1218
+ expect(criteria.klass).to eq(Band)
2334
1219
  end
2335
1220
 
2336
- before do
2337
- criteria.inclusions = [ association ]
1221
+ it "sets the aliased fields" do
1222
+ expect(criteria.aliased_fields).to eq(Band.aliased_fields)
2338
1223
  end
2339
1224
 
2340
- it "sets the inclusions" do
2341
- expect(criteria.inclusions).to eq([ association ])
1225
+ it "sets the serializers" do
1226
+ expect(criteria.serializers).to eq(Band.fields)
2342
1227
  end
2343
1228
  end
2344
1229
 
@@ -3047,7 +1932,7 @@ describe Mongoid::Criteria do
3047
1932
  end
3048
1933
 
3049
1934
  with_config_values :legacy_pluck_distinct, true, false do
3050
- it "returns a array with nil values" do
1935
+ it "returns an array with nil values" do
3051
1936
  expect(plucked).to eq([nil, nil, nil])
3052
1937
  end
3053
1938
  end
@@ -3060,7 +1945,7 @@ describe Mongoid::Criteria do
3060
1945
  end
3061
1946
 
3062
1947
  with_config_values :legacy_pluck_distinct, true, false do
3063
- it "returns a nil arrays" do
1948
+ it "returns an array of arrays with nil values" do
3064
1949
  expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
3065
1950
  end
3066
1951
  end
@@ -3183,10 +2068,6 @@ describe Mongoid::Criteria do
3183
2068
  I18n.fallbacks = prev_fallbacks
3184
2069
  end
3185
2070
 
3186
- after do
3187
- I18n.locale = :en
3188
- end
3189
-
3190
2071
  let(:plucked) do
3191
2072
  Dictionary.all.pluck(:description).first
3192
2073
  end
@@ -3222,10 +2103,6 @@ describe Mongoid::Criteria do
3222
2103
  Person.create!(passport: p, employer_id: 12345)
3223
2104
  end
3224
2105
 
3225
- after do
3226
- I18n.locale = :en
3227
- end
3228
-
3229
2106
  let(:plucked) do
3230
2107
  Person.where(employer_id: 12345).pluck("pass.name").first
3231
2108
  end
@@ -3281,18 +2158,45 @@ describe Mongoid::Criteria do
3281
2158
  context "when legacy_pluck_distinct is set" do
3282
2159
  config_override :legacy_pluck_distinct, true
3283
2160
 
3284
- it "does not demongoize the field" do
3285
- expect(plucked.first).to be_a(String)
3286
- expect(plucked.first).to eq("1E2")
2161
+ context 'when value is stored as string' do
2162
+ config_override :map_big_decimal_to_decimal128, false
2163
+
2164
+ it "does not demongoize the field" do
2165
+ expect(plucked.first).to be_a(String)
2166
+ expect(plucked.first).to eq("1E2")
2167
+ end
2168
+ end
2169
+
2170
+ context 'when value is stored as decimal128' do
2171
+ config_override :map_big_decimal_to_decimal128, true
2172
+ max_bson_version '4.99.99'
2173
+
2174
+ it "does not demongoize the field" do
2175
+ expect(plucked.first).to be_a(BSON::Decimal128)
2176
+ expect(plucked.first).to eq(BSON::Decimal128.new("1E2"))
2177
+ end
3287
2178
  end
3288
2179
  end
3289
2180
 
3290
2181
  context "when legacy_pluck_distinct is not set" do
3291
2182
  config_override :legacy_pluck_distinct, false
3292
2183
 
3293
- it "demongoizes the field" do
3294
- expect(plucked.first).to be_a(BigDecimal)
3295
- expect(plucked.first).to eq(BigDecimal("1E2"))
2184
+ context 'when value is stored as string' do
2185
+ config_override :map_big_decimal_to_decimal128, false
2186
+
2187
+ it "demongoizes the field" do
2188
+ expect(plucked.first).to be_a(BigDecimal)
2189
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2190
+ end
2191
+ end
2192
+
2193
+ context 'when value is stored as decimal128' do
2194
+ config_override :map_big_decimal_to_decimal128, true
2195
+
2196
+ it "demongoizes the field" do
2197
+ expect(plucked.first).to be_a(BigDecimal)
2198
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2199
+ end
3296
2200
  end
3297
2201
  end
3298
2202
  end
@@ -3305,9 +2209,11 @@ describe Mongoid::Criteria do
3305
2209
 
3306
2210
  context "when legacy_pluck_distinct is set" do
3307
2211
  config_override :legacy_pluck_distinct, true
2212
+ config_override :map_big_decimal_to_decimal128, true
2213
+ max_bson_version '4.99.99'
3308
2214
 
3309
2215
  it "returns a hash with a non-demongoized field" do
3310
- expect(plucked.first).to eq({ 'sales' => "1E2" })
2216
+ expect(plucked.first).to eq({ 'sales' => BSON::Decimal128.new('1E+2') })
3311
2217
  end
3312
2218
  end
3313
2219
 
@@ -3315,7 +2221,7 @@ describe Mongoid::Criteria do
3315
2221
  config_override :legacy_pluck_distinct, false
3316
2222
 
3317
2223
  it "demongoizes the field" do
3318
- expect(plucked.first).to eq(BigDecimal("1E2"))
2224
+ expect(plucked).to eq([ BigDecimal("1E2") ])
3319
2225
  end
3320
2226
  end
3321
2227
  end
@@ -3328,9 +2234,11 @@ describe Mongoid::Criteria do
3328
2234
 
3329
2235
  context "when legacy_pluck_distinct is set" do
3330
2236
  config_override :legacy_pluck_distinct, true
2237
+ config_override :map_big_decimal_to_decimal128, true
2238
+ max_bson_version '4.99.99'
3331
2239
 
3332
2240
  it "returns a hash with a non-demongoized field" do
3333
- expect(plucked.first).to eq([{ 'sales' => "1E2" }])
2241
+ expect(plucked.first).to eq([{ 'sales' => BSON::Decimal128.new('1E+2') }])
3334
2242
  end
3335
2243
  end
3336
2244
 
@@ -3338,7 +2246,7 @@ describe Mongoid::Criteria do
3338
2246
  config_override :legacy_pluck_distinct, false
3339
2247
 
3340
2248
  it "demongoizes the field" do
3341
- expect(plucked.first).to eq([BigDecimal("1E2")])
2249
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
3342
2250
  end
3343
2251
  end
3344
2252
  end
@@ -3365,6 +2273,66 @@ describe Mongoid::Criteria do
3365
2273
  end
3366
2274
  end
3367
2275
  end
2276
+
2277
+ context "when tallying deeply nested arrays/embedded associations" do
2278
+
2279
+ before do
2280
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2281
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2282
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2283
+ end
2284
+
2285
+ let(:plucked) do
2286
+ Person.pluck("addresses.code.deepest.array.y.z")
2287
+ end
2288
+
2289
+ it "returns the correct hash" do
2290
+ expect(plucked).to eq([
2291
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2292
+ ])
2293
+ end
2294
+ end
2295
+ end
2296
+
2297
+ describe "#pick" do
2298
+
2299
+ let!(:depeche) do
2300
+ Band.create!(name: "Depeche Mode", likes: 3)
2301
+ end
2302
+
2303
+ let!(:tool) do
2304
+ Band.create!(name: "Tool", likes: 3)
2305
+ end
2306
+
2307
+ context "when picking a field" do
2308
+
2309
+ let(:criteria) do
2310
+ Band.all
2311
+ end
2312
+
2313
+ let(:picked) do
2314
+ criteria.pick(:name)
2315
+ end
2316
+
2317
+ it "returns one element" do
2318
+ expect(picked).to eq("Depeche Mode")
2319
+ end
2320
+ end
2321
+
2322
+ context "when picking multiple fields" do
2323
+
2324
+ let(:criteria) do
2325
+ Band.all
2326
+ end
2327
+
2328
+ let(:picked) do
2329
+ criteria.pick(:name, :likes)
2330
+ end
2331
+
2332
+ it "returns an array" do
2333
+ expect(picked).to eq([ "Depeche Mode", 3 ])
2334
+ end
2335
+ end
3368
2336
  end
3369
2337
 
3370
2338
  describe "#respond_to?" do
@@ -3740,20 +2708,109 @@ describe Mongoid::Criteria do
3740
2708
 
3741
2709
  context "when querying on a big decimal" do
3742
2710
 
3743
- let(:sales) do
3744
- BigDecimal('0.1')
2711
+ context 'when map_big_decimal_to_decimal128 is false' do
2712
+ config_override :map_big_decimal_to_decimal128, false
2713
+
2714
+ let(:sales) do
2715
+ BigDecimal('0.1')
2716
+ end
2717
+
2718
+ let!(:band) do
2719
+ Band.create!(name: "Boards of Canada", sales: sales)
2720
+ end
2721
+
2722
+ let(:from_db) do
2723
+ Band.where(sales: sales).first
2724
+ end
2725
+
2726
+ it "finds the document by the big decimal value" do
2727
+ expect(from_db).to eq(band)
2728
+ end
3745
2729
  end
3746
2730
 
3747
- let!(:band) do
3748
- Band.create!(name: "Boards of Canada", sales: sales)
2731
+ context 'when map_big_decimal_to_decimal128 is true' do
2732
+ config_override :map_big_decimal_to_decimal128, true
2733
+
2734
+ let(:sales) do
2735
+ BigDecimal('0.1')
2736
+ end
2737
+
2738
+ let!(:band) do
2739
+ Band.create!(name: "Boards of Canada", sales: sales)
2740
+ end
2741
+
2742
+ let(:from_db) do
2743
+ Band.where(sales: sales).first
2744
+ end
2745
+
2746
+ it "finds the document by the big decimal value" do
2747
+ expect(from_db).to eq(band)
2748
+ end
3749
2749
  end
3750
2750
 
3751
- let(:from_db) do
3752
- Band.where(sales: sales).first
2751
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2752
+ config_override :map_big_decimal_to_decimal128, false
2753
+
2754
+ let(:sales) do
2755
+ BigDecimal('0.1')
2756
+ end
2757
+
2758
+ let!(:band) do
2759
+ Mongoid.map_big_decimal_to_decimal128 = false
2760
+ Band.create!(name: "Boards of Canada", sales: sales)
2761
+ end
2762
+
2763
+ let(:from_db) do
2764
+ Mongoid.map_big_decimal_to_decimal128 = true
2765
+ Band.where(sales: sales.to_s).first
2766
+ end
2767
+
2768
+ it "finds the document by the big decimal value" do
2769
+ expect(from_db).to eq(band)
2770
+ end
3753
2771
  end
2772
+ end
3754
2773
 
3755
- it "finds the document by the big decimal value" do
3756
- expect(from_db).to eq(band)
2774
+ context "when querying on a big decimal from a dynamic field" do
2775
+
2776
+ context 'when map_big_decimal_to_decimal128 is false' do
2777
+ config_override :map_big_decimal_to_decimal128, false
2778
+
2779
+ let(:fans) do
2780
+ BigDecimal('139432.0002')
2781
+ end
2782
+
2783
+ let!(:band) do
2784
+ Band.create!(name: "Boards of Canada", fans: fans)
2785
+ end
2786
+
2787
+ let(:from_db) do
2788
+ Band.where(fans: fans.to_s).first
2789
+ end
2790
+
2791
+ it "finds the document by the big decimal value" do
2792
+ expect(from_db).to eq(band)
2793
+ end
2794
+ end
2795
+
2796
+ context 'when map_big_decimal_to_decimal128 is true' do
2797
+ config_override :map_big_decimal_to_decimal128, true
2798
+
2799
+ let(:fans) do
2800
+ BigDecimal('139432.0002')
2801
+ end
2802
+
2803
+ let!(:band) do
2804
+ Band.create!(name: "Boards of Canada", fans: fans)
2805
+ end
2806
+
2807
+ let(:from_db) do
2808
+ Band.where(fans: fans).first
2809
+ end
2810
+
2811
+ it "only finds the document by the string value" do
2812
+ expect(from_db).to eq(band)
2813
+ end
3757
2814
  end
3758
2815
  end
3759
2816
 
@@ -3858,6 +2915,217 @@ describe Mongoid::Criteria do
3858
2915
  expect(dup_criteria.selector).to eq({ "_id" => _id })
3859
2916
  end
3860
2917
  end
2918
+
2919
+ context "when querying an embedded field" do
2920
+ let(:criteria) { Band.where("label.name": 12345) }
2921
+
2922
+ it "mongoizes the embedded field in the selector" do
2923
+ expect(criteria.selector).to eq("label.name" => "12345")
2924
+ end
2925
+ end
2926
+
2927
+ context "when querying with a range" do
2928
+
2929
+ context "when querying an embeds_many association" do
2930
+ let(:criteria) do
2931
+ Band.where("labels" => 10..15)
2932
+ end
2933
+
2934
+ it "correctly uses elemMatch without an inner key" do
2935
+ expect(criteria.selector).to eq(
2936
+ "labels" => {
2937
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2938
+ }
2939
+ )
2940
+ end
2941
+ end
2942
+
2943
+ context "when querying an element in an embeds_many association" do
2944
+ let(:criteria) do
2945
+ Band.where("labels.age" => 10..15)
2946
+ end
2947
+
2948
+ it "correctly uses elemMatch" do
2949
+ expect(criteria.selector).to eq(
2950
+ "labels" => {
2951
+ "$elemMatch" => {
2952
+ "age" => { "$gte" => 10, "$lte" => 15 }
2953
+ }
2954
+ }
2955
+ )
2956
+ end
2957
+ end
2958
+
2959
+ context "when querying a field of type array" do
2960
+ let(:criteria) do
2961
+ Band.where("genres" => 10..15)
2962
+ end
2963
+
2964
+ it "correctly uses elemMatch without an inner key" do
2965
+ expect(criteria.selector).to eq(
2966
+ "genres" => {
2967
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2968
+ }
2969
+ )
2970
+ end
2971
+ end
2972
+
2973
+ context "when querying an aliased field of type array" do
2974
+ let(:criteria) do
2975
+ Person.where("array" => 10..15)
2976
+ end
2977
+
2978
+ it "correctly uses the aliased field and elemMatch" do
2979
+ expect(criteria.selector).to eq(
2980
+ "a" => {
2981
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2982
+ }
2983
+ )
2984
+ end
2985
+ end
2986
+
2987
+ context "when querying a field inside an array" do
2988
+ let(:criteria) do
2989
+ Band.where("genres.age" => 10..15)
2990
+ end
2991
+
2992
+ it "correctly uses elemMatch" do
2993
+ expect(criteria.selector).to eq(
2994
+ "genres" => {
2995
+ "$elemMatch" => {
2996
+ "age" => { "$gte" => 10, "$lte" => 15 }
2997
+ }
2998
+ }
2999
+ )
3000
+ end
3001
+ end
3002
+
3003
+ context "when there are no embeds_manys or Arrays" do
3004
+ let(:criteria) do
3005
+ Band.where("fans.info.age" => 10..15)
3006
+ end
3007
+
3008
+ it "does not use elemMatch" do
3009
+ expect(criteria.selector).to eq(
3010
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
3011
+ )
3012
+ end
3013
+ end
3014
+
3015
+ context "when querying a nested element in an embeds_many association" do
3016
+ let(:criteria) do
3017
+ Band.where("labels.age.number" => 10..15)
3018
+ end
3019
+
3020
+ it "correctly uses elemMatch" do
3021
+ expect(criteria.selector).to eq(
3022
+ "labels" => {
3023
+ "$elemMatch" => {
3024
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
3025
+ }
3026
+ }
3027
+ )
3028
+ end
3029
+ end
3030
+
3031
+ context "when querying a nested element in an Array" do
3032
+ let(:criteria) do
3033
+ Band.where("genres.name.length" => 10..15)
3034
+ end
3035
+
3036
+ it "correctly uses elemMatch" do
3037
+ expect(criteria.selector).to eq(
3038
+ "genres" => {
3039
+ "$elemMatch" => {
3040
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3041
+ }
3042
+ }
3043
+ )
3044
+ end
3045
+ end
3046
+
3047
+ context "when querying a nested element in a nested embeds_many association" do
3048
+ context "when the outer association is an embeds_many" do
3049
+ let(:criteria) do
3050
+ Band.where("records.tracks.name.length" => 10..15)
3051
+ end
3052
+
3053
+ it "correctly uses elemMatch" do
3054
+ expect(criteria.selector).to eq(
3055
+ "records.tracks" => {
3056
+ "$elemMatch" => {
3057
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3058
+ }
3059
+ }
3060
+ )
3061
+ end
3062
+ end
3063
+
3064
+ context "when the outer association is an embeds_one" do
3065
+ let(:criteria) do
3066
+ Person.where("name.translations.language.length" => 10..15)
3067
+ end
3068
+
3069
+ it "correctly uses elemMatch" do
3070
+ expect(criteria.selector).to eq(
3071
+ "name.translations" => {
3072
+ "$elemMatch" => {
3073
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
3074
+ }
3075
+ }
3076
+ )
3077
+ end
3078
+ end
3079
+ end
3080
+
3081
+ context "when querying a deeply nested array" do
3082
+ let(:criteria) do
3083
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
3084
+ end
3085
+
3086
+ it "correctly uses elemMatch" do
3087
+ expect(criteria.selector).to eq(
3088
+ "addresses.code.deepest.array" => {
3089
+ "$elemMatch" => {
3090
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
3091
+ }
3092
+ }
3093
+ )
3094
+ end
3095
+ end
3096
+
3097
+ context "when there are multiple conditions" do
3098
+ let(:criteria) do
3099
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
3100
+ end
3101
+
3102
+ it "correctly combines the conditions" do
3103
+ expect(criteria.selector).to eq("$or" => [
3104
+ { "labels" => {
3105
+ "$elemMatch" => {
3106
+ "age" => { "$gte" => 10, "$lte" => 15 }
3107
+ } } },
3108
+ { "labels" => 8 }
3109
+ ])
3110
+ end
3111
+ end
3112
+
3113
+ context "when the association is aliased" do
3114
+ let(:criteria) do
3115
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
3116
+ end
3117
+
3118
+ it "correctly uses the aliased association" do
3119
+ expect(criteria.selector).to eq(
3120
+ "pass.passport_pages" => {
3121
+ "$elemMatch" => {
3122
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
3123
+ }
3124
+ }
3125
+ )
3126
+ end
3127
+ end
3128
+ end
3861
3129
  end
3862
3130
 
3863
3131
  describe "#for_js" do