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
@@ -12,7 +12,7 @@ module Mongoid
12
12
  # We undefine most methods to get them sent through to the target.
13
13
  instance_methods.each do |method|
14
14
  undef_method(method) unless
15
- method =~ /(^__|^send|^object_id|^respond_to|^tap|^public_send|extend_proxy|extend_proxies)/
15
+ method =~ /^(__.*|send|object_id|equal\?|respond_to\?|tap|public_send|extend_proxy|extend_proxies)$/
16
16
  end
17
17
 
18
18
  include Threaded::Lifecycle
@@ -84,35 +84,6 @@ module Mongoid
84
84
  target
85
85
  end
86
86
 
87
- # Tell the next persistence operation to store in a specific collection,
88
- # database or client.
89
- #
90
- # @example Save the current document to a different collection.
91
- # model.with(collection: "secondary").save
92
- #
93
- # @example Save the current document to a different database.
94
- # model.with(database: "secondary").save
95
- #
96
- # @example Save the current document to a different client.
97
- # model.with(client: "replica_set").save
98
- #
99
- # @example Save with a combination of options.
100
- # model.with(client: "sharded", database: "secondary").save
101
- #
102
- # @param [ Hash ] options The storage options.
103
- #
104
- # @option options [ String, Symbol ] :collection The collection name.
105
- # @option options [ String, Symbol ] :database The database name.
106
- # @option options [ String, Symbol ] :client The client name.
107
- #
108
- # @return [ Document ] The current document.
109
- #
110
- # @since 3.0.0
111
- def with(options)
112
- @persistence_options = options
113
- self
114
- end
115
-
116
87
  protected
117
88
 
118
89
  # Get the collection from the root of the hierarchy.
@@ -125,7 +96,6 @@ module Mongoid
125
96
  # @since 2.0.0
126
97
  def collection
127
98
  root = base._root
128
- root.with(@persistence_options)
129
99
  root.collection unless root.embedded?
130
100
  end
131
101
 
@@ -10,6 +10,24 @@ module Mongoid
10
10
  class In < Relations::One
11
11
  include Evolvable
12
12
 
13
+ # The allowed options when defining this relation.
14
+ #
15
+ # @return [ Array<Symbol> ] The allowed options when defining this relation.
16
+ #
17
+ # @since 6.0.0
18
+ VALID_OPTIONS = [
19
+ :autobuild,
20
+ :autosave,
21
+ :dependent,
22
+ :foreign_key,
23
+ :index,
24
+ :polymorphic,
25
+ :primary_key,
26
+ :touch,
27
+ :optional,
28
+ :required
29
+ ].freeze
30
+
13
31
  # Instantiate a new referenced_in relation.
14
32
  #
15
33
  # @example Create the new relation.
@@ -264,16 +282,7 @@ module Mongoid
264
282
  #
265
283
  # @since 2.1.0
266
284
  def valid_options
267
- [
268
- :autobuild,
269
- :autosave,
270
- :dependent,
271
- :foreign_key,
272
- :index,
273
- :polymorphic,
274
- :primary_key,
275
- :touch
276
- ]
285
+ VALID_OPTIONS
277
286
  end
278
287
 
279
288
  # Get the default validation setting for the relation. Determines if
@@ -10,6 +10,24 @@ module Mongoid
10
10
  delegate :count, to: :criteria
11
11
  delegate :first, :in_memory, :last, :reset, :uniq, to: :target
12
12
 
13
+ # The allowed options when defining this relation.
14
+ #
15
+ # @return [ Array<Symbol> ] The allowed options when defining this relation.
16
+ #
17
+ # @since 6.0.0
18
+ VALID_OPTIONS = [
19
+ :after_add,
20
+ :after_remove,
21
+ :as,
22
+ :autosave,
23
+ :before_add,
24
+ :before_remove,
25
+ :dependent,
26
+ :foreign_key,
27
+ :order,
28
+ :primary_key
29
+ ].freeze
30
+
13
31
  # Appends a document or array of documents to the relation. Will set
14
32
  # the parent and update the index in the process.
15
33
  #
@@ -320,7 +338,6 @@ module Mongoid
320
338
  #
321
339
  # @since 2.0.0.rc.1
322
340
  def append(document)
323
- document.with(@persistence_options) if @persistence_options
324
341
  with_add_callbacks(document, already_related?(document)) do
325
342
  target.push(document)
326
343
  characterize_one(document)
@@ -460,7 +477,7 @@ module Mongoid
460
477
  # @since 3.0.0
461
478
  def persist_delayed(docs, inserts)
462
479
  unless docs.empty?
463
- collection.insert_many(inserts)
480
+ collection.insert_many(inserts, session: _session)
464
481
  docs.each do |doc|
465
482
  doc.new_record = false
466
483
  doc.run_after_callbacks(:create, :save)
@@ -500,7 +517,7 @@ module Mongoid
500
517
  selector = conditions || {}
501
518
  removed = klass.send(method, selector.merge!(criteria.selector))
502
519
  target.delete_if do |doc|
503
- if doc.matches?(selector)
520
+ if doc._matches?(selector)
504
521
  unbind_one(doc) and true
505
522
  end
506
523
  end
@@ -550,7 +567,7 @@ module Mongoid
550
567
  if doc.new_record? && doc.valid?(:create)
551
568
  doc.run_before_callbacks(:save, :create)
552
569
  docs.push(doc)
553
- inserts.push(doc.as_document)
570
+ inserts.push(doc.send(:as_attributes))
554
571
  else
555
572
  doc.save
556
573
  end
@@ -590,14 +607,12 @@ module Mongoid
590
607
  # @since 2.1.0
591
608
  def criteria(metadata, object, type = nil)
592
609
  apply_ordering(
593
- with_inverse_field_criterion(
594
- with_polymorphic_criterion(
595
- metadata.klass.where(metadata.foreign_key => object),
596
- metadata,
597
- type
598
- ),
599
- metadata
600
- ), metadata
610
+ with_polymorphic_criterion(
611
+ metadata.klass.where(metadata.foreign_key => object),
612
+ metadata,
613
+ type
614
+ ),
615
+ metadata
601
616
  )
602
617
  end
603
618
 
@@ -729,18 +744,7 @@ module Mongoid
729
744
  #
730
745
  # @since 2.1.0
731
746
  def valid_options
732
- [
733
- :after_add,
734
- :after_remove,
735
- :as,
736
- :autosave,
737
- :before_add,
738
- :before_remove,
739
- :dependent,
740
- :foreign_key,
741
- :order,
742
- :primary_key
743
- ]
747
+ VALID_OPTIONS
744
748
  end
745
749
 
746
750
  # Get the default validation setting for the relation. Determines if
@@ -795,8 +799,8 @@ module Mongoid
795
799
  # @since 3.0.0
796
800
  def with_inverse_field_criterion(criteria, metadata)
797
801
  inverse_metadata = metadata.inverse_metadata(metadata.klass)
798
- if inverse_metadata.try(:inverse_of_field)
799
- criteria.any_in(inverse_metadata.inverse_of_field => [ metadata.name, nil ])
802
+ if inverse_metadata.try(:inverse_of)
803
+ criteria.any_in(inverse_metadata.inverse_of => [ metadata.name, nil ])
800
804
  else
801
805
  criteria
802
806
  end
@@ -7,6 +7,24 @@ module Mongoid
7
7
  # many-to-many between documents in different collections.
8
8
  class ManyToMany < Many
9
9
 
10
+ # The allowed options when defining this relation.
11
+ #
12
+ # @return [ Array<Symbol> ] The allowed options when defining this relation.
13
+ #
14
+ # @since 6.0.0
15
+ VALID_OPTIONS = [
16
+ :after_add,
17
+ :after_remove,
18
+ :autosave,
19
+ :before_add,
20
+ :before_remove,
21
+ :dependent,
22
+ :foreign_key,
23
+ :index,
24
+ :order,
25
+ :primary_key
26
+ ].freeze
27
+
10
28
  # Appends a document or array of documents to the relation. Will set
11
29
  # the parent and update the index in the process.
12
30
  #
@@ -266,7 +284,7 @@ module Mongoid
266
284
  #
267
285
  # @since 3.0.0
268
286
  def unsynced(doc, key)
269
- doc.synced[key] = false
287
+ doc._synced[key] = false
270
288
  true
271
289
  end
272
290
 
@@ -439,18 +457,7 @@ module Mongoid
439
457
  #
440
458
  # @since 2.1.0
441
459
  def valid_options
442
- [
443
- :after_add,
444
- :after_remove,
445
- :autosave,
446
- :before_add,
447
- :before_remove,
448
- :dependent,
449
- :foreign_key,
450
- :index,
451
- :order,
452
- :primary_key
453
- ]
460
+ VALID_OPTIONS
454
461
  end
455
462
 
456
463
  # Get the default validation setting for the relation. Determines if
@@ -7,6 +7,20 @@ module Mongoid
7
7
  # one-to-one between documents in different collections.
8
8
  class One < Relations::One
9
9
 
10
+ # The allowed options when defining this relation.
11
+ #
12
+ # @return [ Array<Symbol> ] The allowed options when defining this relation.
13
+ #
14
+ # @since 6.0.0
15
+ VALID_OPTIONS = [
16
+ :as,
17
+ :autobuild,
18
+ :autosave,
19
+ :dependent,
20
+ :foreign_key,
21
+ :primary_key
22
+ ].freeze
23
+
10
24
  # Instantiate a new references_one relation. Will set the foreign key
11
25
  # and the base on the inverse object.
12
26
  #
@@ -254,7 +268,7 @@ module Mongoid
254
268
  #
255
269
  # @since 2.1.0
256
270
  def valid_options
257
- [ :as, :autobuild, :autosave, :dependent, :foreign_key, :primary_key ]
271
+ VALID_OPTIONS
258
272
  end
259
273
 
260
274
  # Get the default validation setting for the relation. Determines if
@@ -11,41 +11,41 @@ module Mongoid
11
11
  # the key has changed and the relation bindings have not been run.
12
12
  #
13
13
  # @example Are the foreign keys syncable?
14
- # document.syncable?(metadata)
14
+ # document._syncable??(metadata)
15
15
  #
16
16
  # @param [ Metadata ] metadata The relation metadata.
17
17
  #
18
18
  # @return [ true, false ] If we can sync.
19
19
  #
20
20
  # @since 2.1.0
21
- def syncable?(metadata)
22
- !synced?(metadata.foreign_key) && send(metadata.foreign_key_check)
21
+ def _syncable?(metadata)
22
+ !_synced?(metadata.foreign_key) && send(metadata.foreign_key_check)
23
23
  end
24
24
 
25
25
  # Get the synced foreign keys.
26
26
  #
27
27
  # @example Get the synced foreign keys.
28
- # document.synced
28
+ # document._synced
29
29
  #
30
30
  # @return [ Hash ] The synced foreign keys.
31
31
  #
32
32
  # @since 2.1.0
33
- def synced
34
- @synced ||= {}
33
+ def _synced
34
+ @_synced ||= {}
35
35
  end
36
36
 
37
37
  # Has the document been synced for the foreign key?
38
38
  #
39
39
  # @example Has the document been synced?
40
- # document.synced?
40
+ # document._synced??
41
41
  #
42
42
  # @param [ String ] foreign_key The foreign key.
43
43
  #
44
44
  # @return [ true, false ] If we can sync.
45
45
  #
46
46
  # @since 2.1.0
47
- def synced?(foreign_key)
48
- !!synced[foreign_key]
47
+ def _synced?(foreign_key)
48
+ !!_synced[foreign_key]
49
49
  end
50
50
 
51
51
  # Update the inverse keys on destroy.
@@ -81,7 +81,7 @@ module Mongoid
81
81
  adds, subs = new - (old || []), (old || []) - new
82
82
 
83
83
  # If we are autosaving we don't want a duplicate to get added - the
84
- # $addToSet would run previously and then the $pushAll from the
84
+ # $addToSet would run previously and then the $push and $each from the
85
85
  # inverse on the autosave would cause this. We delete each id from
86
86
  # what's in memory in case a mix of id addition and object addition
87
87
  # had occurred.
@@ -110,7 +110,7 @@ module Mongoid
110
110
  # @param [ Metadata ] metadata The relation metadata.
111
111
  #
112
112
  # @since 2.1.0
113
- def synced(metadata)
113
+ def _synced(metadata)
114
114
  unless metadata.forced_nil_inverse?
115
115
  synced_save(metadata)
116
116
  synced_destroy(metadata)
@@ -137,7 +137,7 @@ module Mongoid
137
137
  set_callback(
138
138
  :save,
139
139
  :after,
140
- if: ->(doc){ doc.syncable?(metadata) }
140
+ if: ->(doc){ doc._syncable?(metadata) }
141
141
  ) do |doc|
142
142
  doc.update_inverse_keys(metadata)
143
143
  end
@@ -214,12 +214,22 @@ module Mongoid
214
214
  # @example Get the first document.
215
215
  # enumerable.first
216
216
  #
217
+ # @note Automatically adding a sort on _id when no other sort is
218
+ # defined on the criteria has the potential to cause bad performance issues.
219
+ # If you experience unexpected poor performance when using #first or #last,
220
+ # use the option { id_sort: :none }.
221
+ # Be aware that #first/#last won't guarantee order in this case.
222
+ #
223
+ # @param [ Hash ] opts The options for the query returning the first document.
224
+ #
225
+ # @option opts [ :none ] :id_sort Don't apply a sort on _id.
226
+ #
217
227
  # @return [ Document ] The first document found.
218
228
  #
219
229
  # @since 2.1.0
220
- def first
230
+ def first(opts = {})
221
231
  _loaded.try(:values).try(:first) ||
222
- _added[(ul = _unloaded.try(:first)).try(:id)] ||
232
+ _added[(ul = _unloaded.try(:first, opts)).try(:id)] ||
223
233
  ul ||
224
234
  _added.values.try(:first)
225
235
  end
@@ -298,13 +308,23 @@ module Mongoid
298
308
  # @example Get the last document.
299
309
  # enumerable.last
300
310
  #
311
+ # @note Automatically adding a sort on _id when no other sort is
312
+ # defined on the criteria has the potential to cause bad performance issues.
313
+ # If you experience unexpected poor performance when using #first or #last,
314
+ # use the option { id_sort: :none }.
315
+ # Be aware that #first/#last won't guarantee order in this case.
316
+ #
317
+ # @param [ Hash ] opts The options for the query returning the first document.
318
+ #
319
+ # @option opts [ :none ] :id_sort Don't apply a sort on _id.
320
+ #
301
321
  # @return [ Document ] The last document found.
302
322
  #
303
323
  # @since 2.1.0
304
- def last
324
+ def last(opts = {})
305
325
  _added.values.try(:last) ||
306
326
  _loaded.try(:values).try(:last) ||
307
- _added[(ul = _unloaded.try(:last)).try(:id)] ||
327
+ _added[(ul = _unloaded.try(:last, opts)).try(:id)] ||
308
328
  ul
309
329
  end
310
330
 
@@ -31,7 +31,7 @@ module Mongoid
31
31
  touches = touch_atomic_updates(field)
32
32
  unless touches["$set"].blank?
33
33
  selector = atomic_selector
34
- _root.collection.find(selector).update_one(positionally(selector, touches))
34
+ _root.collection.find(selector).update_one(positionally(selector, touches), session: _session)
35
35
  end
36
36
  run_callbacks(:touch)
37
37
  true
@@ -53,7 +53,8 @@ module Mongoid
53
53
  def touchable(metadata)
54
54
  if metadata.touchable?
55
55
  name = metadata.name
56
- method_name = define_relation_touch_method(name)
56
+ field = metadata[:touch].is_a?(Symbol) ? metadata[:touch] : nil
57
+ method_name = define_relation_touch_method(name, field)
57
58
  after_save method_name
58
59
  after_destroy method_name
59
60
  after_touch method_name
@@ -70,19 +71,21 @@ module Mongoid
70
71
  #
71
72
  # @example Define the touch relation.
72
73
  # Model.define_relation_touch_method(:band)
74
+ # Model.define_relation_touch_method(:band, :band_updated_at)
73
75
  #
74
76
  # @param [ Symbol ] name The name of the relation.
77
+ # @param [ Symbol ] extra_field Additional timestamp field to update.
75
78
  #
76
79
  # @since 3.1.0
77
80
  #
78
81
  # @return [ Symbol ] The method name.
79
- def define_relation_touch_method(name)
82
+ def define_relation_touch_method(name, extra_field = nil)
80
83
  method_name = "touch_#{name}_after_create_or_destroy"
81
84
  class_eval <<-TOUCH, __FILE__, __LINE__ + 1
82
85
  def #{method_name}
83
86
  without_autobuild do
84
87
  relation = __send__(:#{name})
85
- relation.touch if relation
88
+ relation.touch #{":#{extra_field}" if extra_field} if relation
86
89
  end
87
90
  end
88
91
  TOUCH
@@ -58,7 +58,7 @@ module Mongoid
58
58
  #
59
59
  # @since 2.3.2
60
60
  def reload_root_document
61
- {}.merge(collection.find(_id: _id).read(mode: :primary).first || {})
61
+ {}.merge(collection.find({ _id: _id }, session: _session).read(mode: :primary).first || {})
62
62
  end
63
63
 
64
64
  # Reload the embedded document.
@@ -71,7 +71,7 @@ module Mongoid
71
71
  # @since 2.3.2
72
72
  def reload_embedded_document
73
73
  extract_embedded_attributes({}.merge(
74
- _root.collection.find(_id: _root._id).read(mode: :primary).first
74
+ collection(_root).find(_id: _root._id).read(mode: :primary).first
75
75
  ))
76
76
  end
77
77
 
@@ -102,7 +102,7 @@ module Mongoid
102
102
  #
103
103
  # @since 3.0.0
104
104
  def default_scopable?
105
- default_scoping? && !Threaded.executing?(:without_default_scope)
105
+ default_scoping? && !Threaded.without_default_scope?(self)
106
106
  end
107
107
 
108
108
  # Get a queryable, either the last one on the scope stack or a fresh one.
@@ -244,10 +244,10 @@ module Mongoid
244
244
  #
245
245
  # @since 3.0.0
246
246
  def without_default_scope
247
- Threaded.begin_execution("without_default_scope")
247
+ Threaded.begin_without_default_scope(self)
248
248
  yield
249
249
  ensure
250
- Threaded.exit_execution("without_default_scope")
250
+ Threaded.exit_without_default_scope(self)
251
251
  end
252
252
 
253
253
  private
@@ -66,7 +66,7 @@ module Mongoid
66
66
  #
67
67
  # @since 3.0.0
68
68
  def field_names(options)
69
- names = (as_document.keys + attribute_names).uniq.sort
69
+ names = (as_attributes.keys + attribute_names).uniq.sort
70
70
 
71
71
  only = Array.wrap(options[:only]).map(&:to_s)
72
72
  except = Array.wrap(options[:except]).map(&:to_s)
@@ -43,6 +43,7 @@ module Mongoid
43
43
  @flagged_for_destroy ||= false
44
44
  end
45
45
  alias :marked_for_destruction? :flagged_for_destroy?
46
+ alias :_destroy :flagged_for_destroy?
46
47
 
47
48
  # Returns true if the +Document+ has been succesfully destroyed, and false
48
49
  # if it hasn't. This is determined by the variable @destroyed and NOT
@@ -44,7 +44,7 @@ module Mongoid
44
44
  models.each do |model|
45
45
  unless model.embedded?
46
46
  begin
47
- model.collection.indexes.each do |index|
47
+ model.collection.indexes(session: model.send(:_session)).each do |index|
48
48
  # ignore default index
49
49
  unless index['name'] == '_id_'
50
50
  key = index['key'].symbolize_keys
@@ -77,7 +77,7 @@ module Mongoid
77
77
  indexes.each do |index|
78
78
  key = index['key'].symbolize_keys
79
79
  collection = model.collection
80
- collection.indexes.drop_one(key)
80
+ collection.indexes(session: model.send(:_session)).drop_one(key)
81
81
  logger.info(
82
82
  "MONGOID: Removed index '#{index['name']}' on collection " +
83
83
  "'#{collection.name}' in database '#{collection.database.name}'."
@@ -107,6 +107,7 @@ module Mongoid
107
107
  end
108
108
 
109
109
  private
110
+
110
111
  def logger
111
112
  Mongoid.logger
112
113
  end
@@ -163,6 +163,30 @@ module Mongoid
163
163
  validations_for(document.class).delete_one(document._id)
164
164
  end
165
165
 
166
+ # Begin suppressing default scopes for given model on the current thread.
167
+ #
168
+ # @example Begin without default scope stack.
169
+ # Threaded.begin_without_default_scope(klass)
170
+ #
171
+ # @param [ Class ] klass The model to suppress default scoping on.
172
+ #
173
+ # @api private
174
+ def begin_without_default_scope(klass)
175
+ stack(:without_default_scope).push(klass)
176
+ end
177
+
178
+ # Exit suppressing default scopes for given model on the current thread.
179
+ #
180
+ # @example Exit without default scope stack.
181
+ # Threaded.exit_without_default_scope(klass)
182
+ #
183
+ # @param [ Class ] klass The model to unsuppress default scoping on.
184
+ #
185
+ # @api private
186
+ def exit_without_default_scope(klass)
187
+ stack(:without_default_scope).delete(klass)
188
+ end
189
+
166
190
  # Get the global client override.
167
191
  #
168
192
  # @example Get the global client override.
@@ -247,6 +271,18 @@ module Mongoid
247
271
  end
248
272
  end
249
273
 
274
+ # Is the given klass' default scope suppressed on the current thread?
275
+ #
276
+ # @example Is the given klass' default scope suppressed?
277
+ # Threaded.without_default_scope?(klass)
278
+ #
279
+ # @param [ Class ] klass The model to check for default scope suppression.
280
+ #
281
+ # @api private
282
+ def without_default_scope?(klass)
283
+ stack(:without_default_scope).include?(klass)
284
+ end
285
+
250
286
  # Is the document autosaved on the current thread?
251
287
  #
252
288
  # @example Is the document autosaved?
@@ -325,5 +361,43 @@ module Mongoid
325
361
  def validations_for(klass)
326
362
  validations[klass] ||= []
327
363
  end
364
+
365
+ # Cache a session for this thread.
366
+ #
367
+ # @example Save a session for this thread.
368
+ # Threaded.set_session(session)
369
+ #
370
+ # @param [ Mongo::Session ] session The session to save.
371
+ #
372
+ # @since 6.4.0
373
+ def set_session(session)
374
+ Thread.current[:session] = session
375
+ end
376
+
377
+ # Get the cached session for this thread.
378
+ #
379
+ # @example Get the session for this thread.
380
+ # Threaded.get_session
381
+ #
382
+ # @return [ Mongo::Session, nil ] The session cached on this thread or nil.
383
+ #
384
+ # @since 6.4.0
385
+ def get_session
386
+ Thread.current[:session]
387
+ end
388
+
389
+ # Clear the cached session for this thread.
390
+ #
391
+ # @example Clear this thread's session.
392
+ # Threaded.clear_session
393
+ #
394
+ # @return [ nil ]
395
+ #
396
+ # @since 6.4.0
397
+ def clear_session
398
+ session = get_session
399
+ session.end_session if session
400
+ Thread.current[:session] = nil
401
+ end
328
402
  end
329
403
  end
@@ -153,7 +153,7 @@ module Mongoid
153
153
  def _root
154
154
  object = self
155
155
  while (object._parent) do object = object._parent; end
156
- object.with(@persistence_options) || self
156
+ object
157
157
  end
158
158
 
159
159
  # Is this document the root document of the hierarchy?
@@ -169,7 +169,6 @@ module Mongoid
169
169
  name = document.database_field_name(item)
170
170
  criteria = criteria.where(item => document.attributes[name])
171
171
  end
172
- criteria = criteria.with(document.persistence_options)
173
172
  criteria
174
173
  end
175
174
 
@@ -274,7 +273,7 @@ module Mongoid
274
273
  criteria = create_criteria(klass, document, attribute, value)
275
274
  criteria = criteria.merge(options[:conditions].call) if options[:conditions]
276
275
 
277
- if criteria.with(criteria.persistence_options).read(mode: :primary).exists?
276
+ if criteria.read(mode: :primary).exists?
278
277
  add_error(document, attribute, value)
279
278
  end
280
279
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- VERSION = "5.4.0"
3
+ VERSION = "6.4.8"
4
4
  end