mongoid 8.0.8 → 8.1.0

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 (181) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/Rakefile +0 -25
  6. data/lib/config/locales/en.yml +46 -14
  7. data/lib/mongoid/association/accessors.rb +2 -2
  8. data/lib/mongoid/association/builders.rb +1 -1
  9. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  10. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  11. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  13. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
  14. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  15. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  16. data/lib/mongoid/association/macros.rb +0 -6
  17. data/lib/mongoid/association/nested/one.rb +40 -2
  18. data/lib/mongoid/association/proxy.rb +1 -1
  19. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  20. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
  21. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
  22. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  23. data/lib/mongoid/association/reflections.rb +2 -2
  24. data/lib/mongoid/atomic.rb +7 -16
  25. data/lib/mongoid/attributes/dynamic.rb +1 -1
  26. data/lib/mongoid/attributes/nested.rb +2 -2
  27. data/lib/mongoid/attributes/processing.rb +5 -29
  28. data/lib/mongoid/attributes/projector.rb +1 -1
  29. data/lib/mongoid/attributes/readonly.rb +1 -1
  30. data/lib/mongoid/attributes.rb +8 -2
  31. data/lib/mongoid/changeable.rb +107 -5
  32. data/lib/mongoid/clients/storage_options.rb +2 -5
  33. data/lib/mongoid/clients/validators/storage.rb +1 -13
  34. data/lib/mongoid/collection_configurable.rb +58 -0
  35. data/lib/mongoid/composable.rb +2 -0
  36. data/lib/mongoid/config/defaults.rb +60 -0
  37. data/lib/mongoid/config/options.rb +0 -3
  38. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  39. data/lib/mongoid/config/validators.rb +1 -0
  40. data/lib/mongoid/config.rb +99 -28
  41. data/lib/mongoid/contextual/atomic.rb +1 -1
  42. data/lib/mongoid/contextual/memory.rb +233 -33
  43. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  44. data/lib/mongoid/contextual/mongo.rb +370 -133
  45. data/lib/mongoid/contextual/none.rb +162 -7
  46. data/lib/mongoid/contextual.rb +12 -0
  47. data/lib/mongoid/criteria/findable.rb +2 -2
  48. data/lib/mongoid/criteria/includable.rb +4 -3
  49. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  50. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  51. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  52. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  53. data/lib/mongoid/criteria/queryable/selector.rb +1 -1
  54. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  55. data/lib/mongoid/criteria.rb +6 -5
  56. data/lib/mongoid/deprecable.rb +1 -2
  57. data/lib/mongoid/deprecation.rb +3 -3
  58. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  59. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  60. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  61. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  62. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  63. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  64. data/lib/mongoid/errors.rb +4 -1
  65. data/lib/mongoid/extensions/hash.rb +2 -24
  66. data/lib/mongoid/extensions/object.rb +2 -2
  67. data/lib/mongoid/extensions/time.rb +2 -0
  68. data/lib/mongoid/fields/localized.rb +10 -0
  69. data/lib/mongoid/fields/standard.rb +10 -0
  70. data/lib/mongoid/fields.rb +53 -24
  71. data/lib/mongoid/findable.rb +27 -3
  72. data/lib/mongoid/interceptable.rb +10 -118
  73. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  74. data/lib/mongoid/matcher/type.rb +1 -1
  75. data/lib/mongoid/persistable/creatable.rb +1 -0
  76. data/lib/mongoid/persistable/deletable.rb +1 -1
  77. data/lib/mongoid/persistable/savable.rb +13 -1
  78. data/lib/mongoid/persistable/unsettable.rb +2 -2
  79. data/lib/mongoid/persistable/updatable.rb +51 -1
  80. data/lib/mongoid/persistable/upsertable.rb +20 -1
  81. data/lib/mongoid/persistable.rb +3 -0
  82. data/lib/mongoid/query_cache.rb +5 -1
  83. data/lib/mongoid/railties/database.rake +7 -2
  84. data/lib/mongoid/reloadable.rb +5 -3
  85. data/lib/mongoid/stateful.rb +22 -1
  86. data/lib/mongoid/tasks/database.rake +12 -0
  87. data/lib/mongoid/tasks/database.rb +20 -0
  88. data/lib/mongoid/utils.rb +22 -0
  89. data/lib/mongoid/validatable/associated.rb +18 -96
  90. data/lib/mongoid/validatable/macros.rb +5 -5
  91. data/lib/mongoid/validatable.rb +4 -9
  92. data/lib/mongoid/version.rb +1 -1
  93. data/lib/mongoid/warnings.rb +17 -1
  94. data/lib/mongoid.rb +16 -3
  95. data/spec/integration/app_spec.rb +2 -2
  96. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -40
  97. data/spec/integration/callbacks_models.rb +37 -0
  98. data/spec/integration/callbacks_spec.rb +126 -12
  99. data/spec/integration/discriminator_key_spec.rb +4 -5
  100. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  101. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  102. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
  103. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  104. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  105. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  106. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +5 -27
  107. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
  108. data/spec/mongoid/association/syncable_spec.rb +1 -1
  109. data/spec/mongoid/attributes_spec.rb +3 -33
  110. data/spec/mongoid/changeable_spec.rb +299 -24
  111. data/spec/mongoid/clients_spec.rb +122 -13
  112. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  113. data/spec/mongoid/config/defaults_spec.rb +160 -0
  114. data/spec/mongoid/config_spec.rb +154 -27
  115. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  116. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  117. data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
  118. data/spec/mongoid/contextual/none_spec.rb +49 -2
  119. data/spec/mongoid/copyable_spec.rb +2 -10
  120. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
  121. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  122. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  123. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  124. data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
  125. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  126. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  127. data/spec/mongoid/criteria_spec.rb +5 -9
  128. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  129. data/spec/mongoid/extensions/hash_spec.rb +3 -3
  130. data/spec/mongoid/extensions/time_spec.rb +8 -43
  131. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  132. data/spec/mongoid/fields/localized_spec.rb +46 -28
  133. data/spec/mongoid/fields_spec.rb +136 -77
  134. data/spec/mongoid/findable_spec.rb +391 -34
  135. data/spec/mongoid/indexable_spec.rb +16 -10
  136. data/spec/mongoid/interceptable_spec.rb +173 -362
  137. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  138. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  139. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  140. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  141. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  142. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  143. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  144. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  145. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  146. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  147. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  148. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  149. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  150. data/spec/mongoid/persistence_context_spec.rb +7 -57
  151. data/spec/mongoid/query_cache_spec.rb +56 -61
  152. data/spec/mongoid/reloadable_spec.rb +24 -28
  153. data/spec/mongoid/scopable_spec.rb +70 -0
  154. data/spec/mongoid/serializable_spec.rb +9 -30
  155. data/spec/mongoid/stateful_spec.rb +122 -8
  156. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  157. data/spec/mongoid/tasks/database_spec.rb +127 -0
  158. data/spec/mongoid/timestamps_spec.rb +9 -11
  159. data/spec/mongoid/touchable_spec.rb +277 -5
  160. data/spec/mongoid/touchable_spec_models.rb +3 -1
  161. data/spec/mongoid/traversable_spec.rb +9 -24
  162. data/spec/mongoid/validatable/associated_spec.rb +30 -13
  163. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  164. data/spec/mongoid_spec.rb +36 -10
  165. data/spec/spec_helper.rb +5 -0
  166. data/spec/support/immutable_ids.rb +118 -0
  167. data/spec/support/macros.rb +47 -15
  168. data/spec/support/models/artist.rb +0 -1
  169. data/spec/support/models/band.rb +1 -0
  170. data/spec/support/models/book.rb +1 -0
  171. data/spec/support/models/building.rb +2 -0
  172. data/spec/support/models/cover.rb +10 -0
  173. data/spec/support/models/name.rb +0 -10
  174. data/spec/support/models/person.rb +0 -1
  175. data/spec/support/models/product.rb +1 -0
  176. data.tar.gz.sig +0 -0
  177. metadata +698 -664
  178. metadata.gz.sig +0 -0
  179. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  180. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  181. data/spec/support/models/purse.rb +0 -9
data/lib/mongoid.rb CHANGED
@@ -12,8 +12,10 @@ require "active_support/inflector"
12
12
  require "active_support/time_with_zone"
13
13
  require "active_model"
14
14
 
15
+ require 'concurrent-ruby'
16
+
15
17
  require "mongo"
16
- require 'mongo/active_support'
18
+ require "mongo/active_support"
17
19
 
18
20
  require "mongoid/version"
19
21
  require "mongoid/deprecable"
@@ -25,6 +27,7 @@ require "mongoid/document"
25
27
  require "mongoid/tasks/database"
26
28
  require "mongoid/query_cache"
27
29
  require "mongoid/warnings"
30
+ require "mongoid/utils"
28
31
 
29
32
  # If we are using Rails then we will include the Mongoid railtie. This has all
30
33
  # the nifty initializers that Mongoid needs.
@@ -58,9 +61,19 @@ module Mongoid
58
61
  # }
59
62
  # end
60
63
  #
64
+ # @example Using a block without an argument. Use `config` inside
65
+ # the block to perform variable assignment.
66
+ #
67
+ # Mongoid.configure do
68
+ # connect_to("mongoid_test")
69
+ #
70
+ # config.preload_models = true
71
+ #
61
72
  # @return [ Config ] The configuration object.
62
- def configure
63
- block_given? ? yield(Config) : Config
73
+ def configure(&block)
74
+ return Config unless block_given?
75
+
76
+ block.arity == 0 ? Config.instance_exec(&block) : yield(Config)
64
77
  end
65
78
 
66
79
  # Convenience method for getting the default client.
@@ -326,7 +326,7 @@ describe 'Mongoid application tests' do
326
326
  end
327
327
 
328
328
  def wait_for_port(port, timeout, process)
329
- deadline = Time.now + timeout
329
+ deadline = Mongoid::Utils.monotonic_time + timeout
330
330
  loop do
331
331
  begin
332
332
  Socket.tcp('localhost', port, nil, nil, connect_timeout: 0.5) do |socket|
@@ -336,7 +336,7 @@ describe 'Mongoid application tests' do
336
336
  unless process.alive?
337
337
  raise "Process #{process} died while waiting for port #{port}"
338
338
  end
339
- if Time.now > deadline
339
+ if Mongoid::Utils.monotonic_time > deadline
340
340
  raise
341
341
  end
342
342
  end
@@ -2,28 +2,6 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- module HabtmSpec
6
- class Page
7
- include Mongoid::Document
8
- embeds_many :blocks, class_name: 'HabtmSpec::Block'
9
- end
10
-
11
- class Block
12
- include Mongoid::Document
13
- embedded_in :page, class_name: 'HabtmSpec::Page'
14
- end
15
-
16
- class ImageBlock < Block
17
- has_and_belongs_to_many :attachments, inverse_of: nil, class_name: 'HabtmSpec::Attachment'
18
- accepts_nested_attributes_for :attachments
19
- end
20
-
21
- class Attachment
22
- include Mongoid::Document
23
- field :file, type: String
24
- end
25
- end
26
-
27
5
  describe 'has_and_belongs_to_many associations' do
28
6
 
29
7
  context 'when an anonymous class defines a has_and_belongs_to_many association' do
@@ -40,22 +18,4 @@ describe 'has_and_belongs_to_many associations' do
40
18
  expect(klass.new.movies.build).to be_a Movie
41
19
  end
42
20
  end
43
-
44
- context 'when an embedded has habtm relation' do
45
- let(:attachment) { HabtmSpec::Attachment.create!(file: 'foo.jpg') }
46
-
47
- let(:page) { HabtmSpec::Page.create! }
48
-
49
- let(:image_block) do
50
- image_block = page.blocks.build({
51
- _type: 'HabtmSpec::ImageBlock',
52
- attachment_ids: [ attachment.id.to_s ],
53
- attachments_attributes: { '1234' => { file: 'bar.jpg', id: attachment.id.to_s } }
54
- })
55
- end
56
-
57
- it 'does not raise on save' do
58
- expect { image_block.save! }.not_to raise_error
59
- end
60
- end
61
21
  end
@@ -153,3 +153,40 @@ class Building
153
153
 
154
154
  has_and_belongs_to_many :architects, dependent: :nullify
155
155
  end
156
+
157
+ class Root
158
+ include Mongoid::Document
159
+ embeds_many :embedded_once, cascade_callbacks: true
160
+ after_save :trace
161
+
162
+ attr_accessor :logger
163
+
164
+ def trace
165
+ logger << :root
166
+ end
167
+ end
168
+
169
+ class EmbeddedOnce
170
+ include Mongoid::Document
171
+ embeds_many :embedded_twice, cascade_callbacks: true
172
+ embedded_in :root
173
+ after_save :trace
174
+
175
+ attr_accessor :logger
176
+
177
+ def trace
178
+ logger << :embedded_once
179
+ end
180
+ end
181
+
182
+ class EmbeddedTwice
183
+ include Mongoid::Document
184
+ embedded_in :embedded_once
185
+ after_save :trace
186
+
187
+ attr_accessor :logger
188
+
189
+ def trace
190
+ logger << :embedded_twice
191
+ end
192
+ end
@@ -448,23 +448,137 @@ describe 'callbacks integration tests' do
448
448
  end
449
449
  end
450
450
 
451
- context 'cascade callbacks' do
452
- ruby_version_gte '3.0'
453
- config_override :around_callbacks_for_embeds, false
451
+ context 'saved_change_to_attribute, attribute_before_last_save, will_save_change_to_attribute' do
452
+ class TestSCTAAndABLSInCallbacks
453
+ include Mongoid::Document
454
454
 
455
- let(:book) do
456
- Book.new
457
- end
455
+ field :name, type: String
456
+ field :age, type: Integer
458
457
 
459
- before do
460
- 1500.times do
461
- book.pages.build
458
+ set_callback :save, :before do |doc|
459
+ [:name, :age].each do |attr|
460
+ saved_change_to_attribute_values_before[attr] += [saved_change_to_attribute(attr)]
461
+ attribute_before_last_save_values_before[attr] += [attribute_before_last_save(attr)]
462
+ will_save_change_to_attribute_values_before[attr] += [will_save_change_to_attribute?(attr)]
463
+ end
464
+ end
465
+
466
+ set_callback :save, :after do |doc|
467
+ [:name, :age].each do |attr|
468
+ saved_change_to_attribute_values_after[attr] += [saved_change_to_attribute(attr)]
469
+ saved_change_to_attribute_q_values_after[attr] += [saved_change_to_attribute?(attr)]
470
+ attribute_before_last_save_values_after[attr] += [attribute_before_last_save(attr)]
471
+ end
472
+ end
473
+
474
+ def saved_change_to_attribute_values_before
475
+ @saved_change_to_attribute_values_before ||= Hash.new do
476
+ []
477
+ end
478
+ end
479
+
480
+ def attribute_before_last_save_values_before
481
+ @attribute_before_last_save_values_before ||= Hash.new do
482
+ []
483
+ end
462
484
  end
485
+
486
+ def saved_change_to_attribute_values_after
487
+ @saved_change_to_attribute_values_after ||= Hash.new do
488
+ []
489
+ end
490
+ end
491
+
492
+ def saved_change_to_attribute_q_values_after
493
+ @saved_change_to_attribute_q_values_after ||= Hash.new do
494
+ []
495
+ end
496
+ end
497
+
498
+ def attribute_before_last_save_values_after
499
+ @attribute_before_last_save_values_after ||= Hash.new do
500
+ []
501
+ end
502
+ end
503
+
504
+ def will_save_change_to_attribute_values_before
505
+ @will_save_change_to_attribute_values_before ||= Hash.new do
506
+ []
507
+ end
508
+ end
509
+ end
510
+
511
+ it 'reproduces ActiveRecord::AttributeMethods::Dirty behavior' do
512
+ subject = TestSCTAAndABLSInCallbacks.new(name: 'Name 1')
513
+ subject.save!
514
+ subject.age = 18
515
+ subject.save!
516
+ subject.name = 'Name 2'
517
+ subject.save!
518
+
519
+ expect(subject.saved_change_to_attribute_values_before).to eq(
520
+ {
521
+ :name => [nil, [nil, "Name 1"], nil],
522
+ :age => [nil, nil, [nil, 18]],
523
+ }
524
+ )
525
+ expect(subject.saved_change_to_attribute_values_after).to eq(
526
+ {
527
+ :name => [[nil, "Name 1"], nil, ["Name 1", "Name 2"]],
528
+ :age => [nil, [nil, 18], nil],
529
+ }
530
+ )
531
+ expect(subject.saved_change_to_attribute_q_values_after).to eq(
532
+ {
533
+ :name => [true, false, true],
534
+ :age => [false, true, false],
535
+ }
536
+ )
537
+ expect(subject.attribute_before_last_save_values_before).to eq(
538
+ {
539
+ :name => [nil, nil, "Name 1"],
540
+ :age => [nil, nil, nil]
541
+ }
542
+ )
543
+ expect(subject.attribute_before_last_save_values_after).to eq(
544
+ {
545
+ :name => [nil, "Name 1", "Name 1"],
546
+ :age => [nil, nil, 18]
547
+ }
548
+ )
549
+ expect(subject.will_save_change_to_attribute_values_before).to eq(
550
+ {
551
+ :name => [true, false, true],
552
+ :age => [false, true, false]
553
+ }
554
+ )
555
+ end
556
+ end
557
+
558
+ context 'nested embedded documents' do
559
+ config_override :prevent_multiple_calls_of_embedded_callbacks, true
560
+
561
+ let(:logger) { Array.new }
562
+
563
+ let(:root) do
564
+ Root.new(
565
+ embedded_once: [
566
+ EmbeddedOnce.new(
567
+ embedded_twice: [EmbeddedTwice.new]
568
+ )
569
+ ]
570
+ )
571
+ end
572
+
573
+ before(:each) do
574
+ root.logger = logger
575
+ root.embedded_once.first.logger = logger
576
+ root.embedded_once.first.embedded_twice.first.logger = logger
463
577
  end
464
578
 
465
- # https://jira.mongodb.org/browse/MONGOID-5658
466
- it 'does not raise SystemStackError' do
467
- expect { book.save! }.not_to raise_error(SystemStackError)
579
+ it 'runs callbacks in the correct order' do
580
+ root.save!
581
+ expect(logger).to eq(%i[embedded_twice embedded_once root])
468
582
  end
469
583
  end
470
584
  end
@@ -81,8 +81,9 @@ describe "#discriminator_key" do
81
81
  end
82
82
 
83
83
  context "before class creation" do
84
+ config_override :discriminator_key, "test"
85
+
84
86
  before do
85
- Mongoid.discriminator_key = "test"
86
87
 
87
88
  class PreGlobalIntDiscriminatorParent
88
89
  include Mongoid::Document
@@ -93,7 +94,6 @@ describe "#discriminator_key" do
93
94
  end
94
95
 
95
96
  after do
96
- Mongoid.discriminator_key = "_type"
97
97
  Object.send(:remove_const, :PreGlobalIntDiscriminatorParent)
98
98
  Object.send(:remove_const, :PreGlobalIntDiscriminatorChild)
99
99
  end
@@ -336,9 +336,9 @@ describe "#discriminator_key" do
336
336
  end
337
337
 
338
338
  context "Example 3" do
339
- before do
340
- Mongoid.discriminator_key = "shape_type"
339
+ config_override :discriminator_key, "shape_type"
341
340
 
341
+ before do
342
342
  class Example3Shape
343
343
  include Mongoid::Document
344
344
  field :x, type: Integer
@@ -358,7 +358,6 @@ describe "#discriminator_key" do
358
358
  end
359
359
 
360
360
  after do
361
- Mongoid.discriminator_key = "_type"
362
361
  Object.send(:remove_const, :Example3Shape)
363
362
  Object.send(:remove_const, :Example3Circle)
364
363
  Object.send(:remove_const, :Example3Rectangle)
@@ -3,11 +3,12 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'i18n fallbacks' do
6
- with_i18n_fallbacks
6
+ require_fallbacks
7
7
 
8
8
  context 'when fallbacks are enabled with a locale list' do
9
+ with_default_i18n_configs
10
+
9
11
  before do
10
- I18n.default_locale = :en
11
12
  I18n.fallbacks[:de] = [ :en ]
12
13
  end
13
14
 
@@ -616,4 +616,31 @@ describe Mongoid::Association::Embedded::EmbeddedIn::Proxy do
616
616
  end
617
617
  end
618
618
  end
619
+
620
+ context "when assigning a hash" do
621
+ let(:building_address) { BuildingAddress.new }
622
+
623
+ before do
624
+ building_address.building = { name: "Chrysler" }
625
+ end
626
+
627
+ it "creates the objects correctly" do
628
+ expect(building_address.building).to be_a(Building)
629
+ expect(building_address.building.name).to eq("Chrysler")
630
+ end
631
+ end
632
+
633
+ context "when replacing an association with a hash" do
634
+ let(:building_address) { BuildingAddress.new }
635
+
636
+ before do
637
+ building_address.building = { name: "Chrysler" }
638
+ building_address.building = { name: "Empire State" }
639
+ end
640
+
641
+ it "creates the objects correctly" do
642
+ expect(building_address.building).to be_a(Building)
643
+ expect(building_address.building.name).to eq("Empire State")
644
+ end
645
+ end
619
646
  end
@@ -2357,10 +2357,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2357
2357
  context "when the id does not match" do
2358
2358
 
2359
2359
  context "when config set to raise error" do
2360
-
2361
- before do
2362
- Mongoid.raise_not_found_error = true
2363
- end
2360
+ config_override :raise_not_found_error, true
2364
2361
 
2365
2362
  it "raises an error" do
2366
2363
  expect {
@@ -2370,19 +2367,12 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2370
2367
  end
2371
2368
 
2372
2369
  context "when config set not to raise error" do
2370
+ config_override :raise_not_found_error, false
2373
2371
 
2374
2372
  let(:address) do
2375
2373
  person.addresses.find(BSON::ObjectId.new)
2376
2374
  end
2377
2375
 
2378
- before do
2379
- Mongoid.raise_not_found_error = false
2380
- end
2381
-
2382
- after do
2383
- Mongoid.raise_not_found_error = true
2384
- end
2385
-
2386
2376
  it "returns nil" do
2387
2377
  expect(address).to be_nil
2388
2378
  end
@@ -2406,10 +2396,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2406
2396
  context "when the ids do not match" do
2407
2397
 
2408
2398
  context "when config set to raise error" do
2409
-
2410
- before do
2411
- Mongoid.raise_not_found_error = true
2412
- end
2399
+ config_override :raise_not_found_error, true
2413
2400
 
2414
2401
  it "raises an error" do
2415
2402
  expect {
@@ -2419,19 +2406,12 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2419
2406
  end
2420
2407
 
2421
2408
  context "when config set not to raise error" do
2409
+ config_override :raise_not_found_error, false
2422
2410
 
2423
2411
  let(:addresses) do
2424
2412
  person.addresses.find([ BSON::ObjectId.new ])
2425
2413
  end
2426
2414
 
2427
- before do
2428
- Mongoid.raise_not_found_error = false
2429
- end
2430
-
2431
- after do
2432
- Mongoid.raise_not_found_error = true
2433
- end
2434
-
2435
2415
  it "returns an empty array" do
2436
2416
  expect(addresses).to be_empty
2437
2417
  end
@@ -4591,7 +4571,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4591
4571
  before do
4592
4572
  band.collection.
4593
4573
  find(_id: band.id).
4594
- update_one("$set" => { records: [{ name: "Moderat" }]})
4574
+ update_one("$set" => { records: [{ _id: BSON::ObjectId.new, name: "Moderat" }]})
4595
4575
  end
4596
4576
 
4597
4577
  context "when loading the documents" do
@@ -4865,4 +4845,19 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4865
4845
  expect(from_db.company_tags.size).to eq(2)
4866
4846
  end
4867
4847
  end
4848
+
4849
+ context "when assigning hashes" do
4850
+ let(:user) { EmmUser.create! }
4851
+
4852
+ before do
4853
+ user.orders = [ { sku: 1 }, { sku: 2 } ]
4854
+ end
4855
+
4856
+ it "creates the objects correctly" do
4857
+ expect(user.orders.first).to be_a(EmmOrder)
4858
+ expect(user.orders.last).to be_a(EmmOrder)
4859
+
4860
+ expect(user.orders.map(&:sku).sort).to eq([ 1, 2 ])
4861
+ end
4862
+ end
4868
4863
  end
@@ -100,6 +100,7 @@ end
100
100
  class EmmOrder
101
101
  include Mongoid::Document
102
102
 
103
+ field :sku
103
104
  field :amount, type: Integer
104
105
 
105
106
  embedded_in :user, class_name: 'EmmUser'
@@ -202,7 +202,7 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
202
202
  end
203
203
  end
204
204
  end
205
-
205
+
206
206
  context 'when the original document does not need to be unset because it will be replaced by the $set' do
207
207
 
208
208
  let!(:pet_owner) do
@@ -971,7 +971,7 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
971
971
  before do
972
972
  band.collection.
973
973
  find(_id: band.id).
974
- update_one("$set" => { label: { name: "Mute" }})
974
+ update_one("$set" => { label: { _id: BSON::ObjectId.new, name: "Mute" }})
975
975
  end
976
976
 
977
977
  context "when loading the documents" do
@@ -1022,4 +1022,17 @@ describe Mongoid::Association::Embedded::EmbedsOne::Proxy do
1022
1022
  expect(building.building_address).to be_a(BuildingAddress)
1023
1023
  end
1024
1024
  end
1025
+
1026
+ context "when assigning a hash" do
1027
+ let(:building) { Building.create! }
1028
+
1029
+ before do
1030
+ building.building_address = { city: "NYC" }
1031
+ end
1032
+
1033
+ it "creates the objects correctly" do
1034
+ expect(building.building_address).to be_a(BuildingAddress)
1035
+ expect(building.building_address.city).to eq("NYC")
1036
+ end
1037
+ end
1025
1038
  end
@@ -546,17 +546,7 @@ describe Mongoid::Association::Referenced::BelongsTo do
546
546
  end
547
547
 
548
548
  context 'when the global config option is true' do
549
-
550
- around(:example) do |example|
551
- original_config = Mongoid.belongs_to_required_by_default
552
- Mongoid.belongs_to_required_by_default = true
553
- example.run
554
- Mongoid.belongs_to_required_by_default = original_config
555
- end
556
-
557
- let!(:original_required_config) do
558
- Mongoid.belongs_to_required_by_default
559
- end
549
+ config_override :belongs_to_required_by_default, true
560
550
 
561
551
  context 'when the required option is true' do
562
552
 
@@ -684,13 +674,7 @@ describe Mongoid::Association::Referenced::BelongsTo do
684
674
  end
685
675
 
686
676
  context 'when the global config option is false' do
687
-
688
- around(:example) do |example|
689
- original_config = Mongoid.belongs_to_required_by_default
690
- Mongoid.belongs_to_required_by_default = false
691
- example.run
692
- Mongoid.belongs_to_required_by_default = original_config
693
- end
677
+ config_override :belongs_to_required_by_default, false
694
678
 
695
679
  context 'when the required option is true' do
696
680
 
@@ -4,14 +4,12 @@ require "spec_helper"
4
4
  require_relative "../has_and_belongs_to_many_models"
5
5
 
6
6
  describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
7
+ config_override :raise_not_found_error, true
7
8
 
8
9
  around(:each) do |example|
9
- original_raise_not_found_error = Mongoid.raise_not_found_error
10
10
  original_preferences_association = Person.relations["preferences"]
11
- Mongoid.raise_not_found_error = true
12
11
  Person.has_and_belongs_to_many :preferences, autosave: true
13
12
  example.run
14
- Mongoid.raise_not_found_error = original_raise_not_found_error
15
13
  Person.relations["preferences"] = original_preferences_association
16
14
  end
17
15
 
@@ -2469,10 +2467,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2469
2467
  context "when the id does not match" do
2470
2468
 
2471
2469
  context "when config set to raise error" do
2472
-
2473
- before do
2474
- Mongoid.raise_not_found_error = true
2475
- end
2470
+ config_override :raise_not_found_error, true
2476
2471
 
2477
2472
  it "raises an error" do
2478
2473
  expect {
@@ -2482,19 +2477,12 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2482
2477
  end
2483
2478
 
2484
2479
  context "when config set not to raise error" do
2480
+ config_override :raise_not_found_error, false
2485
2481
 
2486
2482
  let(:preference) do
2487
2483
  person.preferences.find(BSON::ObjectId.new)
2488
2484
  end
2489
2485
 
2490
- before do
2491
- Mongoid.raise_not_found_error = false
2492
- end
2493
-
2494
- after do
2495
- Mongoid.raise_not_found_error = true
2496
- end
2497
-
2498
2486
  it "returns nil" do
2499
2487
  expect(preference).to be_nil
2500
2488
  end
@@ -2533,10 +2521,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2533
2521
  context "when the ids do not match" do
2534
2522
 
2535
2523
  context "when config set to raise error" do
2536
-
2537
- before do
2538
- Mongoid.raise_not_found_error = true
2539
- end
2524
+ config_override :raise_not_found_error, true
2540
2525
 
2541
2526
  it "raises an error" do
2542
2527
  expect {
@@ -2546,19 +2531,12 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2546
2531
  end
2547
2532
 
2548
2533
  context "when config set not to raise error" do
2534
+ config_override :raise_not_found_error, false
2549
2535
 
2550
2536
  let(:preferences) do
2551
2537
  person.preferences.find([ BSON::ObjectId.new ])
2552
2538
  end
2553
2539
 
2554
- before do
2555
- Mongoid.raise_not_found_error = false
2556
- end
2557
-
2558
- after do
2559
- Mongoid.raise_not_found_error = true
2560
- end
2561
-
2562
2540
  it "returns an empty array" do
2563
2541
  expect(preferences).to be_empty
2564
2542
  end