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
@@ -8,12 +8,12 @@ module Mongoid
8
8
  # Return true if the attribute and first value in the hash are equal.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If the values match.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  first = first(value)
18
18
  return false if first.is_a?(Array) && first.empty?
19
19
 
@@ -8,19 +8,19 @@ module Mongoid
8
8
  # Does the supplied query match the attribute?
9
9
  #
10
10
  # @example Does this match?
11
- # matcher.matches?([ { field => value } ])
11
+ # matcher._matches?([ { field => value } ])
12
12
  #
13
13
  # @param [ Array ] conditions The or expression.
14
14
  #
15
15
  # @return [ true, false ] True if matches, false if not.
16
16
  #
17
17
  # @since 2.3.0
18
- def matches?(conditions)
18
+ def _matches?(conditions)
19
19
  conditions.each do |condition|
20
20
  condition.keys.each do |k|
21
21
  key = k
22
22
  value = condition[k]
23
- return false unless document.matches?(key => value)
23
+ return false unless document._matches?(key => value)
24
24
  end
25
25
  end
26
26
  true
@@ -24,14 +24,14 @@ module Mongoid
24
24
  # if the value is included.
25
25
  #
26
26
  # @example Does this value match?
27
- # default.matches?("value")
27
+ # default._matches?("value")
28
28
  #
29
29
  # @param [ Object ] value The value to check if it matches.
30
30
  #
31
31
  # @return [ true, false ] True if matches, false if not.
32
32
  #
33
33
  # @since 1.0.0
34
- def matches?(value)
34
+ def _matches?(value)
35
35
  attribute.is_a?(Array) && !value.is_a?(Array) ? attribute.any? { |_attribute| value === _attribute } : value === attribute
36
36
  end
37
37
 
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Matchable
4
+
5
+ class ElemMatch < Default
6
+
7
+ # Return true if a given predicate matches a sub document entirely
8
+ #
9
+ # @example Do the values match?
10
+ # matcher._matches?({"$elemMatch" => {"a" => 1, "b" => 2}})
11
+ #
12
+ # @param [ Hash ] value The values to check.
13
+ #
14
+ # @return [ true, false ] If the values match.
15
+ def _matches?(value)
16
+ if !@attribute.is_a?(Array) || !value.kind_of?(Hash) || !value["$elemMatch"].kind_of?(Hash)
17
+ return false
18
+ end
19
+
20
+ return @attribute.any? do |sub_document|
21
+ value["$elemMatch"].all? do |k, v|
22
+ Matchable.matcher(sub_document, k, v)._matches?(v)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -10,12 +10,12 @@ module Mongoid
10
10
  # non-existence.
11
11
  #
12
12
  # @example Does anything exist?
13
- # matcher.matches?({ :key => 10 })
13
+ # matcher._matches?({ :key => 10 })
14
14
  #
15
15
  # @param [ Hash ] value The values to check.
16
16
  #
17
17
  # @return [ true, false ] If a value exists.
18
- def matches?(value)
18
+ def _matches?(value)
19
19
  @attribute.nil? != value.values.first
20
20
  end
21
21
  end
@@ -8,13 +8,15 @@ module Mongoid
8
8
  # Return true if the attribute is greater than the value.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  determine(value, :>)
18
+ rescue ArgumentError
19
+ false
18
20
  end
19
21
  end
20
22
  end
@@ -8,13 +8,15 @@ module Mongoid
8
8
  # Return true if the attribute is greater than or equal to the value.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  determine(value, :>=)
18
+ rescue ArgumentError
19
+ false
18
20
  end
19
21
  end
20
22
  end
@@ -8,12 +8,12 @@ module Mongoid
8
8
  # Return true if the attribute is in the values.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  attribute_array = @attribute.nil? ? [nil] : Array.wrap(@attribute)
18
18
  value.values.first.any? do |e|
19
19
  attribute_array.any? { |_attribute| e === _attribute }
@@ -8,13 +8,15 @@ module Mongoid
8
8
  # Return true if the attribute is less than the value.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  determine(value, :<)
18
+ rescue ArgumentError
19
+ false
18
20
  end
19
21
  end
20
22
  end
@@ -8,13 +8,15 @@ module Mongoid
8
8
  # Return true if the attribute is less than or equal to the value.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  determine(value, :<=)
18
+ rescue ArgumentError
19
+ false
18
20
  end
19
21
  end
20
22
  end
@@ -8,12 +8,12 @@ module Mongoid
8
8
  # Return true if the attribute and first value are not equal.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  !super(value.values.first)
18
18
  end
19
19
  end
@@ -8,12 +8,12 @@ module Mongoid
8
8
  # Return true if the attribute is not in the value list.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  attribute_array = @attribute.nil? ? [nil] : Array.wrap(@attribute)
18
18
  attribute_array.none? { |e| value.values.first.include?(e) }
19
19
  end
@@ -8,20 +8,20 @@ module Mongoid
8
8
  # Does the supplied query match the attribute?
9
9
  #
10
10
  # @example Does this match?
11
- # matcher.matches?("$or" => [ { field => value } ])
11
+ # matcher._matches?("$or" => [ { field => value } ])
12
12
  #
13
13
  # @param [ Array ] conditions The or expression.
14
14
  #
15
15
  # @return [ true, false ] True if matches, false if not.
16
16
  #
17
17
  # @since 2.0.0.rc.7
18
- def matches?(conditions)
18
+ def _matches?(conditions)
19
19
  conditions.each do |condition|
20
20
  res = true
21
21
  condition.keys.each do |k|
22
22
  key = k
23
23
  value = condition[k]
24
- res &&= document.matches?(key => value)
24
+ res &&= document._matches?(key => value)
25
25
  break unless res
26
26
  end
27
27
  return res if res
@@ -7,15 +7,15 @@ module Mongoid
7
7
  # Does the supplied query match the attribute?
8
8
  #
9
9
  # @example Does this match?
10
- # matcher.matches?(/^Em/)
11
- # matcher.matches?(BSON::Regex::Raw.new("^Em"))
10
+ # matcher._matches?(/^Em/)
11
+ # matcher._matches?(BSON::Regex::Raw.new("^Em"))
12
12
  #
13
13
  # @param [ BSON::Regexp::Raw, Regexp ] regexp The regular expression object.
14
14
  #
15
15
  # @return [ true, false ] True if matches, false if not.
16
16
  #
17
17
  # @since 5.2.1
18
- def matches?(regexp)
18
+ def _matches?(regexp)
19
19
  if native_regexp = regexp.try(:compile)
20
20
  super(native_regexp)
21
21
  else
@@ -8,12 +8,12 @@ module Mongoid
8
8
  # Return true if the attribute size is equal to the first value.
9
9
  #
10
10
  # @example Do the values match?
11
- # matcher.matches?({ :key => 10 })
11
+ # matcher._matches?({ :key => 10 })
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
15
  # @return [ true, false ] If a value exists.
16
- def matches?(value)
16
+ def _matches?(value)
17
17
  @attribute.size == value.values.first
18
18
  end
19
19
  end
@@ -162,12 +162,10 @@ module Mongoid
162
162
  # @since 4.0.0
163
163
  def process_atomic_operations(operations)
164
164
  operations.each do |field, value|
165
- unless attribute_writable?(field)
166
- raise Errors::ReadonlyAttribute.new(field, value)
165
+ as_writable_attribute!(field, value) do |access|
166
+ yield(access, value)
167
+ remove_change(access)
167
168
  end
168
- normalized = database_field_name(field)
169
- yield(normalized, value)
170
- remove_change(normalized)
171
169
  end
172
170
  end
173
171
 
@@ -42,7 +42,7 @@ module Mongoid
42
42
  #
43
43
  # @since 2.1.0
44
44
  def atomic_inserts
45
- { atomic_insert_modifier => { atomic_position => as_document }}
45
+ { atomic_insert_modifier => { atomic_position => as_attributes }}
46
46
  end
47
47
 
48
48
  # Insert the embedded document.
@@ -76,7 +76,7 @@ module Mongoid
76
76
  #
77
77
  # @since 4.0.0
78
78
  def insert_as_root
79
- collection.insert_one(as_document)
79
+ collection.insert_one(as_attributes)
80
80
  end
81
81
 
82
82
  # Post process an insert, which sets the new record attribute to false
@@ -137,7 +137,7 @@ module Mongoid
137
137
  # @since 1.0.0
138
138
  def delete_all(conditions = {})
139
139
  selector = hereditary? ? conditions.merge(_type: name) : conditions
140
- collection.find(selector).delete_many.deleted_count
140
+ where(selector).delete
141
141
  end
142
142
  end
143
143
  end
@@ -28,7 +28,7 @@ module Mongoid
28
28
 
29
29
  if fields[field] && fields[field].type == Hash && attributes.key?(field)
30
30
  merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
31
- value = attributes[field].merge(field_and_value_hash[field], &merger)
31
+ value = (attributes[field] || {}).merge(field_and_value_hash[field], &merger)
32
32
  process_attribute(field.to_s, value)
33
33
  else
34
34
  process_attribute(field.to_s, field_and_value_hash[field])
@@ -24,17 +24,11 @@ module Mongoid
24
24
  #
25
25
  # @since 2.0.0
26
26
  def update_attribute(name, value)
27
- normalized = name.to_s
28
- unless attribute_writable?(normalized)
29
- raise Errors::ReadonlyAttribute.new(normalized, value)
27
+ as_writable_attribute!(name, value) do |access|
28
+ normalized = name.to_s
29
+ process_attribute(normalized, value)
30
+ save(validate: false)
30
31
  end
31
- setter = "#{normalized}="
32
- if respond_to?(setter)
33
- send(setter, value)
34
- else
35
- write_attribute(database_field_name(normalized), value)
36
- end
37
- save(validate: false)
38
32
  end
39
33
 
40
34
  # Update the document attributes in the database.
@@ -135,11 +129,10 @@ module Mongoid
135
129
  #
136
130
  # @since 1.0.0
137
131
  def update_document(options = {})
138
- raise Errors::ReadonlyDocument.new(self.class) if readonly?
139
132
  prepare_update(options) do
140
133
  updates, conflicts = init_atomic_updates
141
134
  unless updates.empty?
142
- coll = _root.collection
135
+ coll = collection(_root)
143
136
  selector = atomic_selector
144
137
  coll.find(selector).update_one(positionally(selector, updates))
145
138
  conflicts.each_pair do |key, value|
@@ -21,7 +21,7 @@ module Mongoid
21
21
  # @since 3.0.0
22
22
  def upsert(options = {})
23
23
  prepare_upsert(options) do
24
- collection.find(atomic_selector).update_one(as_document, upsert: true)
24
+ collection.find(atomic_selector).update_one(as_attributes, upsert: true)
25
25
  end
26
26
  end
27
27
 
@@ -0,0 +1,215 @@
1
+ module Mongoid
2
+
3
+ # Object encapsulating logic for setting/getting a collection and database name
4
+ # and a client with particular options to use when persisting models.
5
+ #
6
+ # @since 6.0.0
7
+ class PersistenceContext
8
+ extend Forwardable
9
+
10
+ # Delegate the cluster method to the client.
11
+ def_delegators :client, :cluster
12
+
13
+ # Delegate the storage options method to the object.
14
+ def_delegators :@object, :storage_options
15
+
16
+ # The options defining this persistence context.
17
+ #
18
+ # @return [ Hash ] The persistence context options.
19
+ #
20
+ # @since 6.0.0
21
+ attr_reader :options
22
+
23
+ # Extra options in addition to driver client options that determine the
24
+ # persistence context.
25
+ #
26
+ # @return [ Array<Symbol> ] The list of extra options besides client options
27
+ # that determine the persistence context.
28
+ #
29
+ # @since 6.0.0
30
+ EXTRA_OPTIONS = [ :client,
31
+ :collection
32
+ ].freeze
33
+
34
+ # The full list of valid persistence context options.
35
+ #
36
+ # @return [ Array<Symbol> ] The full list of options defining the persistence
37
+ # context.
38
+ #
39
+ # @since 6.0.0
40
+ VALID_OPTIONS = ( Mongo::Client::VALID_OPTIONS + EXTRA_OPTIONS ).freeze
41
+
42
+ # Initialize the persistence context object.
43
+ #
44
+ # @example Create a new persistence context.
45
+ # PersistenceContext.new(model, collection: 'other')
46
+ #
47
+ # @param [ Object ] object The class or model instance for which a persistence context
48
+ # should be created.
49
+ # @param [ Hash ] opts The persistence context options.
50
+ #
51
+ # @since 6.0.0
52
+ def initialize(object, opts = {})
53
+ @object = object
54
+ set_options!(opts)
55
+ end
56
+
57
+ # Get the collection for this persistence context.
58
+ #
59
+ # @example Get the collection for this persistence context.
60
+ # context.collection
61
+ #
62
+ # @param [ Object ] parent The parent object whose collection name is used
63
+ # instead of this persistence context's collection name.
64
+ #
65
+ # @return [ Mongo::Collection ] The collection for this persistence
66
+ # context.
67
+ #
68
+ # @since 6.0.0
69
+ def collection(parent = nil)
70
+ parent ? parent.collection.with(client_options) : client[collection_name.to_sym]
71
+ end
72
+
73
+ # Get the collection name for this persistence context.
74
+ #
75
+ # @example Get the collection name for this persistence context.
76
+ # context.collection_name
77
+ #
78
+ # @return [ String ] The collection name for this persistence
79
+ # context.
80
+ #
81
+ # @since 6.0.0
82
+ def collection_name
83
+ @collection_name ||= (__evaluate__(options[:collection] ||
84
+ storage_options[:collection]))
85
+ end
86
+
87
+ # Get the database name for this persistence context.
88
+ #
89
+ # @example Get the database name for this persistence context.
90
+ # context.database_name
91
+ #
92
+ # @return [ String ] The database name for this persistence
93
+ # context.
94
+ #
95
+ # @since 6.0.0
96
+ def database_name
97
+ __evaluate__(database_name_option) || client.database.name
98
+ end
99
+
100
+ # Get the client for this persistence context.
101
+ #
102
+ # @example Get the client for this persistence context.
103
+ # context.client
104
+ #
105
+ # @return [ Mongo::Client ] The client for this persistence
106
+ # context.
107
+ #
108
+ # @since 6.0.0
109
+ def client
110
+ @client ||= (client = Clients.with_name(client_name)
111
+ client = client.use(database_name) if database_name_option
112
+ client.with(client_options))
113
+ end
114
+
115
+ # Determine if this persistence context is equal to another.
116
+ #
117
+ # @example Compare two persistence contexts.
118
+ # context == other_context
119
+ #
120
+ # @param [ Object ] other The object to be compared with this one.
121
+ #
122
+ # @return [ true, false ] Whether the two persistence contexts are equal.
123
+ #
124
+ # @since 6.0.0
125
+ def ==(other)
126
+ return false unless other.is_a?(PersistenceContext)
127
+ options == other.options
128
+ end
129
+
130
+ private
131
+
132
+ def client_name
133
+ @client_name ||= options[:client] ||
134
+ Threaded.client_override ||
135
+ storage_options && __evaluate__(storage_options[:client])
136
+ end
137
+
138
+ def set_options!(opts)
139
+ @options ||= opts.each.reduce({}) do |_options, (key, value)|
140
+ unless VALID_OPTIONS.include?(key.to_sym)
141
+ raise Errors::InvalidPersistenceOption.new(key.to_sym, VALID_OPTIONS)
142
+ end
143
+ value ? _options.merge!(key => value) : _options
144
+ end
145
+ end
146
+
147
+ def __evaluate__(name)
148
+ return nil unless name
149
+ name.respond_to?(:call) ? name.call.to_sym : name.to_sym
150
+ end
151
+
152
+ def client_options
153
+ @client_options ||= options.select do |k, v|
154
+ Mongo::Client::VALID_OPTIONS.include?(k.to_sym)
155
+ end
156
+ end
157
+
158
+ def database_name_option
159
+ @database_name_option ||= options[:database] ||
160
+ Threaded.database_override ||
161
+ storage_options && storage_options[:database]
162
+ end
163
+
164
+ class << self
165
+
166
+ # Set the persistence context for a particular class or model instance.
167
+ #
168
+ # @example Set the persistence context for a class or model instance.
169
+ # PersistenceContext.set(model)
170
+ #
171
+ # @param [ Object ] object The class or model instance.
172
+ # @param [ Hash, Mongoid::PersistenceContext ] options_or_context The persistence
173
+ # options or a persistence context object.
174
+ #
175
+ # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
176
+ #
177
+ # @since 6.0.0
178
+ def set(object, options_or_context)
179
+ context = PersistenceContext.new(object, options_or_context.is_a?(PersistenceContext) ?
180
+ options_or_context.options : options_or_context)
181
+ Thread.current["[mongoid][#{object.object_id}]:context"] = context
182
+ end
183
+
184
+ # Get the persistence context for a particular class or model instance.
185
+ #
186
+ # @example Get the persistence context for a class or model instance.
187
+ # PersistenceContext.get(model)
188
+ #
189
+ # @param [ Object ] object The class or model instance.
190
+ #
191
+ # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
192
+ #
193
+ # @since 6.0.0
194
+ def get(object)
195
+ Thread.current["[mongoid][#{object.object_id}]:context"]
196
+ end
197
+
198
+ # Get the persistence context for a particular class or model instance.
199
+ #
200
+ # @example Get the persistence context for a class or model instance.
201
+ # PersistenceContext.get(model)
202
+ #
203
+ # @param [ Class, Object ] object The class or model instance.
204
+ # @param [ Mongo::Cluster ] cluster The original cluster before this context was used.
205
+ #
206
+ # @since 6.0.0
207
+ def clear(object, cluster = nil)
208
+ if context = get(object)
209
+ context.client.close unless (context.cluster.equal?(cluster) || cluster.nil?)
210
+ end
211
+ Thread.current["[mongoid][#{object.object_id}]:context"] = nil
212
+ end
213
+ end
214
+ end
215
+ end