mongoid 5.4.1 → 6.0.0.beta

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 (264) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/config/locales/en.yml +23 -16
  5. data/lib/mongoid.rb +4 -9
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/modifiers.rb +8 -12
  8. data/lib/mongoid/attributes.rb +9 -11
  9. data/lib/mongoid/attributes/dynamic.rb +5 -6
  10. data/lib/mongoid/attributes/nested.rb +1 -1
  11. data/lib/mongoid/attributes/processing.rb +4 -0
  12. data/lib/mongoid/attributes/readonly.rb +22 -0
  13. data/lib/mongoid/cacheable.rb +36 -0
  14. data/lib/mongoid/changeable.rb +37 -1
  15. data/lib/mongoid/clients.rb +0 -63
  16. data/lib/mongoid/clients/factory.rb +0 -2
  17. data/lib/mongoid/clients/options.rb +54 -249
  18. data/lib/mongoid/clients/storage_options.rb +1 -69
  19. data/lib/mongoid/composable.rb +26 -2
  20. data/lib/mongoid/config.rb +1 -1
  21. data/lib/mongoid/config/options.rb +1 -1
  22. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -0
  23. data/lib/mongoid/contextual/atomic.rb +6 -9
  24. data/lib/mongoid/contextual/geo_near.rb +2 -3
  25. data/lib/mongoid/contextual/map_reduce.rb +97 -24
  26. data/lib/mongoid/contextual/memory.rb +7 -4
  27. data/lib/mongoid/contextual/mongo.rb +63 -54
  28. data/lib/mongoid/contextual/none.rb +2 -2
  29. data/lib/mongoid/copyable.rb +19 -19
  30. data/lib/mongoid/criteria.rb +5 -4
  31. data/lib/mongoid/criteria/findable.rb +2 -3
  32. data/lib/mongoid/criteria/includable.rb +63 -16
  33. data/lib/mongoid/criteria/marshalable.rb +2 -2
  34. data/lib/mongoid/criteria/modifiable.rb +17 -1
  35. data/lib/mongoid/criteria/options.rb +25 -0
  36. data/lib/mongoid/criteria/queryable.rb +86 -0
  37. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  38. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  39. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  40. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  41. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  42. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  43. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  44. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  45. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  47. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  48. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  49. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +45 -0
  50. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  51. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  52. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  53. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  54. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  55. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  56. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  57. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  58. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  59. data/lib/mongoid/criteria/queryable/optional.rb +411 -0
  60. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  61. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  62. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  63. data/lib/mongoid/criteria/queryable/selector.rb +196 -0
  64. data/lib/mongoid/criteria/queryable/smash.rb +103 -0
  65. data/lib/mongoid/document.rb +9 -23
  66. data/lib/mongoid/errors.rb +2 -1
  67. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  68. data/lib/mongoid/errors/delete_restriction.rb +2 -2
  69. data/lib/mongoid/errors/invalid_field.rb +2 -2
  70. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  71. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  72. data/lib/mongoid/errors/inverse_not_found.rb +1 -1
  73. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  74. data/lib/mongoid/evolvable.rb +1 -1
  75. data/lib/mongoid/extensions.rb +0 -5
  76. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  77. data/lib/mongoid/extensions/date.rb +4 -1
  78. data/lib/mongoid/extensions/hash.rb +2 -3
  79. data/lib/mongoid/extensions/object.rb +2 -2
  80. data/lib/mongoid/extensions/string.rb +4 -3
  81. data/lib/mongoid/extensions/time.rb +5 -2
  82. data/lib/mongoid/factory.rb +1 -0
  83. data/lib/mongoid/fields/foreign_key.rb +2 -2
  84. data/lib/mongoid/fields/localized.rb +3 -8
  85. data/lib/mongoid/fields/validators/macro.rb +18 -0
  86. data/lib/mongoid/findable.rb +3 -3
  87. data/lib/mongoid/indexable.rb +17 -16
  88. data/lib/mongoid/indexable/specification.rb +1 -1
  89. data/lib/mongoid/indexable/validators/options.rb +1 -2
  90. data/lib/mongoid/interceptable.rb +6 -17
  91. data/lib/mongoid/loggable.rb +1 -1
  92. data/lib/mongoid/matchable.rb +3 -10
  93. data/lib/mongoid/matchable/gt.rb +2 -0
  94. data/lib/mongoid/matchable/gte.rb +2 -0
  95. data/lib/mongoid/matchable/lt.rb +2 -0
  96. data/lib/mongoid/matchable/lte.rb +2 -0
  97. data/lib/mongoid/persistable.rb +6 -5
  98. data/lib/mongoid/persistable/creatable.rb +2 -0
  99. data/lib/mongoid/persistable/deletable.rb +7 -3
  100. data/lib/mongoid/persistable/settable.rb +3 -16
  101. data/lib/mongoid/persistable/updatable.rb +10 -12
  102. data/lib/mongoid/persistence_context.rb +216 -0
  103. data/lib/mongoid/query_cache.rb +5 -30
  104. data/lib/mongoid/relations/accessors.rb +6 -2
  105. data/lib/mongoid/relations/auto_save.rb +12 -4
  106. data/lib/mongoid/relations/bindings/embedded/in.rb +4 -0
  107. data/lib/mongoid/relations/bindings/embedded/many.rb +8 -1
  108. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -0
  109. data/lib/mongoid/relations/bindings/referenced/many.rb +4 -0
  110. data/lib/mongoid/relations/builders.rb +2 -2
  111. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  112. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  113. data/lib/mongoid/relations/conversions.rb +1 -1
  114. data/lib/mongoid/relations/counter_cache.rb +28 -18
  115. data/lib/mongoid/relations/eager.rb +19 -7
  116. data/lib/mongoid/relations/eager/base.rb +5 -5
  117. data/lib/mongoid/relations/embedded/batchable.rb +9 -33
  118. data/lib/mongoid/relations/embedded/in.rb +16 -2
  119. data/lib/mongoid/relations/embedded/many.rb +23 -8
  120. data/lib/mongoid/relations/embedded/one.rb +17 -2
  121. data/lib/mongoid/relations/macros.rb +9 -2
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/nested_builder.rb +1 -1
  124. data/lib/mongoid/relations/options.rb +2 -2
  125. data/lib/mongoid/relations/proxy.rb +2 -33
  126. data/lib/mongoid/relations/referenced/in.rb +23 -11
  127. data/lib/mongoid/relations/referenced/many.rb +24 -16
  128. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  129. data/lib/mongoid/relations/referenced/one.rb +17 -1
  130. data/lib/mongoid/relations/reflections.rb +3 -5
  131. data/lib/mongoid/relations/touchable.rb +1 -1
  132. data/lib/mongoid/reloadable.rb +1 -1
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +2 -3
  135. data/lib/mongoid/tasks/database.rb +1 -2
  136. data/lib/mongoid/threaded.rb +4 -4
  137. data/lib/mongoid/traversable.rb +1 -1
  138. data/lib/mongoid/validatable.rb +1 -1
  139. data/lib/mongoid/validatable/macros.rb +2 -4
  140. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  141. data/lib/mongoid/version.rb +1 -1
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -7
  143. data/spec/app/models/album.rb +5 -1
  144. data/spec/app/models/artist.rb +21 -0
  145. data/spec/app/models/band.rb +0 -1
  146. data/spec/app/models/church.rb +0 -2
  147. data/spec/app/models/ordered_post.rb +5 -0
  148. data/spec/app/models/oscar.rb +1 -2
  149. data/spec/app/models/person.rb +3 -1
  150. data/spec/app/models/post.rb +0 -1
  151. data/spec/app/models/princess.rb +2 -0
  152. data/spec/app/models/record.rb +1 -0
  153. data/spec/app/models/thing.rb +1 -1
  154. data/spec/config/mongoid.yml +1 -5
  155. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  156. data/spec/mongoid/atomic_spec.rb +17 -17
  157. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  158. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  159. data/spec/mongoid/attributes_spec.rb +63 -0
  160. data/spec/mongoid/cacheable_spec.rb +112 -0
  161. data/spec/mongoid/changeable_spec.rb +58 -0
  162. data/spec/mongoid/clients/factory_spec.rb +3 -11
  163. data/spec/mongoid/clients/options_spec.rb +378 -96
  164. data/spec/mongoid/clients_spec.rb +207 -170
  165. data/spec/mongoid/composable_spec.rb +7 -0
  166. data/spec/mongoid/config_spec.rb +41 -21
  167. data/spec/mongoid/contextual/atomic_spec.rb +77 -343
  168. data/spec/mongoid/contextual/map_reduce_spec.rb +119 -111
  169. data/spec/mongoid/contextual/memory_spec.rb +56 -316
  170. data/spec/mongoid/contextual/mongo_spec.rb +104 -378
  171. data/spec/mongoid/copyable_spec.rb +8 -15
  172. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  173. data/spec/mongoid/criteria/options_spec.rb +29 -0
  174. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  175. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  176. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  177. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  178. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  179. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  180. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  181. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  182. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  183. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  184. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  185. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  186. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  187. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  188. data/spec/mongoid/{extensions/origin/regexp_raw_spec.rb → criteria/queryable/extensions/regexp_spec.rb} +21 -20
  189. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  190. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  191. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  192. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  193. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  194. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  195. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  196. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  197. data/spec/mongoid/criteria/queryable/optional_spec.rb +1786 -0
  198. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  199. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  200. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  201. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4159 -0
  202. data/spec/mongoid/criteria/queryable/selector_spec.rb +778 -0
  203. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  204. data/spec/mongoid/criteria_spec.rb +45 -63
  205. data/spec/mongoid/document_spec.rb +21 -88
  206. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  207. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  208. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  209. data/spec/mongoid/extensions/date_spec.rb +2 -6
  210. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  211. data/spec/mongoid/extensions/float_spec.rb +8 -1
  212. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  213. data/spec/mongoid/extensions/object_spec.rb +11 -0
  214. data/spec/mongoid/extensions/string_spec.rb +21 -0
  215. data/spec/mongoid/extensions/time_spec.rb +4 -8
  216. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  217. data/spec/mongoid/fields/localized_spec.rb +0 -91
  218. data/spec/mongoid/findable_spec.rb +46 -1
  219. data/spec/mongoid/indexable_spec.rb +6 -46
  220. data/spec/mongoid/interceptable_spec.rb +49 -10
  221. data/spec/mongoid/matchable/gt_spec.rb +11 -0
  222. data/spec/mongoid/matchable/gte_spec.rb +10 -0
  223. data/spec/mongoid/matchable/lt_spec.rb +11 -0
  224. data/spec/mongoid/matchable/lte_spec.rb +11 -0
  225. data/spec/mongoid/matchable_spec.rb +1 -51
  226. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  227. data/spec/mongoid/persistable/deletable_spec.rb +1 -1
  228. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  229. data/spec/mongoid/persistable/savable_spec.rb +30 -30
  230. data/spec/mongoid/persistable/settable_spec.rb +0 -185
  231. data/spec/mongoid/persistable/updatable_spec.rb +166 -5
  232. data/spec/mongoid/persistence_context_spec.rb +654 -0
  233. data/spec/mongoid/positional_spec.rb +10 -10
  234. data/spec/mongoid/query_cache_spec.rb +89 -65
  235. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  236. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  237. data/spec/mongoid/relations/builders_spec.rb +37 -10
  238. data/spec/mongoid/relations/counter_cache_spec.rb +64 -15
  239. data/spec/mongoid/relations/cyclic_spec.rb +0 -22
  240. data/spec/mongoid/relations/embedded/many_spec.rb +9 -41
  241. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  242. data/spec/mongoid/relations/macros_spec.rb +395 -7
  243. data/spec/mongoid/relations/proxy_spec.rb +3 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +6 -29
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +6 -29
  247. data/spec/mongoid/relations/reflections_spec.rb +9 -9
  248. data/spec/mongoid/reloadable_spec.rb +51 -0
  249. data/spec/mongoid/scopable_spec.rb +0 -12
  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 +16 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +10 -10
  255. metadata +536 -479
  256. metadata.gz.sig +0 -0
  257. data/lib/mongoid/clients/thread_options.rb +0 -19
  258. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +0 -20
  259. data/lib/mongoid/extensions/decimal128.rb +0 -39
  260. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  261. data/lib/mongoid/matchable/regexp.rb +0 -27
  262. data/spec/app/models/post_genre.rb +0 -6
  263. data/spec/mongoid/extensions/decimal128_spec.rb +0 -44
  264. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
@@ -0,0 +1,196 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ class Criteria
4
+ module Queryable
5
+
6
+ # The selector is a special kind of hash that knows how to serialize values
7
+ # coming into it as well as being alias and locale aware for key names.
8
+ class Selector < Smash
9
+
10
+ # Merges another selector into this one.
11
+ #
12
+ # @example Merge in another selector.
13
+ # selector.merge!(name: "test")
14
+ #
15
+ # @param [ Hash, Selector ] other The object to merge in.
16
+ #
17
+ # @return [ Selector ] The selector.
18
+ #
19
+ # @since 1.0.0
20
+ def merge!(other)
21
+ other.each_pair do |key, value|
22
+ if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
23
+ value = self[key.to_s].merge(value) do |_key, old_val, new_val|
24
+ multi_value?(_key) ? (old_val + new_val).uniq : new_val
25
+ end
26
+ end
27
+ if multi_selection?(key)
28
+ value = (self[key.to_s] || []).concat(value)
29
+ end
30
+ store(key, value)
31
+ end
32
+ end
33
+
34
+ # Store the value in the selector for the provided key. The selector will
35
+ # handle all necessary serialization and localization in this step.
36
+ #
37
+ # @example Store a value in the selector.
38
+ # selector.store(:key, "testing")
39
+ #
40
+ # @param [ String, Symbol ] key The name of the attribute.
41
+ # @param [ Object ] value The value to add.
42
+ #
43
+ # @return [ Object ] The stored object.
44
+ #
45
+ # @since 1.0.0
46
+ def store(key, value)
47
+ name, serializer = storage_pair(key)
48
+ if multi_selection?(name)
49
+ super(name, evolve_multi(value))
50
+ else
51
+ super(normalized_key(name, serializer), evolve(serializer, value))
52
+ end
53
+ end
54
+ alias :[]= :store
55
+
56
+ # Convert the selector to an aggregation pipeline entry.
57
+ #
58
+ # @example Convert the selector to a pipeline.
59
+ # selector.to_pipeline
60
+ #
61
+ # @return [ Array<Hash> ] The pipeline entry for the selector.
62
+ #
63
+ # @since 2.0.0
64
+ def to_pipeline
65
+ pipeline = []
66
+ pipeline.push({ "$match" => self }) unless empty?
67
+ pipeline
68
+ end
69
+
70
+ private
71
+
72
+ # Evolves a multi-list selection, like an $and or $or criterion, and
73
+ # performs the necessary serialization.
74
+ #
75
+ # @api private
76
+ #
77
+ # @example Evolve the multi-selection.
78
+ # selector.evolve_multi([{ field: "value" }])
79
+ #
80
+ # @param [ Array<Hash> ] The multi-selection.
81
+ #
82
+ # @return [ Array<Hash> ] The serialized values.
83
+ #
84
+ # @since 1.0.0
85
+ def evolve_multi(value)
86
+ value.map do |val|
87
+ Hash[val.map do |key, _value|
88
+ _value = evolve_multi(_value) if multi_selection?(key)
89
+ name, serializer = storage_pair(key)
90
+ [ normalized_key(name, serializer), evolve(serializer, _value) ]
91
+ end]
92
+ end.uniq
93
+ end
94
+
95
+ # Evolve a single key selection with various types of values.
96
+ #
97
+ # @api private
98
+ #
99
+ # @example Evolve a simple selection.
100
+ # selector.evolve(field, 5)
101
+ #
102
+ # @param [ Object ] serializer The optional serializer for the field.
103
+ # @param [ Object ] value The value to serialize.
104
+ #
105
+ # @return [ Object ] The serialized object.
106
+ #
107
+ # @since 1.0.0
108
+ def evolve(serializer, value)
109
+ case value
110
+ when Hash
111
+ evolve_hash(serializer, value)
112
+ when Array
113
+ evolve_array(serializer, value)
114
+ else
115
+ (serializer || value.class).evolve(value)
116
+ end
117
+ end
118
+
119
+ # Evolve a single key selection with array values.
120
+ #
121
+ # @api private
122
+ #
123
+ # @example Evolve a simple selection.
124
+ # selector.evolve(field, [ 1, 2, 3 ])
125
+ #
126
+ # @param [ Object ] serializer The optional serializer for the field.
127
+ # @param [ Array<Object> ] value The array to serialize.
128
+ #
129
+ # @return [ Object ] The serialized array.
130
+ #
131
+ # @since 1.0.0
132
+ def evolve_array(serializer, value)
133
+ value.map do |_value|
134
+ evolve(serializer, _value)
135
+ end
136
+ end
137
+
138
+ # Evolve a single key selection with hash values.
139
+ #
140
+ # @api private
141
+ #
142
+ # @example Evolve a simple selection.
143
+ # selector.evolve(field, { "$gt" => 5 })
144
+ #
145
+ # @param [ Object ] serializer The optional serializer for the field.
146
+ # @param [ Hash ] value The hash to serialize.
147
+ #
148
+ # @return [ Object ] The serialized hash.
149
+ #
150
+ # @since 1.0.0
151
+ def evolve_hash(serializer, value)
152
+ value.each_pair do |operator, _value|
153
+ if operator =~ /exists|type|size/
154
+ value[operator] = _value
155
+ else
156
+ value[operator] = evolve(serializer, _value)
157
+ end
158
+ end
159
+ end
160
+
161
+ # Determines if the selection is a multi-select, like an $and or $or or $nor
162
+ # selection.
163
+ #
164
+ # @api private
165
+ #
166
+ # @example Is the selection a multi-select?
167
+ # selector.multi_selection?("$and")
168
+ #
169
+ # @param [ String ] key The key to check.
170
+ #
171
+ # @return [ true, false ] If the key is for a multi-select.
172
+ #
173
+ # @since 1.0.0
174
+ def multi_selection?(key)
175
+ key =~ /\$and|\$or|\$nor/
176
+ end
177
+
178
+ # Determines if the selection operator takes a list. Returns true for $in and $nin.
179
+ #
180
+ # @api private
181
+ #
182
+ # @example Does the selection operator take multiple values?
183
+ # selector.multi_value?("$nin")
184
+ #
185
+ # @param [ String ] key The key to check.
186
+ #
187
+ # @return [ true, false ] If the key is $in or $nin.
188
+ #
189
+ # @since 2.1.1
190
+ def multi_value?(key)
191
+ key =~ /\$nin|\$in/
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ class Criteria
4
+ module Queryable
5
+
6
+ # This is a smart hash for use with options and selectors.
7
+ class Smash < Hash
8
+
9
+ # @attribute [r] aliases The aliases.
10
+ # @attribute [r] serializers The serializers.
11
+ attr_reader :aliases, :serializers
12
+
13
+ # Perform a deep copy of the smash.
14
+ #
15
+ # @example Perform a deep copy.
16
+ # smash.__deep_copy__
17
+ #
18
+ # @return [ Smash ] The copied hash.
19
+ #
20
+ # @since 1.0.0
21
+ def __deep_copy__
22
+ self.class.new(aliases, serializers) do |copy|
23
+ each_pair do |key, value|
24
+ copy.store(key, value.__deep_copy__)
25
+ end
26
+ end
27
+ end
28
+
29
+ # Initialize the new selector.
30
+ #
31
+ # @example Initialize the new selector.
32
+ # Queryable::Smash.new(aliases, serializers)
33
+ #
34
+ # @param [ Hash ] aliases A hash of mappings from aliases to the actual
35
+ # field names in the database.
36
+ # @param [ Hash ] serializers An optional hash of objects that are
37
+ # responsible for serializing values. The keys of the hash must be
38
+ # strings that match the field name, and the values must respond to
39
+ # #localized? and #evolve(object).
40
+ #
41
+ # @since 1.0.0
42
+ def initialize(aliases = {}, serializers = {})
43
+ @aliases, @serializers = aliases, serializers
44
+ yield(self) if block_given?
45
+ end
46
+
47
+ # Get an item from the smart hash by the provided key.
48
+ #
49
+ # @example Get an item by the key.
50
+ # smash["test"]
51
+ #
52
+ # @param [ String ] key The key.
53
+ #
54
+ # @return [ Object ] The found object.
55
+ #
56
+ # @since 2.0.0
57
+ def [](key)
58
+ fetch(aliases[key]) { super }
59
+ end
60
+
61
+ private
62
+
63
+ # Get the normalized value for the key. If localization is in play the
64
+ # current locale will be appended to the key in MongoDB dot notation.
65
+ #
66
+ # @api private
67
+ #
68
+ # @example Get the normalized key name.
69
+ # smash.normalized_key("field", serializer)
70
+ #
71
+ # @param [ String ] name The name of the field.
72
+ # @param [ Object ] serializer The optional field serializer.
73
+ #
74
+ # @return [ String ] The normalized key.
75
+ #
76
+ # @since 1.0.0
77
+ def normalized_key(name, serializer)
78
+ serializer && serializer.localized? ? "#{name}.#{::I18n.locale}" : name
79
+ end
80
+
81
+ # Get the pair of objects needed to store the value in a hash by the
82
+ # provided key. This is the database field name and the serializer.
83
+ #
84
+ # @api private
85
+ #
86
+ # @example Get the name and serializer.
87
+ # smash.storage_pair("id")
88
+ #
89
+ # @param [ Symbol, String ] key The key provided to the selection.
90
+ #
91
+ # @return [ Array<String, Object> ] The name of the db field and
92
+ # serializer.
93
+ #
94
+ # @since 1.0.0
95
+ def storage_pair(key)
96
+ field = key.to_s
97
+ name = aliases[field] || field
98
+ [ name, serializers[name] ]
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -31,6 +31,15 @@ module Mongoid
31
31
  Mongoid.register_model(self)
32
32
  end
33
33
 
34
+ # Regex for matching illegal BSON keys.
35
+ # Note that bson 4.1 has the constant BSON::String::ILLEGAL_KEY
36
+ # that should be used instead.
37
+ # When ruby driver 2.3.0 is released and Mongoid can be updated
38
+ # to require >= 2.3.0, the BSON constant can be used.
39
+ #
40
+ # @since 6.0.0
41
+ ILLEGAL_KEY = /(\A[$])|(\.)/.freeze
42
+
34
43
  # Freezes the internal attributes of the document.
35
44
  #
36
45
  # @example Freeze the document
@@ -101,11 +110,9 @@ module Mongoid
101
110
  #
102
111
  # @since 1.0.0
103
112
  def initialize(attrs = nil)
104
- @__parent = nil
105
113
  _building do
106
114
  @new_record = true
107
115
  @attributes ||= {}
108
- with(self.class.persistence_options)
109
116
  apply_pre_processed_defaults
110
117
  apply_default_scoping
111
118
  process_attributes(attrs) do
@@ -243,27 +250,6 @@ module Mongoid
243
250
  became
244
251
  end
245
252
 
246
- # Print out the cache key. This will append different values on the
247
- # plural model name.
248
- #
249
- # If new_record? - will append /new
250
- # If not - will append /id-updated_at.to_s(:nsec)
251
- # Without updated_at - will append /id
252
- #
253
- # This is usually called insode a cache() block
254
- #
255
- # @example Returns the cache key
256
- # document.cache_key
257
- #
258
- # @return [ String ] the string with or without updated_at
259
- #
260
- # @since 2.4.0
261
- def cache_key
262
- return "#{model_key}/new" if new_record?
263
- return "#{model_key}/#{id}-#{updated_at.utc.to_s(:nsec)}" if do_or_do_not(:updated_at)
264
- "#{model_key}/#{id}"
265
- end
266
-
267
253
  private
268
254
 
269
255
  # Returns the logger
@@ -5,7 +5,6 @@ require "mongoid/errors/callback"
5
5
  require "mongoid/errors/document_not_destroyed"
6
6
  require "mongoid/errors/document_not_found"
7
7
  require "mongoid/errors/eager_load"
8
- require "mongoid/errors/in_memory_collation_not_supported"
9
8
  require "mongoid/errors/invalid_collection"
10
9
  require "mongoid/errors/invalid_config_option"
11
10
  require "mongoid/errors/invalid_field"
@@ -15,6 +14,8 @@ require "mongoid/errors/invalid_includes"
15
14
  require "mongoid/errors/invalid_index"
16
15
  require "mongoid/errors/invalid_options"
17
16
  require "mongoid/errors/invalid_path"
17
+ require "mongoid/errors/invalid_persistence_option"
18
+ require "mongoid/errors/invalid_relation"
18
19
  require "mongoid/errors/invalid_scope"
19
20
  require "mongoid/errors/invalid_set_polymorphic_relation"
20
21
  require "mongoid/errors/invalid_storage_options"
@@ -24,7 +24,7 @@ module Mongoid
24
24
  #
25
25
  # @example Create the error.
26
26
  # AmbiguousRelationship.new(
27
- # Person, Drug, :person, [ :drugs, # :evil_drugs ]
27
+ # Person, Drug, :person, [ :drugs, :evil_drugs ]
28
28
  # )
29
29
  #
30
30
  # @param [ Class ] klass The base class.
@@ -11,8 +11,8 @@ module Mongoid
11
11
  # @example Create the new callbacks error.
12
12
  # Callbacks.new(Post, :create!)
13
13
  #
14
- # @param [ Class ] document
15
- # @param [ Symbol ] relation
14
+ # @param [ Class ] klass The class of the document.
15
+ # @param [ Symbol ] method The name of the method.
16
16
  #
17
17
  # @since 3.0.0
18
18
  def initialize(document, relation)
@@ -29,10 +29,10 @@ module Mongoid
29
29
 
30
30
  private
31
31
 
32
- # Get the origin of the method.
32
+ # Get the queryable of the method.
33
33
  #
34
34
  # @example Get the originating class or module.
35
- # error.origin(Person, :crazy_method_name)
35
+ # error.queryable(Person, :crazy_method_name)
36
36
  #
37
37
  # @param [ Class ] klass The document class.
38
38
  # @param [ Symbol ] name The method name.
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Errors
4
+
5
+ # Raised when invalid options are used to create a persistence context.
6
+ #
7
+ # @since 6.0.0
8
+ class InvalidPersistenceOption < MongoidError
9
+
10
+ # Instantiate the persistence context option error.
11
+ #
12
+ # @example Create the error.
13
+ # InvalidPersistenceOption.new(:invalid_option, [ :connect_timeout, :database ])
14
+ #
15
+ # @param [ Symbol ] invalid The invalid option.
16
+ # @param [ Array<Symbol> ] valid The allowed options.
17
+ #
18
+ # @since 6.0.0
19
+ def initialize(invalid, valid)
20
+ super(
21
+ compose_message(
22
+ "invalid_persistence_option",
23
+ { invalid: invalid, valid: valid }
24
+ )
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Errors
4
+
5
+ # This error is raised when trying to create a relation that conflicts with
6
+ # an already defined method.
7
+ #
8
+ # @since 6.0.0
9
+ class InvalidRelation < MongoidError
10
+
11
+ # Create the new error.
12
+ #
13
+ # @example Create the error.
14
+ # InvalidRelation.new(person, :crazy_relation_name)
15
+ #
16
+ # @param [ Class ] klass The document class.
17
+ # @param [ Symbol ] name The method name.
18
+ def initialize(klass, name)
19
+ super(
20
+ compose_message(
21
+ "invalid_relation",
22
+ {
23
+ name: name,
24
+ origin: origin(klass, name),
25
+ file: location(klass, name)[0],
26
+ line: location(klass, name)[1]
27
+ }
28
+ )
29
+ )
30
+ end
31
+
32
+ private
33
+
34
+ # Get the queryable of the method.
35
+ #
36
+ # @example Get the originating class or module.
37
+ # error.queryable(Person, :crazy_method_name)
38
+ #
39
+ # @param [ Class ] klass The document class.
40
+ # @param [ Symbol ] name The method name.
41
+ #
42
+ # @return [ Class, Module ] The originating class or module.
43
+ #
44
+ # @since 6.0.0
45
+ def origin(klass, name)
46
+ klass.instance_method(name).owner
47
+ end
48
+
49
+ # Get the location of the relation definition.
50
+ #
51
+ # @example Get the location of the method on the filesystem.
52
+ # error.location(Person, :crazy_method_name)
53
+ #
54
+ # @param [ Class ] klass The document class.
55
+ # @param [ Symbol ] name The method name.
56
+ #
57
+ # @return [ Array<String, Integer> ] The location of the method.
58
+ #
59
+ # @since 6.0.0
60
+ def location(klass, name)
61
+ @location ||=
62
+ (klass.instance_method(name).source_location || [ "Unknown", 0 ])
63
+ end
64
+ end
65
+ end
66
+ end