mongoid 6.4.8 → 7.0.13

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 (376) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE +1 -0
  4. data/README.md +4 -3
  5. data/Rakefile +33 -7
  6. data/lib/config/locales/en.yml +17 -0
  7. data/lib/mongoid/association/accessors.rb +339 -0
  8. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
  9. data/lib/mongoid/association/builders.rb +92 -0
  10. data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
  11. data/lib/mongoid/association/depending.rb +137 -0
  12. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
  13. data/lib/mongoid/{relations → association}/embedded/batchable.rb +19 -19
  14. data/lib/mongoid/association/embedded/cyclic.rb +109 -0
  15. data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
  16. data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
  17. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
  18. data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
  19. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
  20. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
  21. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +552 -0
  22. data/lib/mongoid/association/embedded/embeds_many.rb +211 -0
  23. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
  24. data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
  25. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
  26. data/lib/mongoid/association/embedded/embeds_one.rb +174 -0
  27. data/lib/mongoid/association/embedded.rb +4 -0
  28. data/lib/mongoid/association/macros.rb +204 -0
  29. data/lib/mongoid/{relations → association}/many.rb +19 -49
  30. data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
  31. data/lib/mongoid/association/nested/many.rb +200 -0
  32. data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
  33. data/lib/mongoid/association/nested/one.rb +127 -0
  34. data/lib/mongoid/association/nested.rb +15 -0
  35. data/lib/mongoid/{relations → association}/one.rb +6 -6
  36. data/lib/mongoid/association/options.rb +152 -0
  37. data/lib/mongoid/{relations → association}/proxy.rb +45 -59
  38. data/lib/mongoid/association/referenced/auto_save.rb +79 -0
  39. data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
  40. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
  41. data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
  42. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
  43. data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
  44. data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
  45. data/lib/mongoid/association/referenced/eager.rb +162 -0
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +312 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
  51. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
  52. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  53. data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
  54. data/lib/mongoid/association/referenced/has_many/enumerable.rb +510 -0
  55. data/lib/mongoid/association/referenced/has_many/proxy.rb +578 -0
  56. data/lib/mongoid/association/referenced/has_many.rb +275 -0
  57. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
  58. data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
  59. data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
  60. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
  61. data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
  62. data/lib/mongoid/association/referenced/has_one.rb +204 -0
  63. data/lib/mongoid/association/referenced/syncable.rb +170 -0
  64. data/lib/mongoid/association/referenced.rb +7 -0
  65. data/lib/mongoid/{relations → association}/reflections.rb +21 -17
  66. data/lib/mongoid/association/relatable.rb +511 -0
  67. data/lib/mongoid/{relations.rb → association.rb} +57 -56
  68. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  69. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  70. data/lib/mongoid/atomic/paths/embedded.rb +1 -1
  71. data/lib/mongoid/atomic.rb +14 -4
  72. data/lib/mongoid/attributes/dynamic.rb +16 -15
  73. data/lib/mongoid/attributes/nested.rb +22 -11
  74. data/lib/mongoid/attributes/processing.rb +2 -2
  75. data/lib/mongoid/attributes/readonly.rb +2 -4
  76. data/lib/mongoid/attributes.rb +55 -31
  77. data/lib/mongoid/changeable.rb +1 -1
  78. data/lib/mongoid/clients/options.rb +7 -5
  79. data/lib/mongoid/clients/sessions.rb +20 -4
  80. data/lib/mongoid/composable.rb +4 -4
  81. data/lib/mongoid/config/environment.rb +21 -8
  82. data/lib/mongoid/config.rb +1 -0
  83. data/lib/mongoid/contextual/atomic.rb +1 -1
  84. data/lib/mongoid/contextual/geo_near.rb +1 -1
  85. data/lib/mongoid/contextual/memory.rb +21 -3
  86. data/lib/mongoid/contextual/mongo.rb +10 -8
  87. data/lib/mongoid/copyable.rb +11 -6
  88. data/lib/mongoid/criteria/includable.rb +14 -14
  89. data/lib/mongoid/criteria/modifiable.rb +8 -3
  90. data/lib/mongoid/criteria/options.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  92. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
  94. data/lib/mongoid/criteria/queryable/extensions/time.rb +1 -1
  95. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
  96. data/lib/mongoid/criteria/queryable/key.rb +67 -8
  97. data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
  98. data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
  99. data/lib/mongoid/criteria/queryable/selectable.rb +5 -3
  100. data/lib/mongoid/criteria/queryable/selector.rb +9 -31
  101. data/lib/mongoid/criteria.rb +9 -3
  102. data/lib/mongoid/document.rb +14 -4
  103. data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
  104. data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
  105. data/lib/mongoid/errors/unknown_model.rb +25 -0
  106. data/lib/mongoid/errors.rb +3 -0
  107. data/lib/mongoid/extensions/array.rb +5 -5
  108. data/lib/mongoid/extensions/hash.rb +9 -4
  109. data/lib/mongoid/extensions/object.rb +4 -4
  110. data/lib/mongoid/extensions/range.rb +1 -0
  111. data/lib/mongoid/extensions/regexp.rb +1 -1
  112. data/lib/mongoid/extensions/string.rb +2 -2
  113. data/lib/mongoid/extensions.rb +0 -4
  114. data/lib/mongoid/factory.rb +13 -3
  115. data/lib/mongoid/fields/foreign_key.rb +5 -5
  116. data/lib/mongoid/fields/standard.rb +2 -14
  117. data/lib/mongoid/fields/validators/macro.rb +1 -1
  118. data/lib/mongoid/fields.rb +5 -4
  119. data/lib/mongoid/indexable.rb +4 -1
  120. data/lib/mongoid/interceptable.rb +8 -6
  121. data/lib/mongoid/matchable/all.rb +4 -3
  122. data/lib/mongoid/matchable/and.rb +1 -1
  123. data/lib/mongoid/matchable/default.rb +71 -24
  124. data/lib/mongoid/matchable/elem_match.rb +9 -3
  125. data/lib/mongoid/matchable/eq.rb +22 -0
  126. data/lib/mongoid/matchable/ne.rb +1 -1
  127. data/lib/mongoid/matchable/regexp.rb +2 -2
  128. data/lib/mongoid/matchable.rb +17 -16
  129. data/lib/mongoid/persistable/deletable.rb +7 -6
  130. data/lib/mongoid/persistable/incrementable.rb +1 -1
  131. data/lib/mongoid/persistable/logical.rb +1 -1
  132. data/lib/mongoid/persistable/pushable.rb +11 -2
  133. data/lib/mongoid/persistable/settable.rb +57 -12
  134. data/lib/mongoid/persistable.rb +4 -5
  135. data/lib/mongoid/persistence_context.rb +26 -11
  136. data/lib/mongoid/positional.rb +1 -1
  137. data/lib/mongoid/query_cache.rb +4 -2
  138. data/lib/mongoid/serializable.rb +4 -4
  139. data/lib/mongoid/shardable.rb +1 -1
  140. data/lib/mongoid/touchable.rb +102 -0
  141. data/lib/mongoid/traversable.rb +3 -3
  142. data/lib/mongoid/validatable/macros.rb +1 -1
  143. data/lib/mongoid/validatable/presence.rb +2 -2
  144. data/lib/mongoid/validatable/uniqueness.rb +5 -5
  145. data/lib/mongoid/validatable.rb +8 -8
  146. data/lib/mongoid/version.rb +2 -1
  147. data/lib/mongoid.rb +1 -0
  148. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  149. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -0
  150. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  151. data/spec/README.md +18 -0
  152. data/spec/app/models/animal.rb +2 -1
  153. data/spec/app/models/bomb.rb +1 -1
  154. data/spec/app/models/customer.rb +11 -0
  155. data/spec/app/models/customer_address.rb +12 -0
  156. data/spec/app/models/message.rb +1 -1
  157. data/spec/app/models/minim.rb +7 -0
  158. data/spec/app/models/other_owner_object.rb +2 -0
  159. data/spec/app/models/person.rb +5 -2
  160. data/spec/app/models/shipment_address.rb +1 -0
  161. data/spec/app/models/store_as_dup_test3.rb +7 -0
  162. data/spec/app/models/store_as_dup_test4.rb +7 -0
  163. data/spec/app/models/updatable.rb +7 -0
  164. data/spec/app/models/vertex.rb +6 -0
  165. data/spec/app/models/wiki_page.rb +1 -1
  166. data/spec/config/mongoid.yml +13 -3
  167. data/spec/integration/app_spec.rb +341 -0
  168. data/spec/integration/associations/belongs_to_spec.rb +13 -0
  169. data/spec/integration/associations/embedded_spec.rb +176 -0
  170. data/spec/integration/callbacks_models.rb +49 -0
  171. data/spec/integration/callbacks_spec.rb +216 -0
  172. data/spec/integration/criteria/date_field_spec.rb +41 -0
  173. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  174. data/spec/integration/matchable_spec.rb +680 -0
  175. data/spec/lite_spec_helper.rb +71 -0
  176. data/spec/mongoid/{relations → association}/accessors_spec.rb +40 -1
  177. data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
  178. data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
  179. data/spec/mongoid/association/constrainable_spec.rb +115 -0
  180. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
  181. data/spec/mongoid/association/depending_spec.rb +866 -0
  182. data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
  183. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
  184. data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
  185. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
  186. data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
  187. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +55 -77
  188. data/spec/mongoid/association/embedded/embedded_in_spec.rb +901 -0
  189. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
  190. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
  191. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +124 -182
  192. data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
  193. data/spec/mongoid/association/embedded/embeds_many_spec.rb +862 -0
  194. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
  195. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
  196. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
  197. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +6 -0
  198. data/spec/mongoid/association/embedded/embeds_one_models.rb +51 -0
  199. data/spec/mongoid/association/embedded/embeds_one_spec.rb +954 -0
  200. data/spec/mongoid/{relations → association}/macros_spec.rb +148 -73
  201. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
  202. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
  203. data/spec/mongoid/association/options_spec.rb +1321 -0
  204. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +66 -34
  205. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
  206. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
  207. data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +33 -14
  208. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
  209. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2023 -0
  210. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
  211. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
  212. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +26 -7
  213. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +56 -0
  214. data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +247 -99
  215. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -0
  216. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1027 -0
  217. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
  218. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
  219. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +26 -11
  220. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +227 -1
  221. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  222. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +30 -94
  223. data/spec/mongoid/association/referenced/has_many_models.rb +37 -0
  224. data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
  225. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
  226. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
  227. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
  228. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
  229. data/spec/mongoid/association/referenced/has_one_models.rb +48 -0
  230. data/spec/mongoid/association/referenced/has_one_spec.rb +1360 -0
  231. data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
  232. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
  233. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
  234. data/spec/mongoid/atomic/modifiers_spec.rb +2 -2
  235. data/spec/mongoid/atomic/paths_spec.rb +41 -0
  236. data/spec/mongoid/atomic_spec.rb +4 -4
  237. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  238. data/spec/mongoid/attributes/nested_spec.rb +29 -11
  239. data/spec/mongoid/attributes/readonly_spec.rb +80 -125
  240. data/spec/mongoid/attributes_spec.rb +298 -9
  241. data/spec/mongoid/clients/factory_spec.rb +20 -38
  242. data/spec/mongoid/clients/options_spec.rb +64 -50
  243. data/spec/mongoid/clients/sessions_spec.rb +9 -5
  244. data/spec/mongoid/clients/transactions_spec.rb +390 -0
  245. data/spec/mongoid/clients_spec.rb +70 -10
  246. data/spec/mongoid/config_spec.rb +27 -1
  247. data/spec/mongoid/contextual/atomic_spec.rb +37 -14
  248. data/spec/mongoid/contextual/geo_near_spec.rb +11 -2
  249. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  250. data/spec/mongoid/contextual/memory_spec.rb +19 -0
  251. data/spec/mongoid/contextual/mongo_spec.rb +107 -56
  252. data/spec/mongoid/copyable_spec.rb +90 -6
  253. data/spec/mongoid/copyable_spec_models.rb +17 -0
  254. data/spec/mongoid/criteria/modifiable_spec.rb +173 -1
  255. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  256. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  257. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +44 -1
  258. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
  259. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
  260. data/spec/mongoid/criteria/queryable/key_spec.rb +48 -6
  261. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
  262. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
  263. data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
  264. data/spec/mongoid/criteria/queryable/selector_spec.rb +37 -0
  265. data/spec/mongoid/criteria_spec.rb +36 -19
  266. data/spec/mongoid/document_fields_spec.rb +88 -0
  267. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  268. data/spec/mongoid/document_spec.rb +29 -4
  269. data/spec/mongoid/extensions/array_spec.rb +11 -15
  270. data/spec/mongoid/extensions/hash_spec.rb +18 -1
  271. data/spec/mongoid/extensions/object_spec.rb +7 -11
  272. data/spec/mongoid/extensions/range_spec.rb +7 -0
  273. data/spec/mongoid/factory_spec.rb +21 -3
  274. data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
  275. data/spec/mongoid/fields_spec.rb +1 -1
  276. data/spec/mongoid/indexable_spec.rb +24 -12
  277. data/spec/mongoid/interceptable_spec.rb +22 -1
  278. data/spec/mongoid/matchable/default_spec.rb +10 -3
  279. data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
  280. data/spec/mongoid/matchable/eq_spec.rb +48 -0
  281. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  282. data/spec/mongoid/matchable_spec.rb +2 -2
  283. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  284. data/spec/mongoid/persistable/savable_spec.rb +5 -5
  285. data/spec/mongoid/persistable/settable_spec.rb +125 -10
  286. data/spec/mongoid/persistable_spec.rb +21 -6
  287. data/spec/mongoid/persistence_context_spec.rb +1 -1
  288. data/spec/mongoid/query_cache_spec.rb +65 -27
  289. data/spec/mongoid/relations/proxy_spec.rb +124 -124
  290. data/spec/mongoid/scopable_spec.rb +2 -1
  291. data/spec/mongoid/shardable_spec.rb +32 -12
  292. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  293. data/spec/mongoid/tasks/database_spec.rb +1 -1
  294. data/spec/mongoid/{relations/touchable_spec.rb → touchable_spec.rb} +40 -1
  295. data/spec/mongoid/validatable/associated_spec.rb +1 -1
  296. data/spec/mongoid/validatable/presence_spec.rb +7 -6
  297. data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
  298. data/spec/mongoid/validatable_spec.rb +1 -1
  299. data/spec/shared/LICENSE +20 -0
  300. data/spec/shared/bin/get-mongodb-download-url +17 -0
  301. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  302. data/spec/shared/lib/mrss/cluster_config.rb +221 -0
  303. data/spec/shared/lib/mrss/constraints.rb +354 -0
  304. data/spec/shared/lib/mrss/docker_runner.rb +265 -0
  305. data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
  306. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  307. data/spec/shared/lib/mrss/spec_organizer.rb +162 -0
  308. data/spec/shared/lib/mrss/utils.rb +15 -0
  309. data/spec/shared/share/Dockerfile.erb +231 -0
  310. data/spec/shared/shlib/distro.sh +73 -0
  311. data/spec/shared/shlib/server.sh +290 -0
  312. data/spec/shared/shlib/set_env.sh +128 -0
  313. data/spec/spec_helper.rb +34 -49
  314. data/spec/support/cluster_config.rb +3 -3
  315. data/spec/support/constraints.rb +21 -76
  316. data/spec/support/expectations.rb +17 -3
  317. data/spec/support/spec_config.rb +20 -7
  318. data.tar.gz.sig +0 -0
  319. metadata +646 -541
  320. metadata.gz.sig +1 -5
  321. data/lib/mongoid/relations/accessors.rb +0 -267
  322. data/lib/mongoid/relations/auto_save.rb +0 -94
  323. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  324. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  325. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  326. data/lib/mongoid/relations/bindings.rb +0 -9
  327. data/lib/mongoid/relations/builder.rb +0 -57
  328. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  329. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  330. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  331. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  332. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  333. data/lib/mongoid/relations/builders.rb +0 -106
  334. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  335. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  336. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  337. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  338. data/lib/mongoid/relations/cascading.rb +0 -56
  339. data/lib/mongoid/relations/conversions.rb +0 -34
  340. data/lib/mongoid/relations/counter_cache.rb +0 -160
  341. data/lib/mongoid/relations/cyclic.rb +0 -107
  342. data/lib/mongoid/relations/eager/base.rb +0 -153
  343. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  344. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  345. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  346. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  347. data/lib/mongoid/relations/embedded/in.rb +0 -241
  348. data/lib/mongoid/relations/embedded/many.rb +0 -683
  349. data/lib/mongoid/relations/embedded/one.rb +0 -235
  350. data/lib/mongoid/relations/macros.rb +0 -367
  351. data/lib/mongoid/relations/metadata.rb +0 -1179
  352. data/lib/mongoid/relations/nested_builder.rb +0 -74
  353. data/lib/mongoid/relations/options.rb +0 -49
  354. data/lib/mongoid/relations/polymorphic.rb +0 -39
  355. data/lib/mongoid/relations/referenced/in.rb +0 -304
  356. data/lib/mongoid/relations/referenced/many.rb +0 -812
  357. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  358. data/lib/mongoid/relations/referenced/one.rb +0 -290
  359. data/lib/mongoid/relations/synchronization.rb +0 -169
  360. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  361. data/lib/mongoid/relations/targets.rb +0 -2
  362. data/lib/mongoid/relations/touchable.rb +0 -97
  363. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  364. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  365. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  366. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  367. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  368. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  369. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  370. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  371. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  372. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  373. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  374. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  375. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  376. data/spec/mongoid/relations/options_spec.rb +0 -35
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Errors
4
+
5
+ # Raised when an option provided for a relation is invalid.
6
+ class InvalidRelationOption < MongoidError
7
+
8
+ # Create the new error.
9
+ #
10
+ # @example Create the new error.
11
+ # InvalidRelationOption.new(Person, invalid_option: 'make_me_a_sandwich')
12
+ #
13
+ # @param [ Class ] klass The model class.
14
+ # @param [ String, Symbol ] name The relation name.
15
+ # @param [ Symbol ] option The invalid option.
16
+ # @param [ Array<Symbol> ] valid_options The valid option.
17
+ #
18
+ # @since 3.0.0
19
+ def initialize(klass, name, option, valid_options)
20
+ super(
21
+ compose_message(
22
+ "invalid_relation_option",
23
+ { klass: klass, name: name, option: option, valid_options: valid_options }
24
+ )
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Errors
4
+
5
+ # This error is raised when trying to instantiate a model object from the value in
6
+ # the '_type' field of a document and the class doesn't exist.
7
+ class UnknownModel < MongoidError
8
+
9
+ # Create the new error.
10
+ #
11
+ # @example Instantiate the error.
12
+ # UnknownModel.new('InvalidClass', "invalid_class")
13
+ #
14
+ # @param [ String ] klass The model class.
15
+ # @param [ String ] value The value used to determine the (invalid) class.
16
+ #
17
+ # @since 7.0.0
18
+ def initialize(klass, value)
19
+ super(
20
+ compose_message("unknown_model", { klass: klass, value: value })
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
@@ -8,6 +8,7 @@ require "mongoid/errors/eager_load"
8
8
  require "mongoid/errors/in_memory_collation_not_supported"
9
9
  require "mongoid/errors/invalid_collection"
10
10
  require "mongoid/errors/invalid_config_option"
11
+ require "mongoid/errors/invalid_dependent_strategy"
11
12
  require "mongoid/errors/invalid_field"
12
13
  require "mongoid/errors/invalid_field_option"
13
14
  require "mongoid/errors/invalid_find"
@@ -17,6 +18,7 @@ require "mongoid/errors/invalid_options"
17
18
  require "mongoid/errors/invalid_path"
18
19
  require "mongoid/errors/invalid_persistence_option"
19
20
  require "mongoid/errors/invalid_relation"
21
+ require "mongoid/errors/invalid_relation_option"
20
22
  require "mongoid/errors/invalid_scope"
21
23
  require "mongoid/errors/invalid_session_use"
22
24
  require "mongoid/errors/invalid_set_polymorphic_relation"
@@ -42,6 +44,7 @@ require "mongoid/errors/readonly_document"
42
44
  require "mongoid/errors/scope_overwrite"
43
45
  require "mongoid/errors/too_many_nested_attribute_records"
44
46
  require "mongoid/errors/unknown_attribute"
47
+ require "mongoid/errors/unknown_model"
45
48
  require "mongoid/errors/unsaved_document"
46
49
  require "mongoid/errors/unsupported_javascript"
47
50
  require "mongoid/errors/validations"
@@ -122,22 +122,22 @@ module Mongoid
122
122
 
123
123
  module ClassMethods
124
124
 
125
- # Convert the provided object to a propery array of foreign keys.
125
+ # Convert the provided object to a proper array of foreign keys.
126
126
  #
127
127
  # @example Mongoize the object.
128
128
  # Array.__mongoize_fk__(constraint, object)
129
129
  #
130
- # @param [ Constraint ] constraint The metadata constraint.
130
+ # @param [ Association ] association The association metadata.
131
131
  # @param [ Object ] object The object to convert.
132
132
  #
133
133
  # @return [ Array ] The array of ids.
134
134
  #
135
135
  # @since 3.0.0
136
- def __mongoize_fk__(constraint, object)
136
+ def __mongoize_fk__(association, object)
137
137
  if object.resizable?
138
- object.blank? ? object : constraint.convert(object)
138
+ object.blank? ? object : association.convert_to_foreign_key(object)
139
139
  else
140
- object.blank? ? [] : constraint.convert(Array(object))
140
+ object.blank? ? [] : association.convert_to_foreign_key(Array(object))
141
141
  end
142
142
  end
143
143
 
@@ -46,9 +46,11 @@ module Mongoid
46
46
  value.each_pair do |_key, _value|
47
47
  value[_key] = (key == "$rename") ? _value.to_s : mongoize_for(key, klass, _key, _value)
48
48
  end
49
- (consolidated[key] ||= {}).merge!(value)
49
+ consolidated[key] ||= {}
50
+ consolidated[key].update(value)
50
51
  else
51
- (consolidated["$set"] ||= {}).merge!(key => mongoize_for(key, klass, key, value))
52
+ consolidated["$set"] ||= {}
53
+ consolidated["$set"].update(key => mongoize_for(key, klass, key, value))
52
54
  end
53
55
  end
54
56
  consolidated
@@ -106,8 +108,11 @@ module Mongoid
106
108
  value = self
107
109
  keys.each do |key|
108
110
  return nil if value.nil?
109
- nested = value[key] || value[key.to_i]
110
- value = nested
111
+ value_for_key = value[key]
112
+ if value_for_key.nil? && key.to_i.to_s == key
113
+ value_for_key = value[key.to_i]
114
+ end
115
+ value = value_for_key
111
116
  end
112
117
  value
113
118
  end
@@ -225,17 +225,17 @@ module Mongoid
225
225
  # contstraint.
226
226
  #
227
227
  # @example Convert the object to a fk.
228
- # Object.__mongoize_fk__(constraint, object)
228
+ # Object.__mongoize_fk__(association, object)
229
229
  #
230
- # @param [ Constraint ] constraint The constraint.
230
+ # @param [ Association ] association The association metadata.
231
231
  # @param [ Object ] object The object to convert.
232
232
  #
233
233
  # @return [ Object ] The converted object.
234
234
  #
235
235
  # @since 3.0.0
236
- def __mongoize_fk__(constraint, object)
236
+ def __mongoize_fk__(association, object)
237
237
  return nil if !object || object == ""
238
- constraint.convert(object)
238
+ association.convert_to_foreign_key(object)
239
239
  end
240
240
 
241
241
  # Convert the object from its mongo friendly ruby type to this type.
@@ -70,6 +70,7 @@ module Mongoid
70
70
  def mongoize(object)
71
71
  return nil if object.nil?
72
72
  return object if object.is_a?(::Hash)
73
+ return object if object.is_a?(String)
73
74
  hash = { "min" => object.first, "max" => object.last }
74
75
  if object.respond_to?(:exclude_end?) && object.exclude_end?
75
76
  hash.merge!("exclude_end" => true)
@@ -9,7 +9,7 @@ module Mongoid
9
9
  # type.
10
10
  #
11
11
  # @example Mongoize the object.
12
- # Regexp.mongoize(/^[abc]/)
12
+ # Regexp.mongoize(/\A[abc]/)
13
13
  #
14
14
  # @param [ Regexp, String ] object The object to mongoize.
15
15
  #
@@ -69,7 +69,7 @@ module Mongoid
69
69
  #
70
70
  # @since 2.3.1
71
71
  def mongoid_id?
72
- self =~ /\A(|_)id$/
72
+ self =~ /\A(|_)id\z/
73
73
  end
74
74
 
75
75
  # Is the string a number? The literals "NaN", "Infinity", and "-Infinity"
@@ -96,7 +96,7 @@ module Mongoid
96
96
  #
97
97
  # @since 1.0.0
98
98
  def reader
99
- delete("=").sub(/\_before\_type\_cast$/, '')
99
+ delete("=").sub(/\_before\_type\_cast\z/, '')
100
100
  end
101
101
 
102
102
  # Is this string a writer?
@@ -5,10 +5,6 @@ class BSON::ObjectId
5
5
  end
6
6
  end
7
7
 
8
- class Symbol
9
- remove_method :size if instance_methods.include? :size # temporal fix for ruby 1.9
10
- end
11
-
12
8
  class BSON::Document
13
9
  # We need to override this as ActiveSupport creates a new Object, instead of a new Hash
14
10
  # see https://github.com/rails/rails/commit/f1bad130d0c9bd77c94e43b696adca56c46a66aa
@@ -38,12 +38,22 @@ module Mongoid
38
38
  # #only we give the document a list of the selected fields.
39
39
  #
40
40
  # @return [ Document ] The instantiated document.
41
- def from_db(klass, attributes = nil, selected_fields = nil)
41
+ def from_db(klass, attributes = nil, criteria = nil)
42
+ selected_fields = criteria.options[:fields] if criteria
42
43
  type = (attributes || {})[TYPE]
43
44
  if type.blank?
44
- klass.instantiate(attributes, selected_fields)
45
+ obj = klass.instantiate(attributes, selected_fields)
46
+ if criteria && criteria.association && criteria.parent_document
47
+ obj.set_relation(criteria.association.inverse, criteria.parent_document)
48
+ end
49
+ obj
45
50
  else
46
- type.camelize.constantize.instantiate(attributes, selected_fields)
51
+ camelized = type.camelize
52
+ begin
53
+ camelized.constantize.instantiate(attributes, selected_fields)
54
+ rescue NameError
55
+ raise Errors::UnknownModel.new(camelized, type)
56
+ end
47
57
  end
48
58
  end
49
59
  end
@@ -63,8 +63,8 @@ module Mongoid
63
63
  # @since 3.0.0
64
64
  def evolve(object)
65
65
  if object_id_field? || object.is_a?(Document)
66
- if metadata.polymorphic? && constraint
67
- constraint.convert(object)
66
+ if association.polymorphic?
67
+ association.convert_to_foreign_key(object)
68
68
  else
69
69
  object.__evolve_object_id__
70
70
  end
@@ -97,7 +97,7 @@ module Mongoid
97
97
  # @since 3.0.0
98
98
  def mongoize(object)
99
99
  if type.resizable? || object_id_field?
100
- type.__mongoize_fk__(constraint, object)
100
+ type.__mongoize_fk__(association, object)
101
101
  else
102
102
  related_id_field.mongoize(object)
103
103
  end
@@ -113,7 +113,7 @@ module Mongoid
113
113
  # @since 2.2.0
114
114
  def object_id_field?
115
115
  @object_id_field ||=
116
- metadata.polymorphic? ? true : metadata.klass.using_object_ids?
116
+ association.polymorphic? ? true : association.klass.using_object_ids?
117
117
  end
118
118
 
119
119
  # Returns true if an array, false if not.
@@ -156,7 +156,7 @@ module Mongoid
156
156
  #
157
157
  # @since 3.0.0
158
158
  def related_id_field
159
- @related_id_field ||= metadata.klass.fields["_id"]
159
+ @related_id_field ||= association.klass.fields["_id"]
160
160
  end
161
161
 
162
162
  # This is used when default values need to be serialized. Most of the
@@ -26,18 +26,6 @@ module Mongoid
26
26
  mods[key] = new
27
27
  end
28
28
 
29
- # Get the constraint from the metadata once.
30
- #
31
- # @example Get the constraint.
32
- # field.constraint
33
- #
34
- # @return [ Constraint ] The relation's contraint.
35
- #
36
- # @since 2.1.0
37
- def constraint
38
- @constraint ||= metadata.constraint
39
- end
40
-
41
29
  # Evaluate the default value and return it. Will handle the
42
30
  # serialization, proc calls, and duplication if necessary.
43
31
  #
@@ -127,8 +115,8 @@ module Mongoid
127
115
  # @return [ Metadata ] The relation metadata.
128
116
  #
129
117
  # @since 2.2.0
130
- def metadata
131
- @metadata ||= options[:metadata]
118
+ def association
119
+ @association ||= options[:association]
132
120
  end
133
121
 
134
122
  # Is the field a BSON::ObjectId?
@@ -14,7 +14,7 @@ module Mongoid
14
14
  :label,
15
15
  :localize,
16
16
  :fallbacks,
17
- :metadata,
17
+ :association,
18
18
  :pre_processed,
19
19
  :subtype,
20
20
  :type,
@@ -411,7 +411,7 @@ module Mongoid
411
411
  def create_field_getter(name, meth, field)
412
412
  generated_methods.module_eval do
413
413
  re_define_method(meth) do
414
- raw = read_attribute(name)
414
+ raw = read_raw_attribute(name)
415
415
  if lazy_settable?(field, raw)
416
416
  write_attribute(name, field.eval_default(self))
417
417
  else
@@ -461,7 +461,7 @@ module Mongoid
461
461
  re_define_method("#{meth}=") do |value|
462
462
  val = write_attribute(name, value)
463
463
  if field.foreign_key?
464
- remove_ivar(field.metadata.name)
464
+ remove_ivar(field.association.name)
465
465
  end
466
466
  val
467
467
  end
@@ -480,7 +480,7 @@ module Mongoid
480
480
  def create_field_check(name, meth)
481
481
  generated_methods.module_eval do
482
482
  re_define_method("#{meth}?") do
483
- value = read_attribute(name)
483
+ value = read_raw_attribute(name)
484
484
  lookup_attribute_presence(name, value)
485
485
  end
486
486
  end
@@ -498,7 +498,8 @@ module Mongoid
498
498
  def create_translations_getter(name, meth)
499
499
  generated_methods.module_eval do
500
500
  re_define_method("#{meth}_translations") do
501
- (attributes[name] ||= {}).with_indifferent_access
501
+ attributes[name] ||= {}
502
+ attributes[name].with_indifferent_access
502
503
  end
503
504
  alias_method :"#{meth}_t", :"#{meth}_translations"
504
505
  end
@@ -28,8 +28,11 @@ module Mongoid
28
28
  # @since 1.0.0
29
29
  def create_indexes
30
30
  return unless index_specifications
31
+
32
+ default_options = {background: Config.background_indexing}
33
+
31
34
  index_specifications.each do |spec|
32
- key, options = spec.key, spec.options
35
+ key, options = spec.key, default_options.merge(spec.options)
33
36
  if database = options[:database]
34
37
  with(database: database) do |klass|
35
38
  klass.collection.indexes(session: _session).create_one(key, options.except(:database))
@@ -160,8 +160,8 @@ module Mongoid
160
160
  #
161
161
  # @since 2.3.0
162
162
  def cascadable_children(kind, children = Set.new)
163
- embedded_relations.each_pair do |name, metadata|
164
- next unless metadata.cascading_callbacks?
163
+ embedded_relations.each_pair do |name, association|
164
+ next unless association.cascading_callbacks?
165
165
  without_autobuild do
166
166
  delayed_pulls = delayed_atomic_pulls[name]
167
167
  delayed_unsets = delayed_atomic_unsets[name]
@@ -170,7 +170,7 @@ module Mongoid
170
170
  relation = send(name)
171
171
  Array.wrap(relation).each do |child|
172
172
  next if children.include?(child)
173
- children.add(child) if cascadable_child?(kind, child, metadata)
173
+ children.add(child) if cascadable_child?(kind, child, association)
174
174
  child.send(:cascadable_children, kind, children)
175
175
  end
176
176
  end
@@ -189,9 +189,9 @@ module Mongoid
189
189
  # @return [ true, false ] If the child should fire the callback.
190
190
  #
191
191
  # @since 2.3.0
192
- def cascadable_child?(kind, child, metadata)
192
+ def cascadable_child?(kind, child, association)
193
193
  return false if kind == :initialize || kind == :find || kind == :touch
194
- return false if kind == :validate && metadata.validate?
194
+ return false if kind == :validate && association.validate?
195
195
  child.callback_executable?(kind) ? child.in_callback_state?(kind) : false
196
196
  end
197
197
 
@@ -228,9 +228,11 @@ module Mongoid
228
228
  # document.halted_callback_hook(filter)
229
229
  #
230
230
  # @param [ Symbol ] filter The callback that halted.
231
+ # @param [ Symbol ] name The name of the callback that was halted
232
+ # (requires Rails 6.1+)
231
233
  #
232
234
  # @since 3.0.3
233
- def halted_callback_hook(filter)
235
+ def halted_callback_hook(filter, name = nil)
234
236
  @before_callback_halted = true
235
237
  end
236
238
 
@@ -10,11 +10,12 @@ module Mongoid
10
10
  # @example Do the values match?
11
11
  # matcher._matches?({ :key => 10 })
12
12
  #
13
- # @param [ Hash ] value The values to check.
13
+ # @param [ Hash ] condition The condition to evaluate. This must be
14
+ # a one-element hash like {'$gt' => 1}.
14
15
  #
15
16
  # @return [ true, false ] If the values match.
16
- def _matches?(value)
17
- first = first(value)
17
+ def _matches?(condition)
18
+ first = condition_value(condition)
18
19
  return false if first.is_a?(Array) && first.empty?
19
20
 
20
21
  attribute_array = Array.wrap(@attribute)
@@ -2,7 +2,7 @@
2
2
  module Mongoid
3
3
  module Matchable
4
4
 
5
- # Defines behavior for handling $or expressions in embedded documents.
5
+ # Defines behavior for handling $and expressions in embedded documents.
6
6
  class And < Default
7
7
 
8
8
  # Does the supplied query match the attribute?
@@ -20,52 +20,99 @@ module Mongoid
20
20
  @attribute, @document = attribute, document
21
21
  end
22
22
 
23
- # Return true if the attribute and value are equal, or if it is an array
24
- # if the value is included.
23
+ # Checks whether the attribute matches the value, using the default
24
+ # MongoDB matching logic (i.e., when no operator is specified in the
25
+ # criteria).
25
26
  #
26
- # @example Does this value match?
27
- # default._matches?("value")
27
+ # If attribute and value are both of basic types like string or number,
28
+ # this method returns true if and only if the attribute equals the value.
28
29
  #
29
- # @param [ Object ] value The value to check if it matches.
30
+ # Value can also be of a type like Regexp or Range which defines
31
+ # more complex matching/inclusion behavior via the === operator.
32
+ # If so, and attribute is still of a basic type like string or number,
33
+ # this method returns true if and only if the value's === operator
34
+ # returns true for the attribute. For example, this method returns true
35
+ # if attribute is a string and value is a Regexp and attribute matches
36
+ # the value, of if attribute is a number and value is a Range and
37
+ # the value includes the attribute.
30
38
  #
31
- # @return [ true, false ] True if matches, false if not.
39
+ # If attribute is an array and value is not an array, the checks just
40
+ # described (i.e. the === operator invocation) are performed on each item
41
+ # of the attribute array. If any of the items in the attribute match
42
+ # the value according to the value type's === operator, this method
43
+ # returns true.
44
+ #
45
+ # If attribute and value are both arrays, this method returns true if and
46
+ # only if the arrays are equal (including the order of the elements).
47
+ #
48
+ # @param [ Object ] value The value to check.
49
+ #
50
+ # @return [ true, false ] True if attribute matches the value, false if not.
32
51
  #
33
52
  # @since 1.0.0
34
53
  def _matches?(value)
35
- attribute.is_a?(Array) && !value.is_a?(Array) ? attribute.any? { |_attribute| value === _attribute } : value === attribute
54
+ if attribute.is_a?(Array) && !value.is_a?(Array)
55
+ attribute.any? { |_attribute| value === _attribute }
56
+ else
57
+ value === attribute
58
+ end
36
59
  end
37
60
 
38
61
  protected
39
62
 
40
- # Convenience method for getting the first value in a hash.
63
+ # Given a condition, which is a one-element hash consisting of an
64
+ # operator and a value like {'$gt' => 1}, return the value.
41
65
  #
42
- # @example Get the first value.
43
- # matcher.first(:test => "value")
66
+ # @example Get the condition value.
67
+ # matcher.condition_value({'$gt' => 1})
68
+ # # => 1
44
69
  #
45
- # @param [ Hash ] hash The has to pull from.
70
+ # @param [ Hash ] condition The condition.
46
71
  #
47
- # @return [ Object ] The first value.
72
+ # @return [ Object ] The value of the condition.
48
73
  #
49
74
  # @since 1.0.0
50
- def first(hash)
51
- hash.values.first
75
+ def condition_value(condition)
76
+ unless condition.is_a?(Hash)
77
+ raise ArgumentError, 'Condition must be a hash'
78
+ end
79
+
80
+ unless condition.length == 1
81
+ raise ArgumentError, 'Condition must have one element'
82
+ end
83
+
84
+ condition.values.first
52
85
  end
53
86
 
54
- # If object exists then compare the two, otherwise return false
87
+ # Determines whether the attribute value stored in this matcher
88
+ # satisfies the provided condition using the provided operator.
89
+ #
90
+ # For example, given an instance of Gt matcher with the @attribute of
91
+ # 2, the matcher is set up to answer whether the attribute is
92
+ # greater than some input value. This input value is provided in
93
+ # the condition, which could be {"$gt" => 1}, and the operator is
94
+ # provided (somewhat in a duplicate fashion) in the operator argument,
95
+ # in this case :>.
55
96
  #
56
- # @example Determine if we can compare.
57
- # matcher.determine("test", "$in")
97
+ # @example
98
+ # matcher = Matchable::Gt.new(2)
99
+ # matcher.determine({'$gt' => 1}, :>)
100
+ # # => true
58
101
  #
59
- # @param [ Object ] value The value to compare with.
60
- # @param [ Symbol, String ] operator The comparison operation.
102
+ # @param [ Hash ] condition The condition to evaluate. This must be
103
+ # a one-element hash; the key is ignored, and the value is passed
104
+ # as the argument to the operator.
105
+ # @param [ Symbol, String ] operator The comparison operator or method.
106
+ # The operator is invoked on the attribute stored in the matcher
107
+ # instance.
61
108
  #
62
- # @return [ true, false ] The comparison or false.
109
+ # @return [ true, false ] Result of condition evaluation.
63
110
  #
64
111
  # @since 1.0.0
65
- def determine(value, operator)
66
- attribute.__array__.any? {|attr|
67
- attr ? attr.send(operator, first(value)) : false
68
- }
112
+ def determine(condition, operator)
113
+ attribute.__array__.any? do |attr|
114
+ attr && attr.send(operator, condition_value(condition))
115
+ end
69
116
  end
70
117
  end
71
118
  end
@@ -13,13 +13,19 @@ module Mongoid
13
13
  #
14
14
  # @return [ true, false ] If the values match.
15
15
  def _matches?(value)
16
- if !@attribute.is_a?(Array) || !value.kind_of?(Hash) || !value["$elemMatch"].kind_of?(Hash)
16
+ elem_match = value["$elemMatch"] || value[:$elemMatch]
17
+
18
+ if !@attribute.is_a?(Array) || !value.kind_of?(Hash) || !elem_match.kind_of?(Hash)
17
19
  return false
18
20
  end
19
21
 
20
22
  return @attribute.any? do |sub_document|
21
- value["$elemMatch"].all? do |k, v|
22
- Matchable.matcher(sub_document, k, v)._matches?(v)
23
+ elem_match.all? do |k, v|
24
+ if v.try(:first).try(:[],0) == "$not".freeze || v.try(:first).try(:[],0) == :$not
25
+ !Matchable.matcher(sub_document, k, v.first[1])._matches?(v.first[1])
26
+ else
27
+ Matchable.matcher(sub_document, k, v)._matches?(v)
28
+ end
23
29
  end
24
30
  end
25
31
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+ module Mongoid
4
+ module Matchable
5
+
6
+ # Performs equivalency checks.
7
+ class Eq < Default
8
+
9
+ # Return true if the attribute and first value are equal.
10
+ #
11
+ # @example Do the values match?
12
+ # matcher._matches?({ :key => 10 })
13
+ #
14
+ # @param [ Hash ] value The values to check.
15
+ #
16
+ # @return [ true, false ] True if matches, false if not.
17
+ def _matches?(value)
18
+ super(value.values.first)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@ module Mongoid
12
12
  #
13
13
  # @param [ Hash ] value The values to check.
14
14
  #
15
- # @return [ true, false ] If a value exists.
15
+ # @return [ true, false ] True if matches, false if not.
16
16
  def _matches?(value)
17
17
  !super(value.values.first)
18
18
  end
@@ -7,8 +7,8 @@ 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?(/\AEm/)
11
+ # matcher._matches?(BSON::Regex::Raw.new("\\AEm"))
12
12
  #
13
13
  # @param [ BSON::Regexp::Raw, Regexp ] regexp The regular expression object.
14
14
  #