mongoid-multi-db 3.0.0

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 (276) hide show
  1. data/CHANGELOG.md +615 -0
  2. data/LICENSE +20 -0
  3. data/README.md +62 -0
  4. data/Rakefile +49 -0
  5. data/lib/config/locales/bg.yml +54 -0
  6. data/lib/config/locales/de.yml +54 -0
  7. data/lib/config/locales/en-GB.yml +55 -0
  8. data/lib/config/locales/en.yml +55 -0
  9. data/lib/config/locales/es.yml +52 -0
  10. data/lib/config/locales/fr.yml +55 -0
  11. data/lib/config/locales/hi.yml +46 -0
  12. data/lib/config/locales/hu.yml +57 -0
  13. data/lib/config/locales/id.yml +55 -0
  14. data/lib/config/locales/it.yml +52 -0
  15. data/lib/config/locales/ja.yml +50 -0
  16. data/lib/config/locales/kr.yml +47 -0
  17. data/lib/config/locales/nl.yml +52 -0
  18. data/lib/config/locales/pl.yml +52 -0
  19. data/lib/config/locales/pt-BR.yml +53 -0
  20. data/lib/config/locales/pt.yml +53 -0
  21. data/lib/config/locales/ro.yml +59 -0
  22. data/lib/config/locales/ru.yml +54 -0
  23. data/lib/config/locales/sv.yml +53 -0
  24. data/lib/config/locales/vi.yml +55 -0
  25. data/lib/config/locales/zh-CN.yml +46 -0
  26. data/lib/mongoid.rb +148 -0
  27. data/lib/mongoid/atomic.rb +230 -0
  28. data/lib/mongoid/atomic/modifiers.rb +243 -0
  29. data/lib/mongoid/atomic/paths.rb +3 -0
  30. data/lib/mongoid/atomic/paths/embedded.rb +43 -0
  31. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  32. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  33. data/lib/mongoid/atomic/paths/root.rb +40 -0
  34. data/lib/mongoid/attributes.rb +234 -0
  35. data/lib/mongoid/attributes/processing.rb +146 -0
  36. data/lib/mongoid/callbacks.rb +135 -0
  37. data/lib/mongoid/collection.rb +153 -0
  38. data/lib/mongoid/collection_proxy.rb +59 -0
  39. data/lib/mongoid/collections.rb +120 -0
  40. data/lib/mongoid/collections/master.rb +45 -0
  41. data/lib/mongoid/collections/operations.rb +44 -0
  42. data/lib/mongoid/collections/retry.rb +46 -0
  43. data/lib/mongoid/components.rb +96 -0
  44. data/lib/mongoid/config.rb +347 -0
  45. data/lib/mongoid/config/database.rb +186 -0
  46. data/lib/mongoid/config/replset_database.rb +82 -0
  47. data/lib/mongoid/connection_proxy.rb +30 -0
  48. data/lib/mongoid/contexts.rb +25 -0
  49. data/lib/mongoid/contexts/enumerable.rb +288 -0
  50. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  51. data/lib/mongoid/contexts/mongo.rb +409 -0
  52. data/lib/mongoid/copyable.rb +48 -0
  53. data/lib/mongoid/criteria.rb +418 -0
  54. data/lib/mongoid/criterion/builder.rb +34 -0
  55. data/lib/mongoid/criterion/complex.rb +84 -0
  56. data/lib/mongoid/criterion/creational.rb +34 -0
  57. data/lib/mongoid/criterion/exclusion.rb +108 -0
  58. data/lib/mongoid/criterion/inclusion.rb +305 -0
  59. data/lib/mongoid/criterion/inspection.rb +22 -0
  60. data/lib/mongoid/criterion/optional.rb +232 -0
  61. data/lib/mongoid/criterion/selector.rb +153 -0
  62. data/lib/mongoid/cursor.rb +86 -0
  63. data/lib/mongoid/database_proxy.rb +97 -0
  64. data/lib/mongoid/default_scope.rb +36 -0
  65. data/lib/mongoid/dirty.rb +110 -0
  66. data/lib/mongoid/document.rb +280 -0
  67. data/lib/mongoid/errors.rb +17 -0
  68. data/lib/mongoid/errors/callback.rb +26 -0
  69. data/lib/mongoid/errors/document_not_found.rb +28 -0
  70. data/lib/mongoid/errors/eager_load.rb +25 -0
  71. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  72. data/lib/mongoid/errors/invalid_database.rb +19 -0
  73. data/lib/mongoid/errors/invalid_field.rb +18 -0
  74. data/lib/mongoid/errors/invalid_find.rb +19 -0
  75. data/lib/mongoid/errors/invalid_options.rb +28 -0
  76. data/lib/mongoid/errors/invalid_time.rb +25 -0
  77. data/lib/mongoid/errors/invalid_type.rb +25 -0
  78. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  79. data/lib/mongoid/errors/mongoid_error.rb +26 -0
  80. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  81. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  82. data/lib/mongoid/errors/unsupported_version.rb +20 -0
  83. data/lib/mongoid/errors/validations.rb +23 -0
  84. data/lib/mongoid/extensions.rb +82 -0
  85. data/lib/mongoid/extensions/array/deletion.rb +29 -0
  86. data/lib/mongoid/extensions/false_class/equality.rb +26 -0
  87. data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
  88. data/lib/mongoid/extensions/hash/scoping.rb +25 -0
  89. data/lib/mongoid/extensions/integer/checks.rb +23 -0
  90. data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
  91. data/lib/mongoid/extensions/object/checks.rb +29 -0
  92. data/lib/mongoid/extensions/object/reflections.rb +48 -0
  93. data/lib/mongoid/extensions/object/substitutable.rb +15 -0
  94. data/lib/mongoid/extensions/object/yoda.rb +44 -0
  95. data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
  96. data/lib/mongoid/extensions/proc/scoping.rb +25 -0
  97. data/lib/mongoid/extensions/string/checks.rb +36 -0
  98. data/lib/mongoid/extensions/string/conversions.rb +22 -0
  99. data/lib/mongoid/extensions/string/inflections.rb +118 -0
  100. data/lib/mongoid/extensions/symbol/checks.rb +23 -0
  101. data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
  102. data/lib/mongoid/extensions/true_class/equality.rb +26 -0
  103. data/lib/mongoid/extras.rb +31 -0
  104. data/lib/mongoid/factory.rb +46 -0
  105. data/lib/mongoid/fields.rb +332 -0
  106. data/lib/mongoid/fields/mappings.rb +41 -0
  107. data/lib/mongoid/fields/serializable.rb +201 -0
  108. data/lib/mongoid/fields/serializable/array.rb +49 -0
  109. data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
  110. data/lib/mongoid/fields/serializable/bignum.rb +10 -0
  111. data/lib/mongoid/fields/serializable/binary.rb +11 -0
  112. data/lib/mongoid/fields/serializable/boolean.rb +43 -0
  113. data/lib/mongoid/fields/serializable/date.rb +51 -0
  114. data/lib/mongoid/fields/serializable/date_time.rb +28 -0
  115. data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
  116. data/lib/mongoid/fields/serializable/float.rb +32 -0
  117. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
  118. data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
  119. data/lib/mongoid/fields/serializable/hash.rb +11 -0
  120. data/lib/mongoid/fields/serializable/integer.rb +44 -0
  121. data/lib/mongoid/fields/serializable/localized.rb +41 -0
  122. data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
  123. data/lib/mongoid/fields/serializable/object.rb +11 -0
  124. data/lib/mongoid/fields/serializable/object_id.rb +31 -0
  125. data/lib/mongoid/fields/serializable/range.rb +42 -0
  126. data/lib/mongoid/fields/serializable/set.rb +42 -0
  127. data/lib/mongoid/fields/serializable/string.rb +27 -0
  128. data/lib/mongoid/fields/serializable/symbol.rb +27 -0
  129. data/lib/mongoid/fields/serializable/time.rb +23 -0
  130. data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
  131. data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
  132. data/lib/mongoid/finders.rb +152 -0
  133. data/lib/mongoid/hierarchy.rb +120 -0
  134. data/lib/mongoid/identity.rb +92 -0
  135. data/lib/mongoid/identity_map.rb +119 -0
  136. data/lib/mongoid/indexes.rb +54 -0
  137. data/lib/mongoid/inspection.rb +54 -0
  138. data/lib/mongoid/javascript.rb +20 -0
  139. data/lib/mongoid/javascript/functions.yml +63 -0
  140. data/lib/mongoid/json.rb +16 -0
  141. data/lib/mongoid/keys.rb +144 -0
  142. data/lib/mongoid/logger.rb +39 -0
  143. data/lib/mongoid/matchers.rb +32 -0
  144. data/lib/mongoid/matchers/all.rb +21 -0
  145. data/lib/mongoid/matchers/and.rb +30 -0
  146. data/lib/mongoid/matchers/default.rb +70 -0
  147. data/lib/mongoid/matchers/exists.rb +23 -0
  148. data/lib/mongoid/matchers/gt.rb +21 -0
  149. data/lib/mongoid/matchers/gte.rb +21 -0
  150. data/lib/mongoid/matchers/in.rb +21 -0
  151. data/lib/mongoid/matchers/lt.rb +21 -0
  152. data/lib/mongoid/matchers/lte.rb +21 -0
  153. data/lib/mongoid/matchers/ne.rb +21 -0
  154. data/lib/mongoid/matchers/nin.rb +21 -0
  155. data/lib/mongoid/matchers/or.rb +33 -0
  156. data/lib/mongoid/matchers/size.rb +21 -0
  157. data/lib/mongoid/matchers/strategies.rb +93 -0
  158. data/lib/mongoid/multi_database.rb +31 -0
  159. data/lib/mongoid/multi_parameter_attributes.rb +106 -0
  160. data/lib/mongoid/named_scope.rb +146 -0
  161. data/lib/mongoid/nested_attributes.rb +54 -0
  162. data/lib/mongoid/observer.rb +170 -0
  163. data/lib/mongoid/paranoia.rb +158 -0
  164. data/lib/mongoid/persistence.rb +264 -0
  165. data/lib/mongoid/persistence/atomic.rb +223 -0
  166. data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
  167. data/lib/mongoid/persistence/atomic/bit.rb +37 -0
  168. data/lib/mongoid/persistence/atomic/inc.rb +31 -0
  169. data/lib/mongoid/persistence/atomic/operation.rb +85 -0
  170. data/lib/mongoid/persistence/atomic/pop.rb +34 -0
  171. data/lib/mongoid/persistence/atomic/pull.rb +34 -0
  172. data/lib/mongoid/persistence/atomic/pull_all.rb +34 -0
  173. data/lib/mongoid/persistence/atomic/push.rb +31 -0
  174. data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
  175. data/lib/mongoid/persistence/atomic/rename.rb +31 -0
  176. data/lib/mongoid/persistence/atomic/sets.rb +30 -0
  177. data/lib/mongoid/persistence/atomic/unset.rb +28 -0
  178. data/lib/mongoid/persistence/deletion.rb +32 -0
  179. data/lib/mongoid/persistence/insertion.rb +41 -0
  180. data/lib/mongoid/persistence/modification.rb +37 -0
  181. data/lib/mongoid/persistence/operations.rb +211 -0
  182. data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
  183. data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
  184. data/lib/mongoid/persistence/operations/insert.rb +34 -0
  185. data/lib/mongoid/persistence/operations/remove.rb +33 -0
  186. data/lib/mongoid/persistence/operations/update.rb +64 -0
  187. data/lib/mongoid/railtie.rb +126 -0
  188. data/lib/mongoid/railties/database.rake +182 -0
  189. data/lib/mongoid/railties/document.rb +12 -0
  190. data/lib/mongoid/relations.rb +144 -0
  191. data/lib/mongoid/relations/accessors.rb +138 -0
  192. data/lib/mongoid/relations/auto_save.rb +38 -0
  193. data/lib/mongoid/relations/binding.rb +26 -0
  194. data/lib/mongoid/relations/bindings.rb +9 -0
  195. data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
  196. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  197. data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
  198. data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
  199. data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
  200. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
  201. data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
  202. data/lib/mongoid/relations/builder.rb +57 -0
  203. data/lib/mongoid/relations/builders.rb +83 -0
  204. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  205. data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
  206. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  207. data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
  208. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  209. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  210. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  211. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
  212. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  213. data/lib/mongoid/relations/cascading.rb +56 -0
  214. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  215. data/lib/mongoid/relations/cascading/destroy.rb +26 -0
  216. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  217. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  218. data/lib/mongoid/relations/constraint.rb +42 -0
  219. data/lib/mongoid/relations/conversions.rb +35 -0
  220. data/lib/mongoid/relations/cyclic.rb +103 -0
  221. data/lib/mongoid/relations/embedded/atomic.rb +89 -0
  222. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  223. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  224. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  225. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  226. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  227. data/lib/mongoid/relations/embedded/in.rb +220 -0
  228. data/lib/mongoid/relations/embedded/many.rb +560 -0
  229. data/lib/mongoid/relations/embedded/one.rb +206 -0
  230. data/lib/mongoid/relations/embedded/sort.rb +31 -0
  231. data/lib/mongoid/relations/macros.rb +310 -0
  232. data/lib/mongoid/relations/many.rb +135 -0
  233. data/lib/mongoid/relations/metadata.rb +919 -0
  234. data/lib/mongoid/relations/nested_builder.rb +75 -0
  235. data/lib/mongoid/relations/one.rb +36 -0
  236. data/lib/mongoid/relations/options.rb +47 -0
  237. data/lib/mongoid/relations/polymorphic.rb +40 -0
  238. data/lib/mongoid/relations/proxy.rb +145 -0
  239. data/lib/mongoid/relations/referenced/batch.rb +72 -0
  240. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  241. data/lib/mongoid/relations/referenced/in.rb +262 -0
  242. data/lib/mongoid/relations/referenced/many.rb +623 -0
  243. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  244. data/lib/mongoid/relations/referenced/one.rb +272 -0
  245. data/lib/mongoid/relations/reflections.rb +62 -0
  246. data/lib/mongoid/relations/synchronization.rb +153 -0
  247. data/lib/mongoid/relations/targets.rb +2 -0
  248. data/lib/mongoid/relations/targets/enumerable.rb +372 -0
  249. data/lib/mongoid/reloading.rb +91 -0
  250. data/lib/mongoid/safety.rb +105 -0
  251. data/lib/mongoid/scope.rb +31 -0
  252. data/lib/mongoid/serialization.rb +134 -0
  253. data/lib/mongoid/sharding.rb +61 -0
  254. data/lib/mongoid/state.rb +97 -0
  255. data/lib/mongoid/threaded.rb +530 -0
  256. data/lib/mongoid/threaded/lifecycle.rb +192 -0
  257. data/lib/mongoid/timestamps.rb +15 -0
  258. data/lib/mongoid/timestamps/created.rb +24 -0
  259. data/lib/mongoid/timestamps/timeless.rb +50 -0
  260. data/lib/mongoid/timestamps/updated.rb +26 -0
  261. data/lib/mongoid/validations.rb +140 -0
  262. data/lib/mongoid/validations/associated.rb +46 -0
  263. data/lib/mongoid/validations/uniqueness.rb +145 -0
  264. data/lib/mongoid/version.rb +4 -0
  265. data/lib/mongoid/versioning.rb +185 -0
  266. data/lib/rack/mongoid.rb +2 -0
  267. data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
  268. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  269. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  270. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  271. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  272. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  273. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  274. data/lib/rails/generators/mongoid_generator.rb +70 -0
  275. data/lib/rails/mongoid.rb +91 -0
  276. metadata +465 -0
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module String #:nodoc:
5
+ module Conversions #:nodoc:
6
+ extend ActiveSupport::Concern
7
+
8
+ # Convert the string to an array with the string in it.
9
+ #
10
+ # @example Convert the string to an array.
11
+ # "Testing".to_a
12
+ #
13
+ # @return [ Array ] An array with only the string in it.
14
+ #
15
+ # @since 1.0.0
16
+ def to_a
17
+ [ self ]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module String #:nodoc:
5
+
6
+ # This module contains convenience methods for string inflection and
7
+ # conversion.
8
+ module Inflections
9
+
10
+ ActiveSupport::Inflector.inflections do |inflect|
11
+ inflect.singular(/address$/, "address")
12
+ inflect.singular("addresses", "address")
13
+ inflect.irregular("canvas", "canvases")
14
+ end
15
+
16
+ # Represents how special characters will get converted when creating a
17
+ # composite key that should be unique and part of a url.
18
+ CHAR_CONV = {
19
+ " " => "-",
20
+ "!" => "-excl-",
21
+ "\"" => "-dblquo-",
22
+ "#" => "-hash-",
23
+ "$" => "-dol-",
24
+ "%" => "-perc-",
25
+ "&" => "-and-",
26
+ "'" => "-quo-",
27
+ "(" => "-oparen-",
28
+ ")" => "-cparen-",
29
+ "*" => "-astx-",
30
+ "+" => "-plus-",
31
+ "," => "-comma-",
32
+ "-" => "-",
33
+ "." => "-period-",
34
+ "/" => "-fwdslsh-",
35
+ ":" => "-colon-",
36
+ ";" => "-semicol-",
37
+ "<" => "-lt-",
38
+ "=" => "-eq-",
39
+ ">" => "-gt-",
40
+ "?" => "-ques-",
41
+ "@" => "-at-",
42
+ "[" => "-obrck-",
43
+ "\\" => "-bckslsh-",
44
+ "]" => "-clbrck-",
45
+ "^" => "-carat-",
46
+ "_" => "-undscr-",
47
+ "`" => "-bcktick-",
48
+ "{" => "-ocurly-",
49
+ "|" => "-pipe-",
50
+ "}" => "-clcurly-",
51
+ "~" => "-tilde-"
52
+ }
53
+
54
+ REVERSALS = {
55
+ "asc" => "desc",
56
+ "ascending" => "descending",
57
+ "desc" => "asc",
58
+ "descending" => "ascending"
59
+ }
60
+
61
+ # Convert the string to a collection friendly name.
62
+ #
63
+ # @example Collectionize the string.
64
+ # "namespace/model".collectionize
65
+ #
66
+ # @return [ String ] The string in collection friendly form.
67
+ def collectionize
68
+ tableize.gsub("/", "_")
69
+ end
70
+
71
+ # Convert this string to a key friendly string.
72
+ #
73
+ # @example Convert to key.
74
+ # "testing".identify
75
+ #
76
+ # @return [ String ] The key friendly string.
77
+ def identify
78
+ if Mongoid.parameterize_keys
79
+ key = ""
80
+ each_char { |c| key += (CHAR_CONV[c] || c.downcase) }; key
81
+ else
82
+ self
83
+ end
84
+ end
85
+
86
+ # Get the inverted sorting option.
87
+ #
88
+ # @example Get the inverted option.
89
+ # "asc".invert
90
+ #
91
+ # @return [ String ] The string inverted.
92
+ def invert
93
+ REVERSALS[self]
94
+ end
95
+
96
+ # Get the string as a getter string.
97
+ #
98
+ # @example Get the reader/getter
99
+ # "model=".reader
100
+ #
101
+ # @return [ String ] The string stripped of "=".
102
+ def reader
103
+ writer? ? gsub("=", "") : self
104
+ end
105
+
106
+ # Is this string a writer?
107
+ #
108
+ # @example Is the string a setter method?
109
+ # "model=".writer?
110
+ #
111
+ # @return [ true, false ] If the string contains "=".
112
+ def writer?
113
+ include?("=")
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Symbol #:nodoc:
5
+
6
+ # This module has object checks in it.
7
+ module Checks #:nodoc:
8
+
9
+ # Is the symbol a valid value for a Mongoid id?
10
+ #
11
+ # @example Is the string an id value?
12
+ # :_id.mongoid_id?
13
+ #
14
+ # @return [ true, false ] If the symbol is :id or :_id.
15
+ #
16
+ # @since 2.3.1
17
+ def mongoid_id?
18
+ to_s =~ /^(|_)id$/
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Symbol #:nodoc:
5
+
6
+ # This module contains convenience methods for symbol inflection and
7
+ # conversion.
8
+ module Inflections
9
+
10
+ REVERSALS = {
11
+ :asc => :desc,
12
+ :ascending => :descending,
13
+ :desc => :asc,
14
+ :descending => :ascending
15
+ }
16
+
17
+ # Get the inverted sorting option.
18
+ #
19
+ # @example Get the inverted option.
20
+ # :asc.invert
21
+ #
22
+ # @return [ String ] The string inverted.
23
+ def invert
24
+ REVERSALS[self]
25
+ end
26
+
27
+ # Define all the necessary methods on symbol to support Mongoid's
28
+ # complex criterion.
29
+ #
30
+ # @example A greater than criterion.
31
+ # :field.gt => 5
32
+ #
33
+ # @return [ Criterion::Complex ] The criterion.
34
+ #
35
+ # @since 1.0.0
36
+ [
37
+ "all",
38
+ "asc",
39
+ "ascending",
40
+ "desc",
41
+ "descending",
42
+ "exists",
43
+ "gt",
44
+ "gte",
45
+ "in",
46
+ "lt",
47
+ "lte",
48
+ "mod",
49
+ "ne",
50
+ "near",
51
+ "nin",
52
+ "size",
53
+ "within",
54
+ ["matches","elemMatch"] ].each do |oper|
55
+ m, oper = oper
56
+ oper = m unless oper
57
+ class_eval <<-OPERATORS
58
+ def #{m}
59
+ Criterion::Complex.new(:key => self, :operator => "#{oper}")
60
+ end
61
+ OPERATORS
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module TrueClass #:nodoc:
5
+
6
+ # Adds equality hooks for true values.
7
+ module Equality
8
+
9
+ # Is the passed value a boolean?
10
+ #
11
+ # @example Is the value a boolean type?
12
+ # true.is_a?(Boolean)
13
+ #
14
+ # @param [ Class ] other The class to check.
15
+ #
16
+ # @return [ true, false ] If the other is a boolean.
17
+ #
18
+ # @since 1.0.0
19
+ def is_a?(other)
20
+ return true if other.name == "Boolean"
21
+ super(other)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # Adds support for caching queries at the class level.
5
+ module Extras
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class_attribute :cached
10
+ self.cached = false
11
+ end
12
+
13
+ module ClassMethods #:nodoc
14
+
15
+ # Sets caching on for this class. This class level configuration will
16
+ # default all queries to cache the results of the first iteration over
17
+ # the cursor into an internal array. This should only be used for queries
18
+ # that return a small number of results or have small documents, as after
19
+ # the first iteration the entire results will be stored in memory.
20
+ #
21
+ # @example Cache all reads for the class.
22
+ # class Person
23
+ # include Mongoid::Document
24
+ # cache
25
+ # end
26
+ def cache
27
+ self.cached = true
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # Instantiates documents that came from the database.
5
+ module Factory
6
+ extend self
7
+
8
+ # Builds a new +Document+ from the supplied attributes.
9
+ #
10
+ # @example Build the document.
11
+ # Mongoid::Factory.build(Person, { "name" => "Durran" })
12
+ #
13
+ # @param [ Class ] klass The class to instantiate from if _type is not present.
14
+ # @param [ Hash ] attributes The document attributes.
15
+ # @param [ Hash ] optiosn The mass assignment scoping options.
16
+ #
17
+ # @return [ Document ] The instantiated document.
18
+ def build(klass, attributes = {}, options = {})
19
+ type = (attributes || {})["_type"]
20
+ if type && klass._types.include?(type)
21
+ type.constantize.new(attributes, options)
22
+ else
23
+ klass.new(attributes, options)
24
+ end
25
+ end
26
+
27
+ # Builds a new +Document+ from the supplied attributes loaded from the
28
+ # database.
29
+ #
30
+ # @example Build the document.
31
+ # Mongoid::Factory.from_db(Person, { "name" => "Durran" })
32
+ #
33
+ # @param [ Class ] klass The class to instantiate from if _type is not present.
34
+ # @param [ Hash ] attributes The document attributes.
35
+ #
36
+ # @return [ Document ] The instantiated document.
37
+ def from_db(klass, attributes = {})
38
+ type = attributes["_type"]
39
+ if type.blank?
40
+ klass.instantiate(attributes)
41
+ else
42
+ type.camelize.constantize.instantiate(attributes)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,332 @@
1
+ # encoding: utf-8
2
+ require "mongoid/fields/mappings"
3
+ require "mongoid/fields/serializable"
4
+ require "mongoid/fields/serializable/timekeeping"
5
+ require "mongoid/fields/serializable/array"
6
+ require "mongoid/fields/serializable/big_decimal"
7
+ require "mongoid/fields/serializable/binary"
8
+ require "mongoid/fields/serializable/boolean"
9
+ require "mongoid/fields/serializable/date"
10
+ require "mongoid/fields/serializable/date_time"
11
+ require "mongoid/fields/serializable/float"
12
+ require "mongoid/fields/serializable/hash"
13
+ require "mongoid/fields/serializable/integer"
14
+ require "mongoid/fields/serializable/bignum"
15
+ require "mongoid/fields/serializable/fixnum"
16
+ require "mongoid/fields/serializable/localized"
17
+ require "mongoid/fields/serializable/nil_class"
18
+ require "mongoid/fields/serializable/object"
19
+ require "mongoid/fields/serializable/object_id"
20
+ require "mongoid/fields/serializable/range"
21
+ require "mongoid/fields/serializable/set"
22
+ require "mongoid/fields/serializable/string"
23
+ require "mongoid/fields/serializable/symbol"
24
+ require "mongoid/fields/serializable/time"
25
+ require "mongoid/fields/serializable/time_with_zone"
26
+ require "mongoid/fields/serializable/foreign_keys/array"
27
+ require "mongoid/fields/serializable/foreign_keys/object"
28
+
29
+ module Mongoid #:nodoc
30
+
31
+ # This module defines behaviour for fields.
32
+ module Fields
33
+ extend ActiveSupport::Concern
34
+
35
+ included do
36
+ field(:_type, :type => String)
37
+ field(:_id, :type => BSON::ObjectId)
38
+
39
+ alias :id :_id
40
+ alias :id= :_id=
41
+ end
42
+
43
+ # Get the default fields.
44
+ #
45
+ # @note Refactored from using delegate for class load performance.
46
+ #
47
+ # @example Get the defaults.
48
+ # model.defaults
49
+ #
50
+ # @return [ Array<String> ] The default field names.
51
+ def defaults
52
+ self.class.defaults
53
+ end
54
+
55
+ # Get the document's fields.
56
+ #
57
+ # @note Refactored from using delegate for class load performance.
58
+ #
59
+ # @example Get the fields.
60
+ # model.fields
61
+ #
62
+ # @return [ Hash ] The fields.
63
+ def fields
64
+ self.class.fields
65
+ end
66
+
67
+ class << self
68
+
69
+ # Stores the provided block to be run when the option name specified is
70
+ # defined on a field.
71
+ #
72
+ # No assumptions are made about what sort of work the handler might
73
+ # perform, so it will always be called if the `option_name` key is
74
+ # provided in the field definition -- even if it is false or nil.
75
+ #
76
+ # @example
77
+ # Mongoid::Fields.option :required do |model, field, value|
78
+ # model.validates_presence_of field if value
79
+ # end
80
+ #
81
+ # @param [ Symbol ] option_name the option name to match against
82
+ # @param [ Proc ] block the handler to execute when the option is
83
+ # provided.
84
+ #
85
+ # @since 2.1.0
86
+ def option(option_name, &block)
87
+ options[option_name] = block
88
+ end
89
+
90
+ # Return a map of custom option names to their handlers.
91
+ #
92
+ # @example
93
+ # Mongoid::Fields.options
94
+ # # => { :required => #<Proc:0x00000100976b38> }
95
+ #
96
+ # @return [ Hash ] the option map
97
+ #
98
+ # @since 2.1.0
99
+ def options
100
+ @options ||= {}
101
+ end
102
+ end
103
+
104
+ module ClassMethods #:nodoc
105
+
106
+ # Returns the default values for the fields on the document.
107
+ #
108
+ # @example Get the defaults.
109
+ # Person.defaults
110
+ #
111
+ # @return [ Hash ] The field defaults.
112
+ def defaults
113
+ @defaults ||= []
114
+ end
115
+
116
+ # Set the defaults for the class.
117
+ #
118
+ # @example Set the defaults.
119
+ # Person.defaults = defaults
120
+ #
121
+ # @param [ Array ] defaults The array of defaults to set.
122
+ #
123
+ # @since 2.0.0.rc.6
124
+ def defaults=(defaults)
125
+ @defaults = defaults
126
+ end
127
+
128
+ # Defines all the fields that are accessible on the Document
129
+ # For each field that is defined, a getter and setter will be
130
+ # added as an instance method to the Document.
131
+ #
132
+ # @example Define a field.
133
+ # field :score, :type => Integer, :default => 0
134
+ #
135
+ # @param [ Symbol ] name The name of the field.
136
+ # @param [ Hash ] options The options to pass to the field.
137
+ #
138
+ # @option options [ Class ] :type The type of the field.
139
+ # @option options [ String ] :label The label for the field.
140
+ # @option options [ Object, Proc ] :default The field's default
141
+ #
142
+ # @return [ Field ] The generated field
143
+ def field(name, options = {})
144
+ check_field_name!(name)
145
+ add_field(name.to_s, options)
146
+ end
147
+
148
+ # Return the fields for this class.
149
+ #
150
+ # @example Get the fields.
151
+ # Person.fields
152
+ #
153
+ # @return [ Hash ] The fields for this document.
154
+ #
155
+ # @since 2.0.0.rc.6
156
+ def fields
157
+ @fields ||= {}
158
+ end
159
+
160
+ # Set the fields for the class.
161
+ #
162
+ # @example Set the fields.
163
+ # Person.fields = fields
164
+ #
165
+ # @param [ Hash ] fields The hash of fields to set.
166
+ #
167
+ # @since 2.0.0.rc.6
168
+ def fields=(fields)
169
+ @fields = fields
170
+ end
171
+
172
+ # When inheriting, we want to copy the fields from the parent class and
173
+ # set the on the child to start, mimicking the behaviour of the old
174
+ # class_inheritable_accessor that was deprecated in Rails edge.
175
+ #
176
+ # @example Inherit from this class.
177
+ # Person.inherited(Doctor)
178
+ #
179
+ # @param [ Class ] subclass The inheriting class.
180
+ #
181
+ # @since 2.0.0.rc.6
182
+ def inherited(subclass)
183
+ super
184
+ subclass.defaults, subclass.fields = defaults.dup, fields.dup
185
+ end
186
+
187
+ # Is the field with the provided name a BSON::ObjectId?
188
+ #
189
+ # @example Is the field a BSON::ObjectId?
190
+ # Person.object_id_field?(:name)
191
+ #
192
+ # @param [ String, Symbol ] name The name of the field.
193
+ #
194
+ # @return [ true, false ] If the field is a BSON::ObjectId.
195
+ #
196
+ # @since 2.2.0
197
+ def object_id_field?(name)
198
+ field_name = name.to_s
199
+ field_name = "_id" if field_name == "id"
200
+ field = fields[field_name]
201
+ field ? field.object_id_field? : false
202
+ end
203
+
204
+ # Replace a field with a new type.
205
+ #
206
+ # @example Replace the field.
207
+ # Model.replace_field("_id", String)
208
+ #
209
+ # @param [ String ] name The name of the field.
210
+ # @param [ Class ] type The new type of field.
211
+ #
212
+ # @return [ Serializable ] The new field.
213
+ #
214
+ # @since 2.1.0
215
+ def replace_field(name, type)
216
+ defaults.delete_one(name)
217
+ add_field(name, fields[name].options.merge(:type => type))
218
+ end
219
+
220
+ protected
221
+
222
+ # Define a field attribute for the +Document+.
223
+ #
224
+ # @example Set the field.
225
+ # Person.add_field(:name, :default => "Test")
226
+ #
227
+ # @param [ Symbol ] name The name of the field.
228
+ # @param [ Hash ] options The hash of options.
229
+ def add_field(name, options = {})
230
+ meth = options.delete(:as) || name
231
+ type = options[:localize] ? Fields::Serializable::Localized : options[:type]
232
+ Mappings.for(type, options[:identity]).instantiate(name, options).tap do |field|
233
+ fields[name] = field
234
+ defaults << name unless field.default_val.nil?
235
+ create_accessors(name, meth, options)
236
+ process_options(field)
237
+ define_attribute_method(name)
238
+ end
239
+ end
240
+
241
+ # Run through all custom options stored in Mongoid::Fields.options and
242
+ # execute the handler if the option is provided.
243
+ #
244
+ # @example
245
+ # Mongoid::Fields.option :custom do
246
+ # puts "called"
247
+ # end
248
+ #
249
+ # field = Mongoid::Fields.new(:test, :custom => true)
250
+ # Person.process_options(field)
251
+ # # => "called"
252
+ #
253
+ # @param [ Field ] field the field to process
254
+ def process_options(field)
255
+ field_options = field.options
256
+
257
+ Fields.options.each_pair do |option_name, handler|
258
+ if field_options.has_key?(option_name)
259
+ handler.call(self, field, field_options[option_name])
260
+ end
261
+ end
262
+ end
263
+
264
+ # Determine if the field name is allowed, if not raise an error.
265
+ #
266
+ # @example Check the field name.
267
+ # Model.check_field_name!(:collection)
268
+ #
269
+ # @param [ Symbol ] name The field name.
270
+ #
271
+ # @raise [ Errors::InvalidField ] If the name is not allowed.
272
+ #
273
+ # @since 2.1.8
274
+ def check_field_name!(name)
275
+ if Mongoid.destructive_fields.include?(name)
276
+ raise Errors::InvalidField.new(name)
277
+ end
278
+ end
279
+
280
+ # Create the field accessors.
281
+ #
282
+ # @example Generate the accessors.
283
+ # Person.create_accessors(:name, "name")
284
+ # person.name #=> returns the field
285
+ # person.name = "" #=> sets the field
286
+ # person.name? #=> Is the field present?
287
+ #
288
+ # @param [ Symbol ] name The name of the field.
289
+ # @param [ Symbol ] meth The name of the accessor.
290
+ # @param [ Hash ] options The options.
291
+ def create_accessors(name, meth, options = {})
292
+ field = fields[name]
293
+ generated_field_methods.module_eval do
294
+ if field.cast_on_read?
295
+ define_method(meth) do
296
+ field.deserialize(read_attribute(name))
297
+ end
298
+ else
299
+ define_method(meth) do
300
+ read_attribute(name).tap do |value|
301
+ if value.is_a?(Array) || value.is_a?(Hash)
302
+ unless changed_attributes.include?(name)
303
+ changed_attributes[name] = value.clone
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+ define_method("#{meth}=") do |value|
310
+ write_attribute(name, value)
311
+ end
312
+ define_method("#{meth}?") do
313
+ attr = read_attribute(name)
314
+ (options[:type] == Boolean) ? attr == true : attr.present?
315
+ end
316
+ end
317
+ end
318
+
319
+ # Include the field methods as a module, so they can be overridden.
320
+ #
321
+ # @example Include the fields.
322
+ # Person.generated_field_methods
323
+ def generated_field_methods
324
+ @generated_field_methods ||= begin
325
+ Module.new.tap do |mod|
326
+ include mod
327
+ end
328
+ end
329
+ end
330
+ end
331
+ end
332
+ end