mongoid 5.4.1 → 6.1.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 (260) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -3
  3. data/lib/config/locales/en.yml +19 -0
  4. data/lib/mongoid.rb +4 -4
  5. data/lib/mongoid/atomic.rb +2 -2
  6. data/lib/mongoid/atomic/modifiers.rb +8 -12
  7. data/lib/mongoid/attributes.rb +22 -21
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/cacheable.rb +36 -0
  10. data/lib/mongoid/changeable.rb +36 -0
  11. data/lib/mongoid/clients.rb +8 -63
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/storage_options.rb +1 -69
  14. data/lib/mongoid/composable.rb +29 -3
  15. data/lib/mongoid/config.rb +1 -0
  16. data/lib/mongoid/contextual/atomic.rb +5 -8
  17. data/lib/mongoid/contextual/map_reduce.rb +0 -4
  18. data/lib/mongoid/contextual/memory.rb +2 -2
  19. data/lib/mongoid/contextual/mongo.rb +40 -22
  20. data/lib/mongoid/contextual/none.rb +12 -0
  21. data/lib/mongoid/copyable.rb +13 -6
  22. data/lib/mongoid/criteria.rb +5 -2
  23. data/lib/mongoid/criteria/marshalable.rb +2 -2
  24. data/lib/mongoid/criteria/modifiable.rb +17 -1
  25. data/lib/mongoid/criteria/options.rb +25 -0
  26. data/lib/mongoid/criteria/queryable.rb +87 -0
  27. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  28. data/lib/mongoid/criteria/queryable/extensions.rb +28 -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/forwardable.rb +65 -0
  46. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  47. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  48. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  49. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  50. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  51. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  52. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  53. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  54. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  55. data/lib/mongoid/document.rb +30 -37
  56. data/lib/mongoid/errors.rb +2 -0
  57. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  58. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  59. data/lib/mongoid/errors/invalid_field.rb +2 -2
  60. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  61. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  62. data/lib/mongoid/evolvable.rb +1 -1
  63. data/lib/mongoid/extensions.rb +0 -4
  64. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  65. data/lib/mongoid/extensions/date.rb +4 -1
  66. data/lib/mongoid/extensions/decimal128.rb +3 -3
  67. data/lib/mongoid/extensions/hash.rb +1 -0
  68. data/lib/mongoid/extensions/string.rb +4 -3
  69. data/lib/mongoid/extensions/time.rb +4 -1
  70. data/lib/mongoid/fields/validators/macro.rb +18 -0
  71. data/lib/mongoid/findable.rb +2 -2
  72. data/lib/mongoid/indexable.rb +15 -13
  73. data/lib/mongoid/interceptable.rb +5 -22
  74. data/lib/mongoid/matchable.rb +13 -7
  75. data/lib/mongoid/matchable/all.rb +2 -2
  76. data/lib/mongoid/matchable/and.rb +3 -3
  77. data/lib/mongoid/matchable/default.rb +2 -2
  78. data/lib/mongoid/matchable/elem_match.rb +28 -0
  79. data/lib/mongoid/matchable/exists.rb +2 -2
  80. data/lib/mongoid/matchable/gt.rb +4 -2
  81. data/lib/mongoid/matchable/gte.rb +4 -2
  82. data/lib/mongoid/matchable/in.rb +2 -2
  83. data/lib/mongoid/matchable/lt.rb +4 -2
  84. data/lib/mongoid/matchable/lte.rb +4 -2
  85. data/lib/mongoid/matchable/ne.rb +2 -2
  86. data/lib/mongoid/matchable/nin.rb +2 -2
  87. data/lib/mongoid/matchable/or.rb +3 -3
  88. data/lib/mongoid/matchable/regexp.rb +3 -3
  89. data/lib/mongoid/matchable/size.rb +2 -2
  90. data/lib/mongoid/persistable.rb +3 -5
  91. data/lib/mongoid/persistable/creatable.rb +2 -2
  92. data/lib/mongoid/persistable/deletable.rb +1 -1
  93. data/lib/mongoid/persistable/settable.rb +1 -1
  94. data/lib/mongoid/persistable/updatable.rb +5 -12
  95. data/lib/mongoid/persistable/upsertable.rb +1 -1
  96. data/lib/mongoid/persistence_context.rb +215 -0
  97. data/lib/mongoid/query_cache.rb +3 -6
  98. data/lib/mongoid/relations/accessors.rb +3 -0
  99. data/lib/mongoid/relations/auto_save.rb +12 -4
  100. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  101. data/lib/mongoid/relations/counter_cache.rb +15 -5
  102. data/lib/mongoid/relations/eager.rb +6 -11
  103. data/lib/mongoid/relations/eager/base.rb +3 -3
  104. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  105. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  106. data/lib/mongoid/relations/embedded/batchable.rb +12 -36
  107. data/lib/mongoid/relations/embedded/in.rb +13 -1
  108. data/lib/mongoid/relations/embedded/many.rb +28 -10
  109. data/lib/mongoid/relations/embedded/one.rb +14 -1
  110. data/lib/mongoid/relations/macros.rb +9 -1
  111. data/lib/mongoid/relations/metadata.rb +3 -3
  112. data/lib/mongoid/relations/options.rb +2 -2
  113. data/lib/mongoid/relations/proxy.rb +1 -31
  114. data/lib/mongoid/relations/referenced/in.rb +19 -10
  115. data/lib/mongoid/relations/referenced/many.rb +23 -17
  116. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  117. data/lib/mongoid/relations/referenced/one.rb +15 -1
  118. data/lib/mongoid/relations/synchronization.rb +11 -11
  119. data/lib/mongoid/relations/touchable.rb +6 -3
  120. data/lib/mongoid/reloadable.rb +1 -1
  121. data/lib/mongoid/serializable.rb +1 -1
  122. data/lib/mongoid/traversable.rb +1 -1
  123. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  124. data/lib/mongoid/version.rb +1 -1
  125. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +14 -3
  126. data/spec/app/models/album.rb +5 -1
  127. data/spec/app/models/artist.rb +21 -0
  128. data/spec/app/models/book.rb +2 -1
  129. data/spec/app/models/dokument.rb +1 -0
  130. data/spec/app/models/ordered_post.rb +5 -0
  131. data/spec/app/models/oscar.rb +1 -2
  132. data/spec/app/models/page.rb +1 -1
  133. data/spec/app/models/person.rb +3 -3
  134. data/spec/app/models/princess.rb +2 -0
  135. data/spec/app/models/record.rb +1 -0
  136. data/spec/app/models/subscription.rb +1 -0
  137. data/spec/app/models/thing.rb +1 -1
  138. data/spec/config/mongoid.yml +15 -0
  139. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  140. data/spec/mongoid/atomic_spec.rb +17 -17
  141. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  142. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  143. data/spec/mongoid/attributes_spec.rb +90 -5
  144. data/spec/mongoid/cacheable_spec.rb +112 -0
  145. data/spec/mongoid/changeable_spec.rb +58 -0
  146. data/spec/mongoid/clients/factory_spec.rb +31 -3
  147. data/spec/mongoid/clients/options_spec.rb +382 -96
  148. data/spec/mongoid/clients_spec.rb +243 -101
  149. data/spec/mongoid/composable_spec.rb +7 -0
  150. data/spec/mongoid/config_spec.rb +67 -11
  151. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  152. data/spec/mongoid/contextual/mongo_spec.rb +165 -20
  153. data/spec/mongoid/contextual/none_spec.rb +15 -0
  154. data/spec/mongoid/copyable_spec.rb +13 -4
  155. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  156. data/spec/mongoid/criteria/options_spec.rb +29 -0
  157. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  158. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  159. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  160. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  161. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  162. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  163. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  164. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  165. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  166. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  167. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  168. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  169. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  170. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  171. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  172. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  173. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  174. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  175. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  176. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  177. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  178. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  179. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  180. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  181. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  182. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  183. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  184. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  185. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4174 -0
  186. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  187. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  188. data/spec/mongoid/criteria_spec.rb +152 -21
  189. data/spec/mongoid/document_spec.rb +37 -88
  190. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  191. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  192. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  193. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  194. data/spec/mongoid/extensions/date_spec.rb +2 -6
  195. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  196. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  197. data/spec/mongoid/extensions/float_spec.rb +8 -1
  198. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  199. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  200. data/spec/mongoid/extensions/object_spec.rb +11 -0
  201. data/spec/mongoid/extensions/string_spec.rb +21 -0
  202. data/spec/mongoid/extensions/time_spec.rb +2 -6
  203. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  204. data/spec/mongoid/findable_spec.rb +46 -1
  205. data/spec/mongoid/indexable_spec.rb +15 -3
  206. data/spec/mongoid/interceptable_spec.rb +68 -10
  207. data/spec/mongoid/matchable/all_spec.rb +4 -4
  208. data/spec/mongoid/matchable/and_spec.rb +10 -10
  209. data/spec/mongoid/matchable/default_spec.rb +12 -12
  210. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  211. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  212. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  213. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  214. data/spec/mongoid/matchable/in_spec.rb +5 -5
  215. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  216. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  217. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  218. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  219. data/spec/mongoid/matchable/or_spec.rb +7 -7
  220. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  221. data/spec/mongoid/matchable/size_spec.rb +3 -3
  222. data/spec/mongoid/matchable_spec.rb +173 -53
  223. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  224. data/spec/mongoid/persistable/deletable_spec.rb +16 -1
  225. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  226. data/spec/mongoid/persistable/savable_spec.rb +35 -30
  227. data/spec/mongoid/persistable/settable_spec.rb +45 -29
  228. data/spec/mongoid/persistable/updatable_spec.rb +184 -5
  229. data/spec/mongoid/persistence_context_spec.rb +680 -0
  230. data/spec/mongoid/positional_spec.rb +10 -10
  231. data/spec/mongoid/query_cache_spec.rb +89 -0
  232. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  233. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  234. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  235. data/spec/mongoid/relations/builders_spec.rb +37 -10
  236. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  237. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  238. data/spec/mongoid/relations/eager_spec.rb +40 -0
  239. data/spec/mongoid/relations/embedded/many_spec.rb +63 -47
  240. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  241. data/spec/mongoid/relations/macros_spec.rb +395 -7
  242. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  243. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +13 -25
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  247. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  248. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  249. data/spec/mongoid/reloadable_spec.rb +51 -0
  250. data/spec/mongoid/serializable_spec.rb +0 -50
  251. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  252. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +20 -11
  255. metadata +524 -469
  256. checksums.yaml.gz.sig +0 -0
  257. data.tar.gz.sig +0 -0
  258. data/lib/mongoid/clients/thread_options.rb +0 -19
  259. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  260. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 6193f790b2f66cf1e0632b9900555f6f5b36f9e519f01aa64c6286a58a2642f1
4
- data.tar.gz: 76559818003d501dd396d74bc7a1ef08b6617bcf09e64b8e5953cc5bdcac468b
2
+ SHA1:
3
+ metadata.gz: 8df15f3d764e3c19bcc5719c656f833ce258bb65
4
+ data.tar.gz: 335173b371125d1e84100af19293bccf459df5b8
5
5
  SHA512:
6
- metadata.gz: baa3aa0cbbf678a1d9c9ee2d029e32cab1701e3f6c40c464ec711b154dda2c4d6eb635a25a8604559a7deaa57e3dc35a18620595b1eadd3fcdda6e8fe7456660
7
- data.tar.gz: 61f0d82599f9053fb107de7b19dfdab43d92e42fcc2a83582ee8dd651e8b707f16ed55667cbd82be92fbb697a52093053452f4fa5c2148ad8fedeacd5f609201
6
+ metadata.gz: e6fabe8ac17c05be402c8dd42bff52a4158e0a0d0650cd36363a7439ea19e32d0a3b28427b85fb88749df2941d2ba5fa4c639aa74f9b70ef0e4875acd4438ae6
7
+ data.tar.gz: 40cf34caa79067109baeee5b434f8e2497c654a91248a73a220ac1ded8d685fbc3ea13adaa0e4335246af64f09ed4942848b5b3e6beacb966ae7f7250c655ac8
data/README.md CHANGED
@@ -21,17 +21,17 @@ Project Tracking
21
21
  Compatibility
22
22
  -------------
23
23
 
24
- Mongoid is tested against MRI 1.9.3, 2.0.0, 2.1.0. 2.2.0 and JRuby (1.9).
24
+ Mongoid is tested against MRI 2.2, 2.3 and JRuby (9.1).
25
25
 
26
26
  Documentation
27
27
  -------------
28
28
 
29
- Please see the [MongoDB website](http://docs.mongodb.org/ecosystem/tutorial/ruby-mongoid-tutorial/#ruby-mongoid-tutorial) for up-to-date documentation on 5.0.0:
29
+ Please see the [MongoDB website](http://docs.mongodb.org/ecosystem/tutorial/ruby-mongoid-tutorial/#ruby-mongoid-tutorial) for up-to-date documentation.
30
30
 
31
31
  License
32
32
  -------
33
33
 
34
- Copyright (c) 2009-2016 Durran Jordan
34
+ Copyright (c) 2009-2017 Durran Jordan
35
35
 
36
36
  Permission is hereby granted, free of charge, to any person obtaining
37
37
  a copy of this software and associated documentation files (the
@@ -177,6 +177,25 @@ en:
177
177
  collection. Double check the relation definitions and fix any
178
178
  instances where embedded documents are improperly referenced
179
179
  from other collections."
180
+ invalid_persistence_option:
181
+ message: "Invalid persistence option :%{invalid}."
182
+ summary: "The options used to change the persistence context must be one
183
+ of the valid options for a mongo client, or a collection name."
184
+ resolution: "Valid options are: %{valid}, make sure these are the ones
185
+ you are using."
186
+ invalid_relation:
187
+ message: "Defining a relation named '%{name}' is not allowed."
188
+ summary: "Defining this relation would override the method '%{name}',
189
+ which would cause issues with expectations around the original
190
+ method and cause extremely hard to debug issues. The original
191
+ method was defined in:\n
192
+ \_\_Object: %{origin}\n
193
+ \_\_File: %{file}\n
194
+ \_\_Line: %{line}"
195
+ resolution: "Use Mongoid.destructive_fields to see what names are not
196
+ allowed, and don't use these names. These include names that also
197
+ conflict with core Ruby methods on Object, Module, Enumerable, or
198
+ included gems that inject methods into these or Mongoid internals."
180
199
  invalid_scope:
181
200
  message: "Defining a scope of value %{value} on %{klass} is not
182
201
  allowed."
data/lib/mongoid.rb CHANGED
@@ -12,11 +12,11 @@ require "active_support/inflector"
12
12
  require "active_support/time_with_zone"
13
13
  require "active_model"
14
14
 
15
- require "origin"
16
15
  require "mongo"
17
16
 
18
17
  require "mongoid/version"
19
18
  require "mongoid/config"
19
+ require "mongoid/persistence_context"
20
20
  require "mongoid/loggable"
21
21
  require "mongoid/clients"
22
22
  require "mongoid/document"
@@ -65,7 +65,7 @@ module Mongoid
65
65
  #
66
66
  # @return [ Mongo::Client ] The default client.
67
67
  #
68
- # @since 3.0.0
68
+ # @since 5.0.0
69
69
  def default_client
70
70
  Clients.default
71
71
  end
@@ -77,7 +77,7 @@ module Mongoid
77
77
  #
78
78
  # @return [ true ] True.
79
79
  #
80
- # @since 3.1.0
80
+ # @since 5.0.0
81
81
  def disconnect_clients
82
82
  Clients.disconnect
83
83
  end
@@ -89,7 +89,7 @@ module Mongoid
89
89
  #
90
90
  # @return [ Mongo::Client ] The named client.
91
91
  #
92
- # @since 3.0.0
92
+ # @since 5.0.0
93
93
  def client(name)
94
94
  Clients.with_name(name)
95
95
  end
@@ -222,7 +222,7 @@ module Mongoid
222
222
  #
223
223
  # @since 2.1.0
224
224
  def atomic_pushes
225
- pushable? ? { atomic_position => as_document } : {}
225
+ pushable? ? { atomic_position => as_attributes } : {}
226
226
  end
227
227
 
228
228
  # Get all the attributes that need to be set.
@@ -234,7 +234,7 @@ module Mongoid
234
234
  #
235
235
  # @since 2.1.0
236
236
  def atomic_sets
237
- updateable? ? setters : settable? ? { atomic_path => as_document } : {}
237
+ updateable? ? setters : settable? ? { atomic_path => as_attributes } : {}
238
238
  end
239
239
 
240
240
  # Get all the attributes that need to be unset.
@@ -68,7 +68,7 @@ module Mongoid
68
68
  modifications.each_pair do |field, value|
69
69
  push_fields[field] = field
70
70
  mods = push_conflict?(field) ? conflicting_pushes : pushes
71
- add_operation(mods, field, {'$each' => Array.wrap(value)})
71
+ add_operation(mods, field, Array.wrap(value))
72
72
  end
73
73
  end
74
74
 
@@ -118,12 +118,8 @@ module Mongoid
118
118
  # @since 2.2.0
119
119
  def add_operation(mods, field, value)
120
120
  if mods.has_key?(field)
121
- if mods[field].is_a?(Array)
122
- value.each do |val|
123
- mods[field].push(val)
124
- end
125
- elsif mods[field]['$each']
126
- mods[field]['$each'].concat(value['$each'])
121
+ value.each do |val|
122
+ mods[field].push(val)
127
123
  end
128
124
  else
129
125
  mods[field] = value
@@ -194,7 +190,7 @@ module Mongoid
194
190
  #
195
191
  # @since 2.2.0
196
192
  def conflicting_pushes
197
- conflicts["$push"] ||= {}
193
+ conflicts["$pushAll"] ||= {}
198
194
  end
199
195
 
200
196
  # Get the conflicting set modifications.
@@ -281,16 +277,16 @@ module Mongoid
281
277
  self["$pull"] ||= {}
282
278
  end
283
279
 
284
- # Get the $push/$each operations or initialize a new one.
280
+ # Get the $pushAll operations or intialize a new one.
285
281
  #
286
- # @example Get the $push/$each operations.
282
+ # @example Get the $pushAll operations.
287
283
  # modifiers.pushes
288
284
  #
289
- # @return [ Hash ] The $push/$each operations.
285
+ # @return [ Hash ] The $pushAll operations.
290
286
  #
291
287
  # @since 2.1.0
292
288
  def pushes
293
- self["$push"] ||= {}
289
+ self["$pushAll"] ||= {}
294
290
  end
295
291
 
296
292
  # Get the $set operations or intialize a new one.
@@ -139,14 +139,12 @@ module Mongoid
139
139
  #
140
140
  # @since 1.0.0
141
141
  def remove_attribute(name)
142
- access = name.to_s
143
- unless attribute_writable?(name)
144
- raise Errors::ReadonlyAttribute.new(name, :nil)
145
- end
146
- _assigning do
147
- attribute_will_change!(access)
148
- delayed_atomic_unsets[atomic_attribute_name(access)] = [] unless new_record?
149
- attributes.delete(access)
142
+ as_writable_attribute!(name) do |access|
143
+ _assigning do
144
+ attribute_will_change!(access)
145
+ delayed_atomic_unsets[atomic_attribute_name(access)] = [] unless new_record?
146
+ attributes.delete(access)
147
+ end
150
148
  end
151
149
  end
152
150
 
@@ -165,8 +163,7 @@ module Mongoid
165
163
  #
166
164
  # @since 1.0.0
167
165
  def write_attribute(name, value)
168
- access = database_field_name(name.to_s)
169
- if attribute_writable?(access)
166
+ as_writable_attribute!(name) do |access|
170
167
  _assigning do
171
168
  validate_attribute_value(access, value)
172
169
  localized = fields[access].try(:localized?)
@@ -244,22 +241,26 @@ module Mongoid
244
241
  (selection.values.first == 1 && !selection_included?(name, selection, field))
245
242
  end
246
243
 
244
+ # Return type-casted attributes.
245
+ #
246
+ # @example Type-casted attributes.
247
+ # document.typed_attributes
248
+ #
249
+ # @return [ Object ] The hash with keys and values of the type-casted attributes.
250
+ #
251
+ # @since 6.1.0
252
+ def typed_attributes
253
+ attribute_names.map { |name| [name, send(name)] }.to_h
254
+ end
255
+
247
256
  private
248
257
 
249
258
  def selection_excluded?(name, selection, field)
250
- if field && field.localized?
251
- selection["#{name}.#{::I18n.locale}"] == 0
252
- else
253
- selection[name] == 0
254
- end
259
+ selection[name] == 0
255
260
  end
256
261
 
257
262
  def selection_included?(name, selection, field)
258
- if field && field.localized?
259
- selection.key?("#{name}.#{::I18n.locale}")
260
- else
261
- selection.key?(name) || selection.keys.collect { |k| k.partition('.').first }.include?(name)
262
- end
263
+ selection.key?(name) || selection.keys.collect { |k| k.partition('.').first }.include?(name)
263
264
  end
264
265
 
265
266
  # Does the string contain dot syntax for accessing hashes?
@@ -346,7 +347,7 @@ module Mongoid
346
347
  end
347
348
 
348
349
  def lookup_attribute_presence(name, value)
349
- if localized_fields.has_key?(name)
350
+ if localized_fields.has_key?(name) && value
350
351
  value = localized_fields[name].send(:lookup, value)
351
352
  end
352
353
  value.present?
@@ -22,10 +22,32 @@ module Mongoid
22
22
  # readonly.
23
23
  #
24
24
  # @since 3.0.0
25
+ #
26
+ # @deprecated Use #as_writable_attribute! instead.
25
27
  def attribute_writable?(name)
26
28
  new_record? || !readonly_attributes.include?(database_field_name(name))
27
29
  end
28
30
 
31
+ private
32
+
33
+ def as_writable_attribute!(name, value = :nil)
34
+ normalized_name = database_field_name(name)
35
+ if new_record? || (!readonly_attributes.include?(normalized_name) && _loaded?(normalized_name))
36
+ yield(normalized_name)
37
+ else
38
+ raise Errors::ReadonlyAttribute.new(name, value)
39
+ end
40
+ end
41
+
42
+ def _loaded?(name)
43
+ __selected_fields.nil? || projected_field?(name)
44
+ end
45
+
46
+ def projected_field?(name)
47
+ projected = (__selected_fields || {}).keys.select { |f| __selected_fields[f] == 1 }
48
+ projected.empty? || projected.include?(name)
49
+ end
50
+
29
51
  module ClassMethods
30
52
 
31
53
  # Defines an attribute as readonly. This will ensure that the value for
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+
4
+ # Encapsulates behaviour around caching.
5
+ #
6
+ # @since 6.0.0
7
+ module Cacheable
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ cattr_accessor :cache_timestamp_format, instance_writer: false
12
+ self.cache_timestamp_format = :nsec
13
+ end
14
+
15
+ # Print out the cache key. This will append different values on the
16
+ # plural model name.
17
+ #
18
+ # If new_record? - will append /new
19
+ # If not - will append /id-updated_at.to_s(cache_timestamp_format)
20
+ # Without updated_at - will append /id
21
+ #
22
+ # This is usually called insode a cache() block
23
+ #
24
+ # @example Returns the cache key
25
+ # document.cache_key
26
+ #
27
+ # @return [ String ] the string with or without updated_at
28
+ #
29
+ # @since 2.4.0
30
+ def cache_key
31
+ return "#{model_key}/new" if new_record?
32
+ return "#{model_key}/#{id}-#{updated_at.utc.to_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
33
+ "#{model_key}/#{id}"
34
+ end
35
+ end
36
+ end
@@ -278,6 +278,8 @@ module Mongoid
278
278
  create_dirty_previous_value_accessor(name, meth)
279
279
  create_dirty_reset(name, meth)
280
280
  create_dirty_reset_to_default(name, meth)
281
+ create_dirty_previously_changed?(name, meth)
282
+ create_dirty_previous_change(name, meth)
281
283
  end
282
284
 
283
285
  # Creates the dirty change accessor.
@@ -398,6 +400,40 @@ module Mongoid
398
400
  end
399
401
  end
400
402
  end
403
+
404
+ # Creates the dirty change check.
405
+ #
406
+ # @example Create the dirty change check.
407
+ # Model.create_dirty_previously_changed?("name", "alias")
408
+ #
409
+ # @param [ String ] name The attribute name.
410
+ # @param [ String ] meth The name of the accessor.
411
+ #
412
+ # @since 6.0.0
413
+ def create_dirty_previously_changed?(name, meth)
414
+ generated_methods.module_eval do
415
+ re_define_method("#{meth}_previously_changed?") do
416
+ previous_changes.keys.include?(name)
417
+ end
418
+ end
419
+ end
420
+
421
+ # Creates the dirty change accessor.
422
+ #
423
+ # @example Create the dirty change accessor.
424
+ # Model.create_dirty_previous_change("name", "alias")
425
+ #
426
+ # @param [ String ] name The attribute name.
427
+ # @param [ String ] meth The name of the accessor.
428
+ #
429
+ # @since 6.0.0
430
+ def create_dirty_previous_change(name, meth)
431
+ generated_methods.module_eval do
432
+ re_define_method("#{meth}_previous_change") do
433
+ previous_changes[name]
434
+ end
435
+ end
436
+ end
401
437
  end
402
438
  end
403
439
  end
@@ -2,14 +2,12 @@
2
2
  require "mongoid/clients/factory"
3
3
  require "mongoid/clients/validators"
4
4
  require "mongoid/clients/storage_options"
5
- require "mongoid/clients/thread_options"
6
5
  require "mongoid/clients/options"
7
6
 
8
7
  module Mongoid
9
8
  module Clients
10
9
  extend ActiveSupport::Concern
11
10
  include StorageOptions
12
- include ThreadOptions
13
11
  include Options
14
12
 
15
13
  class << self
@@ -35,7 +33,7 @@ module Mongoid
35
33
  #
36
34
  # @since 3.0.0
37
35
  def default
38
- clients[:default] ||= Clients::Factory.default
36
+ with_name(:default)
39
37
  end
40
38
 
41
39
  # Disconnect all active clients.
@@ -63,7 +61,11 @@ module Mongoid
63
61
  #
64
62
  # @since 3.0.0
65
63
  def with_name(name)
66
- clients[name.to_sym] ||= Clients::Factory.create(name)
64
+ name_as_symbol = name.to_sym
65
+ return clients[name_as_symbol] if clients[name_as_symbol]
66
+ CREATE_LOCK.synchronize do
67
+ clients[name_as_symbol] ||= Clients::Factory.create(name)
68
+ end
67
69
  end
68
70
 
69
71
  def set(name, client)
@@ -73,67 +75,10 @@ module Mongoid
73
75
  def clients
74
76
  @clients ||= {}
75
77
  end
76
- end
77
-
78
- # Get the collection for this model from the client. Will check for an
79
- # overridden collection name from the store_in macro or the collection
80
- # with a pluralized model name.
81
- #
82
- # @example Get the model's collection.
83
- # Model.collection
84
- #
85
- # @return [ Mongo::Collection ] The collection.
86
- #
87
- # @since 3.0.0
88
- def collection
89
- mongo_client[collection_name]
90
- end
91
78
 
92
- def mongo_client
93
- super || self.class.mongo_client
94
- end
79
+ private
95
80
 
96
- def collection_name
97
- super || self.class.collection_name
98
- end
99
-
100
- module ClassMethods
101
-
102
- # Get the client for this model. This is determined in the following order:
103
- #
104
- # 1. Any custom configuration provided by the 'store_in' macro.
105
- # 2. The 'default' client as provided in the mongoid.yml
106
- #
107
- # @example Get the client.
108
- # Model.mongo_client
109
- #
110
- # @return [ Mongo::Client ] The default mongo client.
111
- #
112
- # @since 3.0.0
113
- def mongo_client
114
- return client_with_options if client_with_options
115
- client = Clients.with_name(client_name)
116
- opts = self.persistence_options ? self.persistence_options.dup : {}
117
- if defined?(Mongo::Client::VALID_OPTIONS)
118
- opts.reject! { |k, v| !Mongo::Client::VALID_OPTIONS.include?(k.to_sym) }
119
- end
120
- opts.merge!(database: database_name) unless client.database.name.to_sym == database_name.to_sym
121
- client.with(opts)
122
- end
123
-
124
- # Get the collection for this model from the client. Will check for an
125
- # overridden collection name from the store_in macro or the collection
126
- # with a pluralized model name.
127
- #
128
- # @example Get the model's collection.
129
- # Model.collection
130
- #
131
- # @return [ Mongo::Collection ] The collection.
132
- #
133
- # @since 3.0.0
134
- def collection
135
- mongo_client[collection_name]
136
- end
81
+ CREATE_LOCK = Mutex.new
137
82
  end
138
83
  end
139
84
  end