mongoid 7.5.2 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +46 -30
  5. data/lib/mongoid/association/accessors.rb +32 -3
  6. data/lib/mongoid/association/bindable.rb +48 -0
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/eager_loadable.rb +29 -7
  9. data/lib/mongoid/association/embedded/batchable.rb +48 -8
  10. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  11. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  17. data/lib/mongoid/association/macros.rb +2 -1
  18. data/lib/mongoid/association/many.rb +5 -0
  19. data/lib/mongoid/association/nested/many.rb +2 -1
  20. data/lib/mongoid/association/proxy.rb +12 -0
  21. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  22. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  23. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  24. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  25. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  26. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  28. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  29. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  30. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  31. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  32. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  33. data/lib/mongoid/association/relatable.rb +38 -4
  34. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  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 -245
  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 +89 -4
  68. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  69. data/lib/mongoid/criteria/queryable.rb +11 -6
  70. data/lib/mongoid/criteria.rb +1 -28
  71. data/lib/mongoid/deprecable.rb +36 -0
  72. data/lib/mongoid/deprecation.rb +25 -0
  73. data/lib/mongoid/document.rb +88 -33
  74. data/lib/mongoid/equality.rb +4 -4
  75. data/lib/mongoid/errors/document_not_found.rb +6 -2
  76. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  77. data/lib/mongoid/errors/invalid_field.rb +5 -1
  78. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  79. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  80. data/lib/mongoid/errors.rb +2 -2
  81. data/lib/mongoid/extensions/array.rb +8 -6
  82. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  83. data/lib/mongoid/extensions/binary.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +8 -2
  85. data/lib/mongoid/extensions/date.rb +26 -20
  86. data/lib/mongoid/extensions/date_time.rb +1 -1
  87. data/lib/mongoid/extensions/float.rb +4 -5
  88. data/lib/mongoid/extensions/hash.rb +12 -5
  89. data/lib/mongoid/extensions/integer.rb +4 -5
  90. data/lib/mongoid/extensions/object.rb +2 -0
  91. data/lib/mongoid/extensions/range.rb +41 -10
  92. data/lib/mongoid/extensions/regexp.rb +11 -4
  93. data/lib/mongoid/extensions/set.rb +11 -4
  94. data/lib/mongoid/extensions/string.rb +2 -13
  95. data/lib/mongoid/extensions/symbol.rb +3 -14
  96. data/lib/mongoid/extensions/time.rb +27 -16
  97. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  98. data/lib/mongoid/extensions.rb +1 -0
  99. data/lib/mongoid/factory.rb +42 -7
  100. data/lib/mongoid/fields/foreign_key.rb +7 -0
  101. data/lib/mongoid/fields/validators/macro.rb +3 -9
  102. data/lib/mongoid/fields.rb +49 -7
  103. data/lib/mongoid/findable.rb +21 -16
  104. data/lib/mongoid/indexable/specification.rb +1 -1
  105. data/lib/mongoid/indexable/validators/options.rb +4 -1
  106. data/lib/mongoid/interceptable.rb +69 -9
  107. data/lib/mongoid/persistable/creatable.rb +14 -5
  108. data/lib/mongoid/persistable/updatable.rb +12 -5
  109. data/lib/mongoid/persistence_context.rb +8 -42
  110. data/lib/mongoid/query_cache.rb +6 -258
  111. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  112. data/lib/mongoid/reloadable.rb +7 -3
  113. data/lib/mongoid/scopable.rb +9 -11
  114. data/lib/mongoid/selectable.rb +1 -2
  115. data/lib/mongoid/stateful.rb +27 -1
  116. data/lib/mongoid/timestamps/created.rb +1 -1
  117. data/lib/mongoid/timestamps/updated.rb +1 -1
  118. data/lib/mongoid/touchable.rb +2 -3
  119. data/lib/mongoid/traversable.rb +1 -0
  120. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/warnings.rb +3 -4
  123. data/lib/mongoid.rb +1 -0
  124. data/spec/config/mongoid.yml +16 -0
  125. data/spec/integration/app_spec.rb +8 -12
  126. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  127. data/spec/integration/associations/embedded_spec.rb +15 -0
  128. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  129. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  130. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  131. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  132. data/spec/integration/associations/has_one_spec.rb +97 -1
  133. data/spec/integration/associations/scope_option_spec.rb +1 -1
  134. data/spec/integration/callbacks_models.rb +95 -1
  135. data/spec/integration/callbacks_spec.rb +226 -4
  136. data/spec/integration/criteria/range_spec.rb +95 -1
  137. data/spec/integration/discriminator_key_spec.rb +115 -76
  138. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  139. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  140. data/spec/integration/matcher_examples_spec.rb +20 -13
  141. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  142. data/spec/integration/matcher_operator_spec.rb +3 -5
  143. data/spec/integration/persistence/range_field_spec.rb +350 -0
  144. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  145. data/spec/mongoid/association/depending_spec.rb +9 -9
  146. data/spec/mongoid/association/eager_spec.rb +2 -1
  147. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  148. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  149. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  150. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  151. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  152. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  153. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  154. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  155. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  156. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  157. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  158. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  159. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  160. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  161. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  162. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  163. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +38 -5
  164. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  165. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  166. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  167. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  168. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +62 -13
  169. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  170. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  171. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  172. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  173. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  174. data/spec/mongoid/association/syncable_spec.rb +14 -0
  175. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  176. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  177. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  178. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  179. data/spec/mongoid/attributes_spec.rb +480 -27
  180. data/spec/mongoid/cacheable_spec.rb +3 -3
  181. data/spec/mongoid/changeable_spec.rb +130 -13
  182. data/spec/mongoid/clients/factory_spec.rb +23 -30
  183. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  184. data/spec/mongoid/clients_spec.rb +2 -2
  185. data/spec/mongoid/config_spec.rb +52 -14
  186. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  187. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  188. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  189. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  190. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  191. data/spec/mongoid/contextual/mongo_spec.rb +564 -394
  192. data/spec/mongoid/contextual/none_spec.rb +11 -19
  193. data/spec/mongoid/copyable_spec.rb +451 -1
  194. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  195. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  196. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  197. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  198. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  199. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  200. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  201. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  202. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  203. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  204. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  205. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  206. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  207. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  208. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  209. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  210. data/spec/mongoid/criteria_spec.rb +469 -1201
  211. data/spec/mongoid/document_fields_spec.rb +173 -24
  212. data/spec/mongoid/document_spec.rb +32 -41
  213. data/spec/mongoid/equality_spec.rb +12 -12
  214. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  215. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  216. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  217. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  218. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  219. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  220. data/spec/mongoid/extensions/array_spec.rb +16 -2
  221. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  222. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  223. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  224. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  225. data/spec/mongoid/extensions/date_spec.rb +71 -1
  226. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  227. data/spec/mongoid/extensions/float_spec.rb +48 -76
  228. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  229. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  230. data/spec/mongoid/extensions/range_spec.rb +255 -54
  231. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  232. data/spec/mongoid/extensions/set_spec.rb +106 -0
  233. data/spec/mongoid/extensions/string_spec.rb +53 -25
  234. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  235. data/spec/mongoid/extensions/time_spec.rb +634 -66
  236. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  237. data/spec/mongoid/factory_spec.rb +61 -1
  238. data/spec/mongoid/fields_spec.rb +321 -50
  239. data/spec/mongoid/findable_spec.rb +64 -29
  240. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  241. data/spec/mongoid/indexable_spec.rb +16 -19
  242. data/spec/mongoid/interceptable_spec.rb +584 -5
  243. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  244. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  245. data/spec/mongoid/mongoizable_spec.rb +285 -0
  246. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  247. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  248. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  249. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  250. data/spec/mongoid/persistence_context_spec.rb +24 -0
  251. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  252. data/spec/mongoid/query_cache_spec.rb +0 -154
  253. data/spec/mongoid/reloadable_spec.rb +35 -2
  254. data/spec/mongoid/scopable_spec.rb +36 -34
  255. data/spec/mongoid/shardable_spec.rb +14 -0
  256. data/spec/mongoid/stateful_spec.rb +28 -0
  257. data/spec/mongoid/timestamps_spec.rb +390 -0
  258. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  259. data/spec/mongoid/touchable_spec.rb +116 -0
  260. data/spec/mongoid/touchable_spec_models.rb +12 -8
  261. data/spec/mongoid/traversable_spec.rb +4 -11
  262. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  263. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  264. data/spec/mongoid/warnings_spec.rb +35 -0
  265. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  266. data/spec/rails/mongoid_spec.rb +4 -16
  267. data/spec/shared/lib/mrss/docker_runner.rb +0 -4
  268. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  269. data/spec/support/constraints.rb +24 -0
  270. data/spec/support/macros.rb +30 -0
  271. data/spec/support/models/augmentation.rb +12 -0
  272. data/spec/support/models/band.rb +3 -0
  273. data/spec/support/models/catalog.rb +24 -0
  274. data/spec/support/models/circus.rb +3 -0
  275. data/spec/support/models/fanatic.rb +8 -0
  276. data/spec/support/models/implant.rb +9 -0
  277. data/spec/support/models/label.rb +2 -0
  278. data/spec/support/models/passport.rb +9 -0
  279. data/spec/support/models/person.rb +1 -0
  280. data/spec/support/models/player.rb +2 -0
  281. data/spec/support/models/powerup.rb +12 -0
  282. data/spec/support/models/registry.rb +1 -0
  283. data/spec/support/models/school.rb +14 -0
  284. data/spec/support/models/shield.rb +18 -0
  285. data/spec/support/models/student.rb +14 -0
  286. data/spec/support/models/weapon.rb +12 -0
  287. data.tar.gz.sig +0 -0
  288. metadata +667 -631
  289. metadata.gz.sig +0 -0
  290. data/lib/mongoid/errors/eager_load.rb +0 -23
  291. data/lib/mongoid/errors/invalid_value.rb +0 -17
  292. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative 'embeds_many_models'
4
5
 
5
6
  describe Mongoid::Association::Embedded::EmbedsMany do
6
7
 
@@ -861,4 +862,71 @@ describe Mongoid::Association::Embedded::EmbedsMany do
861
862
  expect(association.path(double( :_parent => true))).to be_a(Mongoid::Atomic::Paths::Embedded::Many)
862
863
  end
863
864
  end
865
+
866
+ context "when the document and embedded document's klass is in a submodule" do
867
+
868
+ let(:tank) { EmmSpec::Tank.create! }
869
+ let(:gun) { tank.guns.create! }
870
+
871
+ let(:inverse_assoc) { gun._association.inverse_association }
872
+
873
+ it "has the correct inverses" do
874
+ pending 'MONGOID-5080'
875
+
876
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
877
+ inverse_assoc.name.should == :tank
878
+ end
879
+
880
+ context "when embedded association is not namespaced but has class_name" do
881
+
882
+ let(:turret) { tank.emm_turrets.create! }
883
+
884
+ let(:inverse_assoc) { turret._association.inverse_association }
885
+
886
+ it "has the correct inverses" do
887
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
888
+ inverse_assoc.name.should == :tank
889
+ end
890
+ end
891
+
892
+ context "when embedded association is not namespaced and lacks class_name" do
893
+
894
+ let(:hatch) { tank.emm_hatches.create! }
895
+
896
+ let(:inverse_assoc) { hatch._association.inverse_association }
897
+
898
+ it "does not find the inverse" do
899
+ inverse_assoc.should be nil
900
+ end
901
+ end
902
+
903
+ context "when the class names exist on top level and namespaced" do
904
+
905
+ let(:car) { EmmSpec::Car.create! }
906
+ let(:door) { car.doors.create! }
907
+
908
+ let(:inverse_assoc) { door._association.inverse_association }
909
+
910
+ it "has the correct inverses" do
911
+ pending 'MONGOID-5080'
912
+
913
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
914
+ inverse_assoc.name.should == :car
915
+ end
916
+ end
917
+
918
+ context "when the association has an unqualified class_name in same module" do
919
+
920
+ let(:launcher) { tank.launchers.create! }
921
+
922
+ let(:inverse_assoc) { launcher._association.inverse_association }
923
+
924
+ it "has the correct inverses" do
925
+ pending 'unqualified class_name arguments do not work per MONGOID-5080'
926
+
927
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
928
+ inverse_assoc.name.should == :tank
929
+ end
930
+ end
931
+ end
864
932
  end
@@ -78,4 +78,29 @@ describe Mongoid::Association::Embedded::EmbedsOne::Buildable do
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ context 'when the object is already associated with another object' do
83
+
84
+ let(:owner1) do
85
+ Owner.create!
86
+ end
87
+
88
+ let(:owner2) do
89
+ Owner.create!
90
+ end
91
+
92
+ let(:scribe) do
93
+ Scribe.new
94
+ end
95
+
96
+ before do
97
+ owner1.scribe = scribe
98
+ owner2.scribe = scribe
99
+ end
100
+
101
+ it 'clears the object of its previous association' do
102
+ expect(owner1.scribe).to be_nil
103
+ expect(owner2.scribe).to eq(scribe)
104
+ end
105
+ end
81
106
  end
@@ -52,3 +52,22 @@ class EomDnlChild
52
52
  embedded_in :parent, class_name: 'EomDnlParent'
53
53
  embedded_in :missing_parent, class_name: 'EomDnlMissingParent'
54
54
  end
55
+
56
+ class EomAddress
57
+ include Mongoid::Document
58
+
59
+ field :city, type: String
60
+
61
+ embedded_in :addressable, polymorphic: true
62
+ end
63
+
64
+ # app/models/company.rb
65
+ class EomCompany
66
+ include Mongoid::Document
67
+
68
+ embeds_one :address, class_name: 'EomAddress', as: :addressable
69
+ accepts_nested_attributes_for :address
70
+
71
+ embeds_one :delivery_address, class_name: 'EomAddress', as: :addressable
72
+ accepts_nested_attributes_for :delivery_address
73
+ end
@@ -953,4 +953,32 @@ describe Mongoid::Association::Embedded::EmbedsOne do
953
953
  expect(association.create_relation(owner, target)).to be_a(EmbeddedObject)
954
954
  end
955
955
  end
956
+
957
+ context "when multiple embeds_one associations reference the same class" do
958
+ let(:acme) { EomCompany.create(address: { city: 'Gotham' }, delivery_address: { city: 'Parcelville' }) }
959
+
960
+ context "when the first assignment is modified" do
961
+ before do
962
+ acme.update(address: EomAddress.new(city: 'Bigville'))
963
+ acme.reload
964
+ end
965
+
966
+ it "updates the correct association" do
967
+ expect(acme.address.city).to eq("Bigville")
968
+ expect(acme.delivery_address.city).to eq("Parcelville")
969
+ end
970
+ end
971
+
972
+ context "when the second assignment is modified" do
973
+ before do
974
+ acme.update(delivery_address: EomAddress.new(city: 'Bigville'))
975
+ acme.reload
976
+ end
977
+
978
+ it "updates the correct association" do
979
+ expect(acme.address.city).to eq("Gotham")
980
+ expect(acme.delivery_address.city).to eq("Bigville")
981
+ end
982
+ end
983
+ end
956
984
  end
@@ -83,7 +83,8 @@ describe Mongoid::Association::Referenced::BelongsTo::Binding do
83
83
  end
84
84
 
85
85
  it "does nothing" do
86
- expect(game).to receive(:person=).never
86
+ expect(game).to receive(:person=).with(person).never
87
+ expect(game).to receive(:person=).with(nil).once
87
88
  binding.bind_one
88
89
  end
89
90
  end
@@ -235,4 +235,58 @@ describe Mongoid::Association::Referenced::BelongsTo::Buildable do
235
235
  end
236
236
  end
237
237
  end
238
+
239
+ context 'when the object is already associated with another object' do
240
+
241
+ context "when inverse is has_many" do
242
+
243
+ let(:drug1) do
244
+ Drug.create!
245
+ end
246
+
247
+ let(:drug2) do
248
+ Drug.create!
249
+ end
250
+
251
+ let(:person) do
252
+ Person.create!
253
+ end
254
+
255
+ before do
256
+ drug1.person = person
257
+ drug2.person = person
258
+ end
259
+
260
+ it 'does not clear the object of its previous association' do
261
+ expect(drug1.person).to eq(person)
262
+ expect(drug2.person).to eq(person)
263
+ expect(person.drugs).to eq([drug1, drug2])
264
+ end
265
+ end
266
+
267
+ context "when inverse is has_one" do
268
+
269
+ let(:account1) do
270
+ Account.create!(name: "1")
271
+ end
272
+
273
+ let(:account2) do
274
+ Account.create!(name: "2")
275
+ end
276
+
277
+ let(:person) do
278
+ Person.create!
279
+ end
280
+
281
+ before do
282
+ account1.person = person
283
+ account2.person = person
284
+ end
285
+
286
+ it 'clears the object of its previous association' do
287
+ expect(account1.person).to be_nil
288
+ expect(account2.person).to eq(person)
289
+ end
290
+ end
291
+ end
238
292
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative '../belongs_to_models.rb'
4
5
 
5
6
  describe Mongoid::Association::Referenced::BelongsTo::Proxy do
6
7
 
@@ -1368,6 +1369,20 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
1368
1369
  game.person.set_personal_data(ssn: '123', age: 25)
1369
1370
  end.not_to raise_error
1370
1371
  end
1372
+ end
1373
+
1374
+ # This is a very specific case, see MONGOID-5089 for more details.
1375
+ context "when required is false, child is an orphan, and parent has explicit _id" do
1376
+ let(:comment) { BTMComment.create! }
1377
+ let(:article) do
1378
+ BTMArticle.new(
1379
+ comment_ids: [comment.id],
1380
+ id: 1
1381
+ )
1382
+ end
1371
1383
 
1384
+ it "uses the correct explicit id" do
1385
+ expect(article.comments.first.article_id).to eq(1)
1386
+ end
1372
1387
  end
1373
1388
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BTMArticle
4
+ include Mongoid::Document
5
+ has_many :comments, class_name: "BTMComment"
6
+ end
7
+
8
+ class BTMComment
9
+ include Mongoid::Document
10
+ belongs_to :article, class_name: "BTMArticle", required: false
11
+ end
@@ -2019,8 +2019,8 @@ describe Mongoid::Association::Referenced::BelongsTo do
2019
2019
 
2020
2020
  describe '#foreign_key_check' do
2021
2021
 
2022
- it 'returns the foreign_key followed by "_changed?"' do
2023
- expect(association.foreign_key_check).to eq('owner_object_id_changed?')
2022
+ it 'returns the foreign_key followed by "_previously_changed?"' do
2023
+ expect(association.foreign_key_check).to eq('owner_object_id_previously_changed?')
2024
2024
  end
2025
2025
  end
2026
2026
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
- require_relative "../has_and_belongs_to_many_models.rb"
4
+ require_relative "../has_and_belongs_to_many_models"
5
5
 
6
6
  describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
7
7
 
@@ -2395,6 +2395,10 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2395
2395
  it "removes the ids from the foreign key" do
2396
2396
  expect(person.preference_ids).to eq([ preference_two.id ])
2397
2397
  end
2398
+
2399
+ it "sets the association locally" do
2400
+ expect(person.preferences).to eq([preference_two])
2401
+ end
2398
2402
  end
2399
2403
 
2400
2404
  context "when conditions are not provided" do
@@ -2421,6 +2425,10 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2421
2425
  it "returns the number of documents deleted" do
2422
2426
  expect(deleted).to eq(2)
2423
2427
  end
2428
+
2429
+ it "sets the association locally" do
2430
+ expect(person.preferences).to eq([])
2431
+ end
2424
2432
  end
2425
2433
  end
2426
2434
  end
@@ -2508,7 +2516,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2508
2516
  it "raises an error" do
2509
2517
  expect {
2510
2518
  preference
2511
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2519
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Preference with id\(s\)/)
2512
2520
  end
2513
2521
  end
2514
2522
 
@@ -2523,7 +2531,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2523
2531
  it "raises an error" do
2524
2532
  expect {
2525
2533
  person.preferences.find(BSON::ObjectId.new)
2526
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2534
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Preference with id\(s\)/)
2527
2535
  end
2528
2536
  end
2529
2537
 
@@ -2572,7 +2580,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2572
2580
  it "raises an error" do
2573
2581
  expect {
2574
2582
  preferences
2575
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2583
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Preference with id\(s\)/)
2576
2584
  end
2577
2585
  end
2578
2586
 
@@ -2587,7 +2595,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
2587
2595
  it "raises an error" do
2588
2596
  expect {
2589
2597
  person.preferences.find([ BSON::ObjectId.new ])
2590
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2598
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Preference with id\(s\)/)
2591
2599
  end
2592
2600
  end
2593
2601
 
@@ -3772,6 +3780,31 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
3772
3780
  end
3773
3781
  end
3774
3782
 
3783
+ context "when accesing own _id from parent's foreign key in default" do
3784
+ let!(:contract) { HabtmmContract.create! }
3785
+ let!(:signature) { contract.signatures.create! }
3786
+
3787
+ it "is nil" do
3788
+ expect(signature.favorite_signature).to be nil
3789
+ end
3790
+ end
3791
+
3792
+ context "when setting an association on a model that uses the class_name option" do
3793
+ let!(:contract) { HabtmmContract.create! }
3794
+ let!(:signature) { HabtmmSignature.create!(contracts: [contract]) }
3795
+
3796
+ it "populates the inverse foreign key" do
3797
+ expect(signature.contracts.first.signature_ids).to eq([signature.id])
3798
+ end
3799
+ end
3800
+
3801
+ context "when there is a foreign key in the aliased associations" do
3802
+ it "has the correct aliases" do
3803
+ expect(Dog.aliased_associations["breed_ids"]).to eq("breeds")
3804
+ expect(Breed.aliased_associations["dog_ids"]).to eq("dogs")
3805
+ end
3806
+ end
3807
+
3775
3808
  # This test is for MONGOID-5344 which tests that the initial call to
3776
3809
  # signature_ids refers to the same array as subsequent calls to signature_ids.
3777
3810
  # Prior to the change in that ticket, this test broke because the array
@@ -32,6 +32,8 @@ end
32
32
  class HabtmmSignature
33
33
  include Mongoid::Document
34
34
 
35
+ field :favorite_signature, default: ->{ contracts.first.signature_ids.first if contracts.first }
36
+
35
37
  has_and_belongs_to_many :contracts, class_name: 'HabtmmContract'
36
38
 
37
39
  field :name, type: String
@@ -65,3 +67,26 @@ class HabtmmAnimal
65
67
 
66
68
  has_and_belongs_to_many :trainers, inverse_of: :animals, class_name: 'HabtmmTrainer', scope: -> { where(name: 'Dave') }
67
69
  end
70
+
71
+ class HabtmmSchool
72
+ include Mongoid::Document
73
+ include Mongoid::Timestamps
74
+
75
+ has_and_belongs_to_many :students, class_name: 'HabtmmStudent'
76
+
77
+ field :after_destroy_triggered, default: false
78
+
79
+ accepts_nested_attributes_for :students, allow_destroy: true
80
+ end
81
+
82
+ class HabtmmStudent
83
+ include Mongoid::Document
84
+ include Mongoid::Timestamps
85
+
86
+ has_and_belongs_to_many :schools, class_name: 'HabtmmSchool'
87
+
88
+ after_destroy do |doc|
89
+ schools.first.update_attributes!(after_destroy_triggered: true) unless schools.empty?
90
+ end
91
+ end
92
+
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative "./has_and_belongs_to_many_models"
4
5
 
5
6
  describe Mongoid::Association::Referenced::HasAndBelongsToMany do
6
7
 
@@ -1008,8 +1009,8 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany do
1008
1009
 
1009
1010
  describe '#foreign_key_check' do
1010
1011
 
1011
- it 'returns the foreign_key followed by "_changed?"' do
1012
- expect(association.foreign_key_check).to eq('has_many_right_object_ids_changed?')
1012
+ it 'returns the foreign_key followed by "_previously_changed?"' do
1013
+ expect(association.foreign_key_check).to eq('has_many_right_object_ids_previously_changed?')
1013
1014
  end
1014
1015
  end
1015
1016
 
@@ -1060,6 +1061,13 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany do
1060
1061
  expect(association.inverse_foreign_key).to eq('bar_ref')
1061
1062
  end
1062
1063
  end
1064
+
1065
+ context "when using a model that uses the class_name option" do
1066
+ let(:inverse_foreign_key) { HabtmmSchool.relations[:students].inverse_foreign_key }
1067
+ it "gets the correct inverse foreign key" do
1068
+ expect(inverse_foreign_key).to eq("school_ids")
1069
+ end
1070
+ end
1063
1071
  end
1064
1072
 
1065
1073
  describe '#inverse_foreign_key_setter' do
@@ -1068,4 +1076,29 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany do
1068
1076
  expect(association.inverse_foreign_key_setter).to eq('has_many_left_object_ids=')
1069
1077
  end
1070
1078
  end
1079
+
1080
+ context "when adding an object to the association" do
1081
+ let!(:start_time) { Timecop.freeze(Time.at(Time.now.to_i)) }
1082
+
1083
+ let(:update_time) do
1084
+ Timecop.freeze(Time.at(Time.now.to_i) + 2)
1085
+ end
1086
+
1087
+ after do
1088
+ Timecop.return
1089
+ end
1090
+
1091
+ let!(:school) { HabtmmSchool.create! }
1092
+ let!(:student) { HabtmmStudent.create! }
1093
+
1094
+ before do
1095
+ update_time
1096
+ school.update(students: [student])
1097
+ end
1098
+
1099
+ it "updates the updated at" do
1100
+ pending "MONGOID-4953"
1101
+ expect(school.updated_at).to eq(update_time)
1102
+ end
1103
+ end
1071
1104
  end
@@ -138,5 +138,114 @@ describe Mongoid::Association::Referenced::HasMany::Buildable do
138
138
  end
139
139
  end
140
140
  end
141
+
142
+ context 'when the object is already associated with another object' do
143
+
144
+ context "when using <<" do
145
+
146
+ let(:person1) do
147
+ Person.new
148
+ end
149
+
150
+ let(:person2) do
151
+ Person.new
152
+ end
153
+
154
+ let(:drug) do
155
+ Drug.new
156
+ end
157
+
158
+ before do
159
+ person1.drugs << drug
160
+ person2.drugs << drug
161
+ end
162
+
163
+ it 'clears the object of its previous association' do
164
+ expect(person1.drugs).to eq([])
165
+ expect(person1.drug_ids).to eq([])
166
+ expect(person2.drugs).to eq([drug])
167
+ expect(person2.drug_ids).to eq([drug._id])
168
+ end
169
+ end
170
+
171
+ context "when using concat" do
172
+
173
+ let(:person1) do
174
+ Person.new
175
+ end
176
+
177
+ let(:person2) do
178
+ Person.new
179
+ end
180
+
181
+ let(:drug) do
182
+ Drug.new
183
+ end
184
+
185
+ before do
186
+ person1.drugs.concat([drug])
187
+ person2.drugs.concat([drug])
188
+ end
189
+
190
+ it 'clears the object of its previous association' do
191
+ expect(person1.drugs).to eq([])
192
+ expect(person1.drug_ids).to eq([])
193
+ expect(person2.drugs).to eq([drug])
194
+ expect(person2.drug_ids).to eq([drug._id])
195
+ end
196
+ end
197
+
198
+ context "when using =" do
199
+
200
+ let(:person1) do
201
+ Person.new
202
+ end
203
+
204
+ let(:person2) do
205
+ Person.new
206
+ end
207
+
208
+ let(:drug) do
209
+ Drug.new
210
+ end
211
+
212
+ before do
213
+ person1.drugs = [drug]
214
+ person2.drugs = [drug]
215
+ end
216
+
217
+ it 'clears the object of its previous association' do
218
+ expect(person1.drugs).to eq([])
219
+ expect(person1.drug_ids).to eq([])
220
+ expect(person2.drugs).to eq([drug])
221
+ expect(person2.drug_ids).to eq([drug._id])
222
+ end
223
+ end
224
+
225
+ context "when using = on the same document twice" do
226
+
227
+ let(:person1) do
228
+ Person.new
229
+ end
230
+
231
+ let(:person2) do
232
+ Person.new
233
+ end
234
+
235
+ let(:drug) do
236
+ Drug.new
237
+ end
238
+
239
+ before do
240
+ person1.drugs = [drug]
241
+ person1.drugs = [drug]
242
+ end
243
+
244
+ it 'clears the object of its previous association' do
245
+ expect(person1.drugs).to eq([drug])
246
+ expect(person1.drug_ids).to eq([drug._id])
247
+ end
248
+ end
249
+ end
141
250
  end
142
251
  end
@@ -1237,33 +1237,6 @@ describe Mongoid::Association::Referenced::HasMany::Enumerable do
1237
1237
  end
1238
1238
  end
1239
1239
 
1240
- context 'when the id_sort option is none' do
1241
-
1242
- let(:person) do
1243
- Person.create!
1244
- end
1245
-
1246
- let(:criteria) do
1247
- Post.where(person_id: person.id)
1248
- end
1249
-
1250
- let(:enumerable) do
1251
- described_class.new(criteria)
1252
- end
1253
-
1254
- let!(:first_post) do
1255
- person.posts.create!(title: "One")
1256
- end
1257
-
1258
- let!(:second_post) do
1259
- person.posts.create!(title: "Two")
1260
- end
1261
-
1262
- it 'does not use the sort on id' do
1263
- expect(enumerable.first(id_sort: :none)).to eq(first_post)
1264
- end
1265
- end
1266
-
1267
1240
  context 'when including a limit' do
1268
1241
 
1269
1242
  let(:person) do
@@ -1291,7 +1264,7 @@ describe Mongoid::Association::Referenced::HasMany::Enumerable do
1291
1264
  end
1292
1265
  end
1293
1266
 
1294
- context 'when the id_sort option is not provided' do
1267
+ context 'when no parameters are provided' do
1295
1268
 
1296
1269
  let(:person) do
1297
1270
  Person.create!
@@ -1761,34 +1734,7 @@ describe Mongoid::Association::Referenced::HasMany::Enumerable do
1761
1734
  end
1762
1735
  end
1763
1736
 
1764
- context 'when the id_sort option is none' do
1765
-
1766
- let(:person) do
1767
- Person.create!
1768
- end
1769
-
1770
- let(:criteria) do
1771
- Post.where(person_id: person.id)
1772
- end
1773
-
1774
- let(:enumerable) do
1775
- described_class.new(criteria)
1776
- end
1777
-
1778
- let!(:first_post) do
1779
- person.posts.create!(title: "One")
1780
- end
1781
-
1782
- let!(:second_post) do
1783
- person.posts.create!(title: "Two")
1784
- end
1785
-
1786
- it 'does not use the sort on id' do
1787
- expect(enumerable.last(id_sort: :none)).to eq(first_post)
1788
- end
1789
- end
1790
-
1791
- context 'when the id_sort option is not provided' do
1737
+ context 'when no parameters are provided' do
1792
1738
 
1793
1739
  let(:person) do
1794
1740
  Person.create!