mongoid 5.4.0 → 6.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +26 -0
  5. data/lib/config/locales/en.yml +40 -0
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic.rb +5 -5
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/attributes.rb +22 -21
  10. data/lib/mongoid/cacheable.rb +36 -0
  11. data/lib/mongoid/changeable.rb +36 -0
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/sessions.rb +113 -0
  14. data/lib/mongoid/clients/storage_options.rb +2 -69
  15. data/lib/mongoid/clients.rb +10 -63
  16. data/lib/mongoid/composable.rb +29 -2
  17. data/lib/mongoid/config.rb +1 -0
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  19. data/lib/mongoid/contextual/atomic.rb +4 -4
  20. data/lib/mongoid/contextual/map_reduce.rb +7 -3
  21. data/lib/mongoid/contextual/memory.rb +9 -4
  22. data/lib/mongoid/contextual/mongo.rb +65 -30
  23. data/lib/mongoid/contextual/none.rb +12 -0
  24. data/lib/mongoid/copyable.rb +13 -6
  25. data/lib/mongoid/criteria/marshalable.rb +2 -2
  26. data/lib/mongoid/criteria/modifiable.rb +29 -3
  27. data/lib/mongoid/criteria/options.rb +25 -0
  28. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  29. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  30. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  32. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  33. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  34. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  35. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  36. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  37. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  38. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  39. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
  40. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  41. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  42. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  43. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  44. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  45. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  46. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  47. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  48. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  49. data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
  50. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  51. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  52. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  53. data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
  54. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  55. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  56. data/lib/mongoid/criteria/queryable.rb +87 -0
  57. data/lib/mongoid/criteria.rb +6 -2
  58. data/lib/mongoid/document.rb +34 -41
  59. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  60. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  61. data/lib/mongoid/errors/invalid_field.rb +2 -2
  62. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  63. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  64. data/lib/mongoid/errors/invalid_session_use.rb +24 -0
  65. data/lib/mongoid/errors.rb +3 -0
  66. data/lib/mongoid/evolvable.rb +1 -1
  67. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  68. data/lib/mongoid/extensions/date.rb +4 -1
  69. data/lib/mongoid/extensions/decimal128.rb +3 -3
  70. data/lib/mongoid/extensions/hash.rb +1 -0
  71. data/lib/mongoid/extensions/regexp.rb +1 -0
  72. data/lib/mongoid/extensions/string.rb +6 -3
  73. data/lib/mongoid/extensions/time.rb +4 -1
  74. data/lib/mongoid/extensions.rb +0 -4
  75. data/lib/mongoid/factory.rb +2 -1
  76. data/lib/mongoid/fields/validators/macro.rb +18 -0
  77. data/lib/mongoid/findable.rb +2 -2
  78. data/lib/mongoid/indexable.rb +16 -14
  79. data/lib/mongoid/interceptable.rb +9 -22
  80. data/lib/mongoid/matchable/all.rb +2 -2
  81. data/lib/mongoid/matchable/and.rb +3 -3
  82. data/lib/mongoid/matchable/default.rb +2 -2
  83. data/lib/mongoid/matchable/elem_match.rb +28 -0
  84. data/lib/mongoid/matchable/exists.rb +2 -2
  85. data/lib/mongoid/matchable/gt.rb +4 -2
  86. data/lib/mongoid/matchable/gte.rb +4 -2
  87. data/lib/mongoid/matchable/in.rb +2 -2
  88. data/lib/mongoid/matchable/lt.rb +4 -2
  89. data/lib/mongoid/matchable/lte.rb +4 -2
  90. data/lib/mongoid/matchable/ne.rb +2 -2
  91. data/lib/mongoid/matchable/nin.rb +2 -2
  92. data/lib/mongoid/matchable/nor.rb +37 -0
  93. data/lib/mongoid/matchable/or.rb +3 -3
  94. data/lib/mongoid/matchable/regexp.rb +3 -3
  95. data/lib/mongoid/matchable/size.rb +2 -2
  96. data/lib/mongoid/matchable.rb +16 -7
  97. data/lib/mongoid/persistable/creatable.rb +5 -3
  98. data/lib/mongoid/persistable/deletable.rb +5 -3
  99. data/lib/mongoid/persistable/destroyable.rb +1 -5
  100. data/lib/mongoid/persistable/settable.rb +5 -5
  101. data/lib/mongoid/persistable/updatable.rb +7 -14
  102. data/lib/mongoid/persistable/upsertable.rb +2 -1
  103. data/lib/mongoid/persistable.rb +4 -6
  104. data/lib/mongoid/persistence_context.rb +220 -0
  105. data/lib/mongoid/query_cache.rb +67 -23
  106. data/lib/mongoid/railtie.rb +17 -1
  107. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  108. data/lib/mongoid/relations/accessors.rb +3 -0
  109. data/lib/mongoid/relations/auto_save.rb +12 -4
  110. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  111. data/lib/mongoid/relations/counter_cache.rb +15 -5
  112. data/lib/mongoid/relations/eager/base.rb +3 -3
  113. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  114. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  115. data/lib/mongoid/relations/eager.rb +6 -11
  116. data/lib/mongoid/relations/embedded/batchable.rb +20 -18
  117. data/lib/mongoid/relations/embedded/in.rb +13 -1
  118. data/lib/mongoid/relations/embedded/many.rb +51 -10
  119. data/lib/mongoid/relations/embedded/one.rb +14 -1
  120. data/lib/mongoid/relations/macros.rb +9 -1
  121. data/lib/mongoid/relations/many.rb +4 -0
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/options.rb +2 -2
  124. data/lib/mongoid/relations/proxy.rb +1 -31
  125. data/lib/mongoid/relations/referenced/in.rb +19 -10
  126. data/lib/mongoid/relations/referenced/many.rb +30 -26
  127. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  128. data/lib/mongoid/relations/referenced/one.rb +15 -1
  129. data/lib/mongoid/relations/synchronization.rb +12 -12
  130. data/lib/mongoid/relations/targets/enumerable.rb +24 -4
  131. data/lib/mongoid/relations/touchable.rb +7 -4
  132. data/lib/mongoid/reloadable.rb +2 -2
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +1 -1
  135. data/lib/mongoid/stateful.rb +1 -0
  136. data/lib/mongoid/tasks/database.rb +3 -2
  137. data/lib/mongoid/threaded.rb +74 -0
  138. data/lib/mongoid/traversable.rb +1 -1
  139. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  140. data/lib/mongoid/version.rb +1 -1
  141. data/lib/mongoid.rb +6 -6
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
  143. data/spec/app/models/agent.rb +2 -0
  144. data/spec/app/models/album.rb +5 -1
  145. data/spec/app/models/array_field.rb +7 -0
  146. data/spec/app/models/artist.rb +21 -0
  147. data/spec/app/models/band.rb +3 -0
  148. data/spec/app/models/book.rb +2 -1
  149. data/spec/app/models/delegating_patient.rb +16 -0
  150. data/spec/app/models/dokument.rb +1 -0
  151. data/spec/app/models/ordered_post.rb +5 -0
  152. data/spec/app/models/oscar.rb +1 -2
  153. data/spec/app/models/page.rb +1 -1
  154. data/spec/app/models/person.rb +3 -3
  155. data/spec/app/models/princess.rb +2 -0
  156. data/spec/app/models/record.rb +1 -0
  157. data/spec/app/models/subscription.rb +1 -0
  158. data/spec/app/models/thing.rb +1 -1
  159. data/spec/config/mongoid.yml +15 -0
  160. data/spec/integration/document_spec.rb +22 -0
  161. data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
  162. data/spec/mongoid/atomic_spec.rb +5 -5
  163. data/spec/mongoid/attributes/nested_spec.rb +18 -14
  164. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  165. data/spec/mongoid/attributes_spec.rb +90 -5
  166. data/spec/mongoid/cacheable_spec.rb +112 -0
  167. data/spec/mongoid/changeable_spec.rb +58 -0
  168. data/spec/mongoid/clients/factory_spec.rb +80 -28
  169. data/spec/mongoid/clients/options_spec.rb +396 -95
  170. data/spec/mongoid/clients/sessions_spec.rb +334 -0
  171. data/spec/mongoid/clients_spec.rb +243 -101
  172. data/spec/mongoid/composable_spec.rb +7 -0
  173. data/spec/mongoid/config_spec.rb +67 -11
  174. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  175. data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
  176. data/spec/mongoid/contextual/mongo_spec.rb +275 -22
  177. data/spec/mongoid/contextual/none_spec.rb +15 -0
  178. data/spec/mongoid/copyable_spec.rb +13 -4
  179. data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
  180. data/spec/mongoid/criteria/options_spec.rb +29 -0
  181. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  182. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  183. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  184. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  185. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  186. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  187. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  189. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  190. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  191. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  192. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  193. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  194. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  195. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  196. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  197. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  198. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  199. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  200. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  201. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  202. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  203. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  204. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  205. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  206. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  207. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  208. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  209. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
  210. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  211. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  212. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  213. data/spec/mongoid/criteria_spec.rb +156 -22
  214. data/spec/mongoid/document_spec.rb +100 -90
  215. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  216. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  217. data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
  218. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  219. data/spec/mongoid/extensions/date_spec.rb +2 -6
  220. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  221. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  222. data/spec/mongoid/extensions/float_spec.rb +8 -1
  223. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  224. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  225. data/spec/mongoid/extensions/object_spec.rb +11 -0
  226. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  227. data/spec/mongoid/extensions/string_spec.rb +53 -4
  228. data/spec/mongoid/extensions/time_spec.rb +2 -6
  229. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  230. data/spec/mongoid/factory_spec.rb +11 -0
  231. data/spec/mongoid/fields_spec.rb +1 -1
  232. data/spec/mongoid/findable_spec.rb +47 -2
  233. data/spec/mongoid/indexable_spec.rb +15 -3
  234. data/spec/mongoid/interceptable_spec.rb +85 -19
  235. data/spec/mongoid/matchable/all_spec.rb +4 -4
  236. data/spec/mongoid/matchable/and_spec.rb +10 -10
  237. data/spec/mongoid/matchable/default_spec.rb +12 -12
  238. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  239. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  240. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  241. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  242. data/spec/mongoid/matchable/in_spec.rb +5 -5
  243. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  244. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  245. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  246. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  247. data/spec/mongoid/matchable/nor_spec.rb +209 -0
  248. data/spec/mongoid/matchable/or_spec.rb +7 -7
  249. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  250. data/spec/mongoid/matchable/size_spec.rb +3 -3
  251. data/spec/mongoid/matchable_spec.rb +199 -54
  252. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  253. data/spec/mongoid/persistable/deletable_spec.rb +35 -1
  254. data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
  255. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  256. data/spec/mongoid/persistable/savable_spec.rb +34 -29
  257. data/spec/mongoid/persistable/settable_spec.rb +77 -27
  258. data/spec/mongoid/persistable/updatable_spec.rb +182 -3
  259. data/spec/mongoid/persistable_spec.rb +16 -16
  260. data/spec/mongoid/persistence_context_spec.rb +694 -0
  261. data/spec/mongoid/positional_spec.rb +1 -1
  262. data/spec/mongoid/query_cache_spec.rb +170 -12
  263. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  264. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  265. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  266. data/spec/mongoid/relations/builders_spec.rb +37 -10
  267. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  268. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  269. data/spec/mongoid/relations/eager_spec.rb +40 -0
  270. data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
  271. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  272. data/spec/mongoid/relations/macros_spec.rb +415 -7
  273. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  274. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  275. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  276. data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
  277. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  278. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  279. data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
  280. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  281. data/spec/mongoid/reloadable_spec.rb +51 -0
  282. data/spec/mongoid/scopable_spec.rb +13 -0
  283. data/spec/mongoid/serializable_spec.rb +0 -50
  284. data/spec/mongoid/threaded_spec.rb +68 -0
  285. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  286. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  287. data/spec/mongoid/validatable_spec.rb +16 -0
  288. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  289. data/spec/spec_helper.rb +101 -8
  290. data/spec/support/cluster_config.rb +158 -0
  291. data/spec/support/constraints.rb +101 -0
  292. data/spec/support/macros.rb +20 -0
  293. data/spec/support/session_registry.rb +50 -0
  294. data/spec/support/spec_config.rb +42 -0
  295. data.tar.gz.sig +0 -0
  296. metadata +163 -61
  297. metadata.gz.sig +0 -0
  298. data/lib/mongoid/clients/thread_options.rb +0 -19
  299. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  300. data/lib/mongoid/railties/document.rb +0 -12
  301. data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -538,6 +538,135 @@ describe Mongoid::Criteria::Modifiable do
538
538
  it "sets the additional attributes" do
539
539
  expect(document.origin).to eq("Essex")
540
540
  end
541
+
542
+ context 'when attributes contain keys also in the criteria selector' do
543
+
544
+ context 'when the selector has symbol keys' do
545
+
546
+ context 'when the attributes use symbol keys' do
547
+
548
+ let(:document) do
549
+ Band.where(name: 'Tool').first_or_create(name: 'Essex')
550
+ end
551
+
552
+ it 'uses the values from the attributes' do
553
+ expect(document.name).to eq('Essex')
554
+ end
555
+ end
556
+
557
+ context 'when the attributes use string keys' do
558
+
559
+ let(:document) do
560
+ Band.where(name: 'Tool').first_or_create('name' => 'Essex')
561
+ end
562
+
563
+ it 'uses the values from the attributes' do
564
+ expect(document.name).to eq('Essex')
565
+ end
566
+ end
567
+ end
568
+
569
+ context 'when the selector has string keys' do
570
+
571
+ context 'when the attributes use symbol keys' do
572
+
573
+ let(:document) do
574
+ Band.where('name' => 'Tool').first_or_create(name: 'Essex')
575
+ end
576
+
577
+ it 'uses the values from the attributes' do
578
+ expect(document.name).to eq('Essex')
579
+ end
580
+ end
581
+
582
+ context 'when the attributes use string keys' do
583
+
584
+ let(:document) do
585
+ Band.where('name' => 'Tool').first_or_create('name' => 'Essex')
586
+ end
587
+
588
+ it 'uses the values from the attributes' do
589
+ expect(document.name).to eq('Essex')
590
+ end
591
+ end
592
+ end
593
+ end
594
+
595
+ context 'when the query criteria is on a hash attribute' do
596
+
597
+ let(:document) do
598
+ Person.where(map: { foo: :bar }).first_or_create
599
+ end
600
+
601
+ it 'uses the values from the attributes' do
602
+ expect(document.map).to eq({ foo: :bar })
603
+ end
604
+ end
605
+
606
+ context 'when the criteria has a selector with query operators' do
607
+
608
+ let(:document) do
609
+ Band.in(genres: ['Hiphop', 'Soul']).first_or_create(name: 'Smooth')
610
+ end
611
+
612
+ it 'does not create a document with the query operators' do
613
+ expect(document.attributes.keys).not_to include('genres')
614
+ end
615
+ end
616
+
617
+ context 'when the criteria has a nested selector with query operators' do
618
+
619
+ let(:band) do
620
+ record = Record.new(producers: ['testing'])
621
+ band = Band.create(records: [record])
622
+ end
623
+
624
+ let(:document) do
625
+ band.records.in(producers: ['nonexistent']).first_or_create(name: 'new-embedded-doc')
626
+ band.reload
627
+ end
628
+
629
+ it 'creates a new embedded document' do
630
+ expect(document.records.size).to eq(2)
631
+ end
632
+
633
+ it 'does not alter the existing embedded document' do
634
+ expect(document.records[0].producers).to eq(['testing'])
635
+ end
636
+
637
+ it 'does not create a document with the query operators as attributes' do
638
+ expect(document.records[1].producers).to be_nil
639
+ end
640
+
641
+ it 'applies the attribute to the new embedded document' do
642
+ expect(document.records[1].name).to eq('new-embedded-doc')
643
+ end
644
+ end
645
+
646
+ context 'when the criteria has a deeply-nested selector with query operators' do
647
+
648
+ let(:criteria) do
649
+ band = Band.create
650
+ Mongoid::Criteria.new(Record) do |criteria|
651
+ criteria.embedded = true
652
+ criteria.metadata = Band.reflect_on_association(:records)
653
+ criteria.parent_document = band
654
+ criteria.selector = { "records" => { "producers"=>{"$in"=>["nonexistent"] } } }
655
+ end
656
+ end
657
+
658
+ let(:document) do
659
+ criteria.first_or_create(name: 'new-record')
660
+ end
661
+
662
+ it 'does not create a document with the query operators' do
663
+ expect(document.attributes.keys).not_to include('producers')
664
+ end
665
+
666
+ it 'applies the attribute to the new embedded document' do
667
+ expect(document.name).to eq('new-record')
668
+ end
669
+ end
541
670
  end
542
671
 
543
672
  context "when attributes are not provided" do
@@ -736,6 +865,59 @@ describe Mongoid::Criteria::Modifiable do
736
865
  end
737
866
  end
738
867
  end
868
+
869
+ context 'when attributes contain keys also in the criteria selector' do
870
+
871
+ context 'when the selector has symbol keys' do
872
+
873
+ context 'when the attributes use symbol keys' do
874
+
875
+ let(:document) do
876
+ Band.where(name: 'Tool').first_or_create!(name: 'Essex')
877
+ end
878
+
879
+ it 'uses the values from the attributes' do
880
+ expect(document.name).to eq('Essex')
881
+ end
882
+ end
883
+
884
+ context 'when the attributes use string keys' do
885
+
886
+ let(:document) do
887
+ Band.where(name: 'Tool').first_or_create!('name' => 'Essex')
888
+ end
889
+
890
+ it 'uses the values from the attributes' do
891
+ expect(document.name).to eq('Essex')
892
+ end
893
+ end
894
+ end
895
+
896
+ context 'when the selector has string keys' do
897
+
898
+ context 'when the attributes use symbol keys' do
899
+
900
+ let(:document) do
901
+ Band.where('name' => 'Tool').first_or_create!(name: 'Essex')
902
+ end
903
+
904
+ it 'uses the values from the attributes' do
905
+ expect(document.name).to eq('Essex')
906
+ end
907
+ end
908
+
909
+ context 'when the attributes use string keys' do
910
+
911
+ let(:document) do
912
+ Band.where('name' => 'Tool').first_or_create!('name' => 'Essex')
913
+ end
914
+
915
+ it 'uses the values from the attributes' do
916
+ expect(document.name).to eq('Essex')
917
+ end
918
+ end
919
+ end
920
+ end
739
921
  end
740
922
  end
741
923
 
@@ -830,6 +1012,59 @@ describe Mongoid::Criteria::Modifiable do
830
1012
  end
831
1013
  end
832
1014
  end
1015
+
1016
+ context 'when attributes contain keys also in the criteria selector' do
1017
+
1018
+ context 'when the selector has symbol keys' do
1019
+
1020
+ context 'when the attributes use symbol keys' do
1021
+
1022
+ let(:document) do
1023
+ Band.where(name: 'Tool').first_or_initialize(name: 'Essex')
1024
+ end
1025
+
1026
+ it 'uses the values from the attributes' do
1027
+ expect(document.name).to eq('Essex')
1028
+ end
1029
+ end
1030
+
1031
+ context 'when the attributes use string keys' do
1032
+
1033
+ let(:document) do
1034
+ Band.where(name: 'Tool').first_or_initialize('name' => 'Essex')
1035
+ end
1036
+
1037
+ it 'uses the values from the attributes' do
1038
+ expect(document.name).to eq('Essex')
1039
+ end
1040
+ end
1041
+ end
1042
+
1043
+ context 'when the selector has string keys' do
1044
+
1045
+ context 'when the attributes use symbol keys' do
1046
+
1047
+ let(:document) do
1048
+ Band.where('name' => 'Tool').first_or_initialize(name: 'Essex')
1049
+ end
1050
+
1051
+ it 'uses the values from the attributes' do
1052
+ expect(document.name).to eq('Essex')
1053
+ end
1054
+ end
1055
+
1056
+ context 'when the attributes use string keys' do
1057
+
1058
+ let(:document) do
1059
+ Band.where('name' => 'Tool').first_or_initialize('name' => 'Essex')
1060
+ end
1061
+
1062
+ it 'uses the values from the attributes' do
1063
+ expect(document.name).to eq('Essex')
1064
+ end
1065
+ end
1066
+ end
1067
+ end
833
1068
  end
834
1069
  end
835
1070
 
@@ -1236,11 +1471,15 @@ describe Mongoid::Criteria::Modifiable do
1236
1471
  { 'username' => 'Turnip' }
1237
1472
  end
1238
1473
 
1239
- it 'returns a criteria with the defined attributes' do
1240
- expect(Person.create_with(attrs).selector).to eq(attrs)
1474
+ it 'does not modify the selector' do
1475
+ expect(Person.create_with(attrs).selector[:username]).to be_nil
1241
1476
  end
1242
1477
 
1243
- context 'when a method is chained' do
1478
+ it 'create_attrs is modified' do
1479
+ expect(Person.create_with(attrs).create_attrs).to eq(attrs)
1480
+ end
1481
+
1482
+ context 'when a create is chained' do
1244
1483
 
1245
1484
  context 'when a write method is chained' do
1246
1485
 
@@ -1264,6 +1503,25 @@ describe Mongoid::Criteria::Modifiable do
1264
1503
  expect(new_person.age).to eq(50)
1265
1504
  end
1266
1505
 
1506
+ context 'when a matching document is already in the collection' do
1507
+ let(:query) do
1508
+ { 'username' => 'foo', 'age' => 12 }
1509
+ end
1510
+
1511
+ let(:person) do
1512
+ Person.create!(query)
1513
+ end
1514
+
1515
+ let(:found_person) do
1516
+ Person.create_with(attrs).find_or_create_by(query)
1517
+ end
1518
+
1519
+ it 'finds the matching document' do
1520
+ person
1521
+ expect(found_person.id).to eq(person.id)
1522
+ end
1523
+ end
1524
+
1267
1525
  context 'when the attributes are shared with the write method args' do
1268
1526
 
1269
1527
  let(:query) do
@@ -1274,9 +1532,8 @@ describe Mongoid::Criteria::Modifiable do
1274
1532
  Person.create_with(attrs).find_or_create_by(query)
1275
1533
  end
1276
1534
 
1277
- it 'gives the write method args precedence' do
1278
- # @todo: uncomment when MONGOID-4193 is closed
1279
- #expect(new_person.username).to eq('Beet')
1535
+ it 'gives the find method args precedence' do
1536
+ expect(new_person.username).to eq('Beet')
1280
1537
  expect(new_person.age).to eq(50)
1281
1538
  end
1282
1539
  end
@@ -1302,8 +1559,12 @@ describe Mongoid::Criteria::Modifiable do
1302
1559
  { 'username' => 'Beet', 'age' => 50 }
1303
1560
  end
1304
1561
 
1562
+ it 'does not modify the selector' do
1563
+ expect(criteria.create_with(attrs).selector).to eq(criteria_selector)
1564
+ end
1565
+
1305
1566
  it 'overwrites all the original attributes' do
1306
- expect(criteria.create_with(attrs).selector).to eq(attrs)
1567
+ expect(criteria.create_with(attrs).create_attrs).to eq(attrs)
1307
1568
  end
1308
1569
  end
1309
1570
  end
@@ -1314,8 +1575,12 @@ describe Mongoid::Criteria::Modifiable do
1314
1575
  { 'username' => 'Beet' }
1315
1576
  end
1316
1577
 
1578
+ it 'does not modify the selector' do
1579
+ expect(criteria.create_with(attrs).selector).to eq(criteria_selector)
1580
+ end
1581
+
1317
1582
  it 'only overwrites the shared attributes' do
1318
- expect(criteria.create_with(attrs).selector).to eq(criteria_selector.merge!(attrs))
1583
+ expect(criteria.create_with(attrs).create_attrs).to eq(attrs)
1319
1584
  end
1320
1585
  end
1321
1586
 
@@ -1324,16 +1589,14 @@ describe Mongoid::Criteria::Modifiable do
1324
1589
  let(:attrs) do
1325
1590
  { 'username' => 'Turnip' }
1326
1591
  end
1327
-
1328
1592
  let(:query) do
1329
1593
  { 'username' => 'Beet', 'age' => 50 }
1330
1594
  end
1331
1595
 
1332
- context 'when a write method is chained' do
1596
+ context 'when a create method is chained' do
1333
1597
 
1334
1598
  it 'executes the method' do
1335
- # @todo: uncomment when MONGOID-4193 is closed
1336
- #expect(criteria.create_with(attrs).new.username).to eq('Beet')
1599
+ expect(criteria.create_with(attrs).new.username).to eq('Turnip')
1337
1600
  expect(criteria.create_with(attrs).new.age).to eq(25)
1338
1601
  end
1339
1602
  end
@@ -1344,10 +1607,28 @@ describe Mongoid::Criteria::Modifiable do
1344
1607
  criteria.create_with(attrs).find_or_create_by(query)
1345
1608
  end
1346
1609
 
1347
- it 'executes the query' do
1348
- # @todo: uncomment when MONGOID-4193 is closed
1349
- #expect(new_person.username).to eq('Beet')
1350
- #expect(new_person.age).to eq(50)
1610
+ it 'gives the find method arg precedence' do
1611
+ expect(new_person.username).to eq('Beet')
1612
+ expect(new_person.age).to be(50)
1613
+ end
1614
+
1615
+ context 'when a matching document is already in the collection' do
1616
+ let(:query) do
1617
+ { 'username' => 'foo', 'age' => 12 }
1618
+ end
1619
+
1620
+ let(:person) do
1621
+ Person.create!(query)
1622
+ end
1623
+
1624
+ let(:found_person) do
1625
+ criteria.create_with(attrs).find_or_create_by(query)
1626
+ end
1627
+
1628
+ it 'finds the matching document' do
1629
+ person
1630
+ expect(found_person.id).to eq(person.id)
1631
+ end
1351
1632
  end
1352
1633
  end
1353
1634
  end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Options do
4
+
5
+
6
+ context 'when a persistence context with options is set on the class of the criteria' do
7
+
8
+ let(:context) do
9
+ Band.with(connect_timeout: 10) do |klass|
10
+ klass.where(name: 'FKA Twigs').persistence_context
11
+ end
12
+ end
13
+
14
+ it 'uses the persistence context of the class of the criteria' do
15
+ expect(context.options).to eq({ connect_timeout: 10 })
16
+ end
17
+ end
18
+
19
+ context 'when a persistence context with options is not set on the class of the criteria' do
20
+
21
+ let(:context) do
22
+ Band.where(name: 'FKA Twigs').persistence_context
23
+ end
24
+
25
+ it 'uses the persistence context of the class of the criteria' do
26
+ expect(context.options).to eq({ })
27
+ end
28
+ end
29
+ end