mongoid_heroku_stable 4.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 (660) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3235 -0
  3. data/LICENSE +20 -0
  4. data/README.md +62 -0
  5. data/Rakefile +35 -0
  6. data/lib/config/locales/en.yml +452 -0
  7. data/lib/mongoid.rb +104 -0
  8. data/lib/mongoid/atomic.rb +384 -0
  9. data/lib/mongoid/atomic/modifiers.rb +317 -0
  10. data/lib/mongoid/atomic/paths.rb +3 -0
  11. data/lib/mongoid/atomic/paths/embedded.rb +28 -0
  12. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  13. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  14. data/lib/mongoid/atomic/paths/root.rb +39 -0
  15. data/lib/mongoid/attributes.rb +305 -0
  16. data/lib/mongoid/attributes/dynamic.rb +154 -0
  17. data/lib/mongoid/attributes/nested.rb +82 -0
  18. data/lib/mongoid/attributes/processing.rb +147 -0
  19. data/lib/mongoid/attributes/readonly.rb +56 -0
  20. data/lib/mongoid/changeable.rb +379 -0
  21. data/lib/mongoid/composable.rb +104 -0
  22. data/lib/mongoid/config.rb +263 -0
  23. data/lib/mongoid/config/environment.rb +44 -0
  24. data/lib/mongoid/config/options.rb +74 -0
  25. data/lib/mongoid/config/validators.rb +3 -0
  26. data/lib/mongoid/config/validators/option.rb +25 -0
  27. data/lib/mongoid/config/validators/session.rb +140 -0
  28. data/lib/mongoid/contextual.rb +54 -0
  29. data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
  30. data/lib/mongoid/contextual/aggregable/mongo.rb +145 -0
  31. data/lib/mongoid/contextual/atomic.rb +180 -0
  32. data/lib/mongoid/contextual/command.rb +61 -0
  33. data/lib/mongoid/contextual/eager.rb +158 -0
  34. data/lib/mongoid/contextual/find_and_modify.rb +69 -0
  35. data/lib/mongoid/contextual/geo_near.rb +238 -0
  36. data/lib/mongoid/contextual/map_reduce.rb +324 -0
  37. data/lib/mongoid/contextual/memory.rb +440 -0
  38. data/lib/mongoid/contextual/mongo.rb +676 -0
  39. data/lib/mongoid/contextual/queryable.rb +25 -0
  40. data/lib/mongoid/contextual/text_search.rb +180 -0
  41. data/lib/mongoid/copyable.rb +67 -0
  42. data/lib/mongoid/criteria.rb +562 -0
  43. data/lib/mongoid/criteria/findable.rb +179 -0
  44. data/lib/mongoid/criteria/inspectable.rb +25 -0
  45. data/lib/mongoid/criteria/marshalable.rb +50 -0
  46. data/lib/mongoid/criteria/modifiable.rb +189 -0
  47. data/lib/mongoid/criteria/scopable.rb +158 -0
  48. data/lib/mongoid/document.rb +361 -0
  49. data/lib/mongoid/equality.rb +66 -0
  50. data/lib/mongoid/errors.rb +41 -0
  51. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  52. data/lib/mongoid/errors/callback.rb +25 -0
  53. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  54. data/lib/mongoid/errors/document_not_found.rb +111 -0
  55. data/lib/mongoid/errors/eager_load.rb +22 -0
  56. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  57. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  58. data/lib/mongoid/errors/invalid_field.rb +64 -0
  59. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  60. data/lib/mongoid/errors/invalid_find.rb +19 -0
  61. data/lib/mongoid/errors/invalid_includes.rb +32 -0
  62. data/lib/mongoid/errors/invalid_index.rb +28 -0
  63. data/lib/mongoid/errors/invalid_options.rb +28 -0
  64. data/lib/mongoid/errors/invalid_path.rb +21 -0
  65. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  66. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  67. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  68. data/lib/mongoid/errors/invalid_time.rb +22 -0
  69. data/lib/mongoid/errors/invalid_value.rb +16 -0
  70. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  71. data/lib/mongoid/errors/mixed_relations.rb +32 -0
  72. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  73. data/lib/mongoid/errors/mongoid_error.rb +92 -0
  74. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  75. data/lib/mongoid/errors/no_default_session.rb +23 -0
  76. data/lib/mongoid/errors/no_environment.rb +19 -0
  77. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  78. data/lib/mongoid/errors/no_metadata.rb +21 -0
  79. data/lib/mongoid/errors/no_parent.rb +24 -0
  80. data/lib/mongoid/errors/no_session_config.rb +22 -0
  81. data/lib/mongoid/errors/no_session_database.rb +27 -0
  82. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  83. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  84. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  85. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  86. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  87. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  88. data/lib/mongoid/errors/unsaved_document.rb +19 -0
  89. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  90. data/lib/mongoid/errors/validations.rb +29 -0
  91. data/lib/mongoid/evolvable.rb +19 -0
  92. data/lib/mongoid/extensions.rb +35 -0
  93. data/lib/mongoid/extensions/array.rb +180 -0
  94. data/lib/mongoid/extensions/big_decimal.rb +69 -0
  95. data/lib/mongoid/extensions/boolean.rb +21 -0
  96. data/lib/mongoid/extensions/date.rb +77 -0
  97. data/lib/mongoid/extensions/date_time.rb +73 -0
  98. data/lib/mongoid/extensions/false_class.rb +38 -0
  99. data/lib/mongoid/extensions/float.rb +56 -0
  100. data/lib/mongoid/extensions/hash.rb +209 -0
  101. data/lib/mongoid/extensions/integer.rb +67 -0
  102. data/lib/mongoid/extensions/module.rb +28 -0
  103. data/lib/mongoid/extensions/nil_class.rb +33 -0
  104. data/lib/mongoid/extensions/object.rb +274 -0
  105. data/lib/mongoid/extensions/object_id.rb +54 -0
  106. data/lib/mongoid/extensions/range.rb +85 -0
  107. data/lib/mongoid/extensions/regexp.rb +27 -0
  108. data/lib/mongoid/extensions/set.rb +55 -0
  109. data/lib/mongoid/extensions/string.rb +199 -0
  110. data/lib/mongoid/extensions/symbol.rb +54 -0
  111. data/lib/mongoid/extensions/time.rb +88 -0
  112. data/lib/mongoid/extensions/time_with_zone.rb +56 -0
  113. data/lib/mongoid/extensions/true_class.rb +38 -0
  114. data/lib/mongoid/factory.rb +46 -0
  115. data/lib/mongoid/fields.rb +542 -0
  116. data/lib/mongoid/fields/foreign_key.rb +174 -0
  117. data/lib/mongoid/fields/localized.rb +73 -0
  118. data/lib/mongoid/fields/standard.rb +273 -0
  119. data/lib/mongoid/fields/validators.rb +2 -0
  120. data/lib/mongoid/fields/validators/macro.rb +92 -0
  121. data/lib/mongoid/findable.rb +133 -0
  122. data/lib/mongoid/identity_map.rb +163 -0
  123. data/lib/mongoid/indexable.rb +147 -0
  124. data/lib/mongoid/indexable/specification.rb +115 -0
  125. data/lib/mongoid/indexable/validators/options.rb +103 -0
  126. data/lib/mongoid/inspectable.rb +59 -0
  127. data/lib/mongoid/interceptable.rb +265 -0
  128. data/lib/mongoid/loggable.rb +69 -0
  129. data/lib/mongoid/matchable.rb +152 -0
  130. data/lib/mongoid/matchable/all.rb +27 -0
  131. data/lib/mongoid/matchable/and.rb +30 -0
  132. data/lib/mongoid/matchable/default.rb +72 -0
  133. data/lib/mongoid/matchable/exists.rb +23 -0
  134. data/lib/mongoid/matchable/gt.rb +21 -0
  135. data/lib/mongoid/matchable/gte.rb +21 -0
  136. data/lib/mongoid/matchable/in.rb +24 -0
  137. data/lib/mongoid/matchable/lt.rb +21 -0
  138. data/lib/mongoid/matchable/lte.rb +21 -0
  139. data/lib/mongoid/matchable/ne.rb +21 -0
  140. data/lib/mongoid/matchable/nin.rb +21 -0
  141. data/lib/mongoid/matchable/or.rb +33 -0
  142. data/lib/mongoid/matchable/size.rb +21 -0
  143. data/lib/mongoid/persistable.rb +207 -0
  144. data/lib/mongoid/persistable/creatable.rb +189 -0
  145. data/lib/mongoid/persistable/deletable.rb +149 -0
  146. data/lib/mongoid/persistable/destroyable.rb +55 -0
  147. data/lib/mongoid/persistable/incrementable.rb +36 -0
  148. data/lib/mongoid/persistable/logical.rb +38 -0
  149. data/lib/mongoid/persistable/poppable.rb +39 -0
  150. data/lib/mongoid/persistable/pullable.rb +55 -0
  151. data/lib/mongoid/persistable/pushable.rb +62 -0
  152. data/lib/mongoid/persistable/renamable.rb +35 -0
  153. data/lib/mongoid/persistable/savable.rb +52 -0
  154. data/lib/mongoid/persistable/settable.rb +33 -0
  155. data/lib/mongoid/persistable/unsettable.rb +36 -0
  156. data/lib/mongoid/persistable/updatable.rb +151 -0
  157. data/lib/mongoid/persistable/upsertable.rb +55 -0
  158. data/lib/mongoid/positional.rb +71 -0
  159. data/lib/mongoid/railtie.rb +156 -0
  160. data/lib/mongoid/railties/database.rake +97 -0
  161. data/lib/mongoid/railties/document.rb +12 -0
  162. data/lib/mongoid/relations.rb +162 -0
  163. data/lib/mongoid/relations/accessors.rb +299 -0
  164. data/lib/mongoid/relations/auto_save.rb +106 -0
  165. data/lib/mongoid/relations/binding.rb +218 -0
  166. data/lib/mongoid/relations/bindings.rb +9 -0
  167. data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
  168. data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
  169. data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
  170. data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
  171. data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
  172. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
  173. data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
  174. data/lib/mongoid/relations/builder.rb +57 -0
  175. data/lib/mongoid/relations/builders.rb +104 -0
  176. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  177. data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
  178. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  179. data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
  180. data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
  181. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  182. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  183. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
  184. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  185. data/lib/mongoid/relations/cascading.rb +56 -0
  186. data/lib/mongoid/relations/cascading/delete.rb +44 -0
  187. data/lib/mongoid/relations/cascading/destroy.rb +43 -0
  188. data/lib/mongoid/relations/cascading/nullify.rb +35 -0
  189. data/lib/mongoid/relations/cascading/restrict.rb +39 -0
  190. data/lib/mongoid/relations/constraint.rb +49 -0
  191. data/lib/mongoid/relations/conversions.rb +34 -0
  192. data/lib/mongoid/relations/counter_cache.rb +105 -0
  193. data/lib/mongoid/relations/cyclic.rb +107 -0
  194. data/lib/mongoid/relations/embedded/batchable.rb +355 -0
  195. data/lib/mongoid/relations/embedded/in.rb +231 -0
  196. data/lib/mongoid/relations/embedded/many.rb +639 -0
  197. data/lib/mongoid/relations/embedded/one.rb +223 -0
  198. data/lib/mongoid/relations/macros.rb +356 -0
  199. data/lib/mongoid/relations/many.rb +208 -0
  200. data/lib/mongoid/relations/marshalable.rb +32 -0
  201. data/lib/mongoid/relations/metadata.rb +1172 -0
  202. data/lib/mongoid/relations/nested_builder.rb +74 -0
  203. data/lib/mongoid/relations/one.rb +60 -0
  204. data/lib/mongoid/relations/options.rb +48 -0
  205. data/lib/mongoid/relations/polymorphic.rb +39 -0
  206. data/lib/mongoid/relations/proxy.rb +270 -0
  207. data/lib/mongoid/relations/referenced/in.rb +297 -0
  208. data/lib/mongoid/relations/referenced/many.rb +787 -0
  209. data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
  210. data/lib/mongoid/relations/referenced/one.rb +290 -0
  211. data/lib/mongoid/relations/reflections.rb +62 -0
  212. data/lib/mongoid/relations/synchronization.rb +169 -0
  213. data/lib/mongoid/relations/targets.rb +2 -0
  214. data/lib/mongoid/relations/targets/enumerable.rb +473 -0
  215. data/lib/mongoid/relations/touchable.rb +94 -0
  216. data/lib/mongoid/reloadable.rb +95 -0
  217. data/lib/mongoid/scopable.rb +379 -0
  218. data/lib/mongoid/selectable.rb +59 -0
  219. data/lib/mongoid/serializable.rb +170 -0
  220. data/lib/mongoid/sessions.rb +330 -0
  221. data/lib/mongoid/sessions/factory.rb +129 -0
  222. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  223. data/lib/mongoid/sessions/options.rb +141 -0
  224. data/lib/mongoid/sessions/validators.rb +2 -0
  225. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  226. data/lib/mongoid/shardable.rb +65 -0
  227. data/lib/mongoid/state.rb +97 -0
  228. data/lib/mongoid/threaded.rb +383 -0
  229. data/lib/mongoid/threaded/lifecycle.rb +164 -0
  230. data/lib/mongoid/timestamps.rb +15 -0
  231. data/lib/mongoid/timestamps/created.rb +30 -0
  232. data/lib/mongoid/timestamps/created/short.rb +19 -0
  233. data/lib/mongoid/timestamps/short.rb +10 -0
  234. data/lib/mongoid/timestamps/updated.rb +39 -0
  235. data/lib/mongoid/timestamps/updated/short.rb +19 -0
  236. data/lib/mongoid/traversable.rb +192 -0
  237. data/lib/mongoid/unit_of_work.rb +61 -0
  238. data/lib/mongoid/validatable.rb +180 -0
  239. data/lib/mongoid/validatable/associated.rb +48 -0
  240. data/lib/mongoid/validatable/format.rb +20 -0
  241. data/lib/mongoid/validatable/length.rb +20 -0
  242. data/lib/mongoid/validatable/localizable.rb +30 -0
  243. data/lib/mongoid/validatable/macros.rb +94 -0
  244. data/lib/mongoid/validatable/presence.rb +86 -0
  245. data/lib/mongoid/validatable/queryable.rb +30 -0
  246. data/lib/mongoid/validatable/uniqueness.rb +330 -0
  247. data/lib/mongoid/version.rb +4 -0
  248. data/lib/rack/mongoid.rb +2 -0
  249. data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
  250. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  251. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
  252. data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
  253. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  254. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  255. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  256. data/lib/rails/generators/mongoid_generator.rb +65 -0
  257. data/lib/rails/mongoid.rb +180 -0
  258. data/lib/support/ruby_version.rb +26 -0
  259. data/spec/app/models/account.rb +28 -0
  260. data/spec/app/models/acolyte.rb +17 -0
  261. data/spec/app/models/actor.rb +18 -0
  262. data/spec/app/models/actress.rb +2 -0
  263. data/spec/app/models/address.rb +77 -0
  264. data/spec/app/models/address_component.rb +5 -0
  265. data/spec/app/models/address_number.rb +6 -0
  266. data/spec/app/models/agency.rb +5 -0
  267. data/spec/app/models/agent.rb +12 -0
  268. data/spec/app/models/album.rb +14 -0
  269. data/spec/app/models/alert.rb +5 -0
  270. data/spec/app/models/animal.rb +25 -0
  271. data/spec/app/models/answer.rb +4 -0
  272. data/spec/app/models/appointment.rb +7 -0
  273. data/spec/app/models/article.rb +10 -0
  274. data/spec/app/models/artist.rb +66 -0
  275. data/spec/app/models/artwork.rb +4 -0
  276. data/spec/app/models/audio.rb +5 -0
  277. data/spec/app/models/augmentation.rb +11 -0
  278. data/spec/app/models/author.rb +4 -0
  279. data/spec/app/models/band.rb +26 -0
  280. data/spec/app/models/bar.rb +10 -0
  281. data/spec/app/models/basic.rb +6 -0
  282. data/spec/app/models/bed.rb +1 -0
  283. data/spec/app/models/big_palette.rb +2 -0
  284. data/spec/app/models/birthday.rb +13 -0
  285. data/spec/app/models/book.rb +13 -0
  286. data/spec/app/models/breed.rb +4 -0
  287. data/spec/app/models/browser.rb +6 -0
  288. data/spec/app/models/building.rb +5 -0
  289. data/spec/app/models/building_address.rb +5 -0
  290. data/spec/app/models/bus.rb +7 -0
  291. data/spec/app/models/business.rb +5 -0
  292. data/spec/app/models/callback_recorder.rb +25 -0
  293. data/spec/app/models/callback_test.rb +9 -0
  294. data/spec/app/models/canvas.rb +25 -0
  295. data/spec/app/models/car.rb +1 -0
  296. data/spec/app/models/cat.rb +8 -0
  297. data/spec/app/models/category.rb +8 -0
  298. data/spec/app/models/child.rb +4 -0
  299. data/spec/app/models/child_doc.rb +22 -0
  300. data/spec/app/models/church.rb +4 -0
  301. data/spec/app/models/circle.rb +3 -0
  302. data/spec/app/models/circuit.rb +4 -0
  303. data/spec/app/models/circus.rb +7 -0
  304. data/spec/app/models/code.rb +5 -0
  305. data/spec/app/models/comment.rb +16 -0
  306. data/spec/app/models/contractor.rb +5 -0
  307. data/spec/app/models/cookie.rb +6 -0
  308. data/spec/app/models/country_code.rb +8 -0
  309. data/spec/app/models/definition.rb +7 -0
  310. data/spec/app/models/description.rb +11 -0
  311. data/spec/app/models/dictionary.rb +10 -0
  312. data/spec/app/models/division.rb +10 -0
  313. data/spec/app/models/doctor.rb +12 -0
  314. data/spec/app/models/dog.rb +7 -0
  315. data/spec/app/models/dokument.rb +5 -0
  316. data/spec/app/models/dragon.rb +4 -0
  317. data/spec/app/models/driver.rb +7 -0
  318. data/spec/app/models/drug.rb +6 -0
  319. data/spec/app/models/dungeon.rb +4 -0
  320. data/spec/app/models/email.rb +6 -0
  321. data/spec/app/models/employer.rb +5 -0
  322. data/spec/app/models/entry.rb +6 -0
  323. data/spec/app/models/eraser.rb +1 -0
  324. data/spec/app/models/event.rb +22 -0
  325. data/spec/app/models/exhibition.rb +4 -0
  326. data/spec/app/models/exhibitor.rb +5 -0
  327. data/spec/app/models/eye.rb +9 -0
  328. data/spec/app/models/eye_bowl.rb +9 -0
  329. data/spec/app/models/face.rb +8 -0
  330. data/spec/app/models/favorite.rb +6 -0
  331. data/spec/app/models/filesystem.rb +5 -0
  332. data/spec/app/models/fire_hydrant.rb +6 -0
  333. data/spec/app/models/firefox.rb +4 -0
  334. data/spec/app/models/fish.rb +7 -0
  335. data/spec/app/models/folder.rb +7 -0
  336. data/spec/app/models/folder_item.rb +9 -0
  337. data/spec/app/models/fruits.rb +34 -0
  338. data/spec/app/models/game.rb +19 -0
  339. data/spec/app/models/ghost.rb +7 -0
  340. data/spec/app/models/home.rb +4 -0
  341. data/spec/app/models/house.rb +6 -0
  342. data/spec/app/models/html_writer.rb +3 -0
  343. data/spec/app/models/image.rb +22 -0
  344. data/spec/app/models/implant.rb +16 -0
  345. data/spec/app/models/item.rb +8 -0
  346. data/spec/app/models/jar.rb +7 -0
  347. data/spec/app/models/label.rb +40 -0
  348. data/spec/app/models/language.rb +5 -0
  349. data/spec/app/models/lat_lng.rb +15 -0
  350. data/spec/app/models/league.rb +11 -0
  351. data/spec/app/models/learner.rb +2 -0
  352. data/spec/app/models/line_item.rb +6 -0
  353. data/spec/app/models/location.rb +8 -0
  354. data/spec/app/models/login.rb +8 -0
  355. data/spec/app/models/manufacturer.rb +7 -0
  356. data/spec/app/models/meat.rb +4 -0
  357. data/spec/app/models/membership.rb +4 -0
  358. data/spec/app/models/mixed_drink.rb +4 -0
  359. data/spec/app/models/movie.rb +13 -0
  360. data/spec/app/models/my_hash.rb +2 -0
  361. data/spec/app/models/name.rb +23 -0
  362. data/spec/app/models/node.rb +5 -0
  363. data/spec/app/models/note.rb +12 -0
  364. data/spec/app/models/ordered_post.rb +6 -0
  365. data/spec/app/models/ordered_preference.rb +6 -0
  366. data/spec/app/models/oscar.rb +15 -0
  367. data/spec/app/models/override.rb +16 -0
  368. data/spec/app/models/ownable.rb +6 -0
  369. data/spec/app/models/owner.rb +6 -0
  370. data/spec/app/models/pack.rb +3 -0
  371. data/spec/app/models/page.rb +5 -0
  372. data/spec/app/models/page_question.rb +4 -0
  373. data/spec/app/models/palette.rb +7 -0
  374. data/spec/app/models/parent.rb +5 -0
  375. data/spec/app/models/parent_doc.rb +6 -0
  376. data/spec/app/models/passport.rb +5 -0
  377. data/spec/app/models/patient.rb +9 -0
  378. data/spec/app/models/pdf_writer.rb +3 -0
  379. data/spec/app/models/pencil.rb +1 -0
  380. data/spec/app/models/person.rb +206 -0
  381. data/spec/app/models/pet.rb +23 -0
  382. data/spec/app/models/pet_owner.rb +6 -0
  383. data/spec/app/models/phone.rb +11 -0
  384. data/spec/app/models/pizza.rb +7 -0
  385. data/spec/app/models/player.rb +35 -0
  386. data/spec/app/models/post.rb +44 -0
  387. data/spec/app/models/powerup.rb +11 -0
  388. data/spec/app/models/preference.rb +9 -0
  389. data/spec/app/models/princess.rb +8 -0
  390. data/spec/app/models/product.rb +15 -0
  391. data/spec/app/models/profile.rb +5 -0
  392. data/spec/app/models/pronunciation.rb +5 -0
  393. data/spec/app/models/purchase.rb +4 -0
  394. data/spec/app/models/question.rb +8 -0
  395. data/spec/app/models/quiz.rb +7 -0
  396. data/spec/app/models/rating.rb +8 -0
  397. data/spec/app/models/record.rb +46 -0
  398. data/spec/app/models/registry.rb +4 -0
  399. data/spec/app/models/role.rb +7 -0
  400. data/spec/app/models/root_category.rb +4 -0
  401. data/spec/app/models/sandwich.rb +4 -0
  402. data/spec/app/models/scheduler.rb +7 -0
  403. data/spec/app/models/seo.rb +7 -0
  404. data/spec/app/models/series.rb +4 -0
  405. data/spec/app/models/server.rb +13 -0
  406. data/spec/app/models/service.rb +22 -0
  407. data/spec/app/models/shape.rb +12 -0
  408. data/spec/app/models/shelf.rb +5 -0
  409. data/spec/app/models/shipping_container.rb +5 -0
  410. data/spec/app/models/shipping_pack.rb +3 -0
  411. data/spec/app/models/shop.rb +6 -0
  412. data/spec/app/models/short_agent.rb +4 -0
  413. data/spec/app/models/short_quiz.rb +5 -0
  414. data/spec/app/models/slave.rb +6 -0
  415. data/spec/app/models/song.rb +8 -0
  416. data/spec/app/models/sound.rb +5 -0
  417. data/spec/app/models/square.rb +4 -0
  418. data/spec/app/models/strategy.rb +3 -0
  419. data/spec/app/models/sub_item.rb +3 -0
  420. data/spec/app/models/subscription.rb +4 -0
  421. data/spec/app/models/survey.rb +5 -0
  422. data/spec/app/models/symptom.rb +6 -0
  423. data/spec/app/models/tag.rb +8 -0
  424. data/spec/app/models/target.rb +5 -0
  425. data/spec/app/models/template.rb +5 -0
  426. data/spec/app/models/thing.rb +9 -0
  427. data/spec/app/models/title.rb +3 -0
  428. data/spec/app/models/tool.rb +8 -0
  429. data/spec/app/models/topping.rb +5 -0
  430. data/spec/app/models/track.rb +38 -0
  431. data/spec/app/models/translation.rb +5 -0
  432. data/spec/app/models/tree.rb +9 -0
  433. data/spec/app/models/truck.rb +3 -0
  434. data/spec/app/models/user.rb +21 -0
  435. data/spec/app/models/user_account.rb +10 -0
  436. data/spec/app/models/validation_callback.rb +10 -0
  437. data/spec/app/models/vehicle.rb +11 -0
  438. data/spec/app/models/version.rb +5 -0
  439. data/spec/app/models/vet_visit.rb +5 -0
  440. data/spec/app/models/video.rb +13 -0
  441. data/spec/app/models/weapon.rb +11 -0
  442. data/spec/app/models/wiki_page.rb +14 -0
  443. data/spec/app/models/word.rb +15 -0
  444. data/spec/app/models/word_origin.rb +11 -0
  445. data/spec/app/models/writer.rb +11 -0
  446. data/spec/config/mongoid.yml +38 -0
  447. data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
  448. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
  449. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
  450. data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
  451. data/spec/mongoid/atomic/paths_spec.rb +270 -0
  452. data/spec/mongoid/atomic_spec.rb +365 -0
  453. data/spec/mongoid/attributes/nested_spec.rb +4832 -0
  454. data/spec/mongoid/attributes/readonly_spec.rb +169 -0
  455. data/spec/mongoid/attributes_spec.rb +1467 -0
  456. data/spec/mongoid/changeable_spec.rb +1507 -0
  457. data/spec/mongoid/composable_spec.rb +24 -0
  458. data/spec/mongoid/config/environment_spec.rb +83 -0
  459. data/spec/mongoid/config/options_spec.rb +56 -0
  460. data/spec/mongoid/config_spec.rb +318 -0
  461. data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
  462. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +495 -0
  463. data/spec/mongoid/contextual/atomic_spec.rb +529 -0
  464. data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
  465. data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
  466. data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
  467. data/spec/mongoid/contextual/memory_spec.rb +1236 -0
  468. data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
  469. data/spec/mongoid/contextual/text_search_spec.rb +207 -0
  470. data/spec/mongoid/copyable_spec.rb +393 -0
  471. data/spec/mongoid/criteria/findable_spec.rb +1222 -0
  472. data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
  473. data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
  474. data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
  475. data/spec/mongoid/criteria/scopable_spec.rb +391 -0
  476. data/spec/mongoid/criteria_spec.rb +3821 -0
  477. data/spec/mongoid/document_spec.rb +1205 -0
  478. data/spec/mongoid/equality_spec.rb +241 -0
  479. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
  480. data/spec/mongoid/errors/callback_spec.rb +29 -0
  481. data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
  482. data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
  483. data/spec/mongoid/errors/eager_load_spec.rb +29 -0
  484. data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
  485. data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
  486. data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
  487. data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
  488. data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
  489. data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
  490. data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
  491. data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
  492. data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
  493. data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
  494. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
  495. data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
  496. data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
  497. data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
  498. data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
  499. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
  500. data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
  501. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
  502. data/spec/mongoid/errors/no_environment_spec.rb +29 -0
  503. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
  504. data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
  505. data/spec/mongoid/errors/no_parent_spec.rb +29 -0
  506. data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
  507. data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
  508. data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
  509. data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
  510. data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
  511. data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
  512. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
  513. data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
  514. data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
  515. data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
  516. data/spec/mongoid/errors/validations_spec.rb +45 -0
  517. data/spec/mongoid/extensions/array_spec.rb +638 -0
  518. data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
  519. data/spec/mongoid/extensions/binary_spec.rb +60 -0
  520. data/spec/mongoid/extensions/boolean_spec.rb +135 -0
  521. data/spec/mongoid/extensions/date_spec.rb +235 -0
  522. data/spec/mongoid/extensions/date_time_spec.rb +155 -0
  523. data/spec/mongoid/extensions/false_class_spec.rb +42 -0
  524. data/spec/mongoid/extensions/float_spec.rb +133 -0
  525. data/spec/mongoid/extensions/hash_spec.rb +333 -0
  526. data/spec/mongoid/extensions/integer_spec.rb +136 -0
  527. data/spec/mongoid/extensions/module_spec.rb +42 -0
  528. data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
  529. data/spec/mongoid/extensions/object_id_spec.rb +946 -0
  530. data/spec/mongoid/extensions/object_spec.rb +292 -0
  531. data/spec/mongoid/extensions/range_spec.rb +154 -0
  532. data/spec/mongoid/extensions/regexp_spec.rb +47 -0
  533. data/spec/mongoid/extensions/set_spec.rb +33 -0
  534. data/spec/mongoid/extensions/string_spec.rb +357 -0
  535. data/spec/mongoid/extensions/symbol_spec.rb +76 -0
  536. data/spec/mongoid/extensions/time_spec.rb +467 -0
  537. data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
  538. data/spec/mongoid/extensions/true_class_spec.rb +42 -0
  539. data/spec/mongoid/extensions_spec.rb +15 -0
  540. data/spec/mongoid/factory_spec.rb +185 -0
  541. data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
  542. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
  543. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
  544. data/spec/mongoid/fields/localized_spec.rb +386 -0
  545. data/spec/mongoid/fields/standard_spec.rb +166 -0
  546. data/spec/mongoid/fields_spec.rb +1229 -0
  547. data/spec/mongoid/findable_spec.rb +342 -0
  548. data/spec/mongoid/identity_map_spec.rb +564 -0
  549. data/spec/mongoid/indexable/specification_spec.rb +87 -0
  550. data/spec/mongoid/indexable_spec.rb +504 -0
  551. data/spec/mongoid/inspectable_spec.rb +49 -0
  552. data/spec/mongoid/interceptable_spec.rb +1564 -0
  553. data/spec/mongoid/loggable_spec.rb +21 -0
  554. data/spec/mongoid/matchable/all_spec.rb +31 -0
  555. data/spec/mongoid/matchable/and_spec.rb +162 -0
  556. data/spec/mongoid/matchable/default_spec.rb +130 -0
  557. data/spec/mongoid/matchable/exists_spec.rb +57 -0
  558. data/spec/mongoid/matchable/gt_spec.rb +75 -0
  559. data/spec/mongoid/matchable/gte_spec.rb +74 -0
  560. data/spec/mongoid/matchable/in_spec.rb +25 -0
  561. data/spec/mongoid/matchable/lt_spec.rb +74 -0
  562. data/spec/mongoid/matchable/lte_spec.rb +74 -0
  563. data/spec/mongoid/matchable/ne_spec.rb +25 -0
  564. data/spec/mongoid/matchable/nin_spec.rb +25 -0
  565. data/spec/mongoid/matchable/or_spec.rb +106 -0
  566. data/spec/mongoid/matchable/size_spec.rb +25 -0
  567. data/spec/mongoid/matchable_spec.rb +532 -0
  568. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  569. data/spec/mongoid/persistable/deletable_spec.rb +205 -0
  570. data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
  571. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  572. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  573. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  574. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  575. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  576. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  577. data/spec/mongoid/persistable/savable_spec.rb +432 -0
  578. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  579. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  580. data/spec/mongoid/persistable/updatable_spec.rb +522 -0
  581. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  582. data/spec/mongoid/persistable_spec.rb +206 -0
  583. data/spec/mongoid/positional_spec.rb +227 -0
  584. data/spec/mongoid/railties/document_spec.rb +24 -0
  585. data/spec/mongoid/relations/accessors_spec.rb +736 -0
  586. data/spec/mongoid/relations/auto_save_spec.rb +261 -0
  587. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
  588. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
  589. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
  590. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
  591. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
  592. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
  593. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
  594. data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
  595. data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
  596. data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
  597. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
  598. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
  599. data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
  600. data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
  601. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
  602. data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
  603. data/spec/mongoid/relations/builders_spec.rb +226 -0
  604. data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
  605. data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
  606. data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
  607. data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
  608. data/spec/mongoid/relations/cascading_spec.rb +355 -0
  609. data/spec/mongoid/relations/constraint_spec.rb +74 -0
  610. data/spec/mongoid/relations/conversions_spec.rb +126 -0
  611. data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
  612. data/spec/mongoid/relations/cyclic_spec.rb +156 -0
  613. data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
  614. data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
  615. data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
  616. data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
  617. data/spec/mongoid/relations/macros_spec.rb +631 -0
  618. data/spec/mongoid/relations/metadata_spec.rb +1936 -0
  619. data/spec/mongoid/relations/options_spec.rb +35 -0
  620. data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
  621. data/spec/mongoid/relations/proxy_spec.rb +48 -0
  622. data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
  623. data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
  624. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
  625. data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
  626. data/spec/mongoid/relations/reflections_spec.rb +101 -0
  627. data/spec/mongoid/relations/synchronization_spec.rb +449 -0
  628. data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
  629. data/spec/mongoid/relations/touchable_spec.rb +296 -0
  630. data/spec/mongoid/relations_spec.rb +188 -0
  631. data/spec/mongoid/reloadable_spec.rb +305 -0
  632. data/spec/mongoid/scopable_spec.rb +926 -0
  633. data/spec/mongoid/selectable_spec.rb +134 -0
  634. data/spec/mongoid/serializable_spec.rb +862 -0
  635. data/spec/mongoid/sessions/factory_spec.rb +312 -0
  636. data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
  637. data/spec/mongoid/sessions/options_spec.rb +71 -0
  638. data/spec/mongoid/sessions_spec.rb +1078 -0
  639. data/spec/mongoid/shardable_spec.rb +61 -0
  640. data/spec/mongoid/state_spec.rb +102 -0
  641. data/spec/mongoid/threaded_spec.rb +258 -0
  642. data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
  643. data/spec/mongoid/timestamps/created_spec.rb +44 -0
  644. data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
  645. data/spec/mongoid/timestamps/updated_spec.rb +86 -0
  646. data/spec/mongoid/timestamps_spec.rb +112 -0
  647. data/spec/mongoid/traversable_spec.rb +244 -0
  648. data/spec/mongoid/unit_of_work_spec.rb +196 -0
  649. data/spec/mongoid/validatable/associated_spec.rb +183 -0
  650. data/spec/mongoid/validatable/format_spec.rb +83 -0
  651. data/spec/mongoid/validatable/length_spec.rb +119 -0
  652. data/spec/mongoid/validatable/numericality_spec.rb +30 -0
  653. data/spec/mongoid/validatable/presence_spec.rb +511 -0
  654. data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
  655. data/spec/mongoid/validatable_spec.rb +309 -0
  656. data/spec/mongoid_spec.rb +74 -0
  657. data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
  658. data/spec/rails/mongoid_spec.rb +462 -0
  659. data/spec/spec_helper.rb +103 -0
  660. metadata +1160 -0
@@ -0,0 +1,305 @@
1
+ # encoding: utf-8
2
+ require "mongoid/attributes/dynamic"
3
+ require "mongoid/attributes/nested"
4
+ require "mongoid/attributes/processing"
5
+ require "mongoid/attributes/readonly"
6
+
7
+ module Mongoid
8
+
9
+ # This module contains the logic for handling the internal attributes hash,
10
+ # and how to get and set values.
11
+ module Attributes
12
+ extend ActiveSupport::Concern
13
+ include Nested
14
+ include Processing
15
+ include Readonly
16
+
17
+ attr_reader :attributes
18
+ alias :raw_attributes :attributes
19
+
20
+ # Determine if an attribute is present.
21
+ #
22
+ # @example Is the attribute present?
23
+ # person.attribute_present?("title")
24
+ #
25
+ # @param [ String, Symbol ] name The name of the attribute.
26
+ #
27
+ # @return [ true, false ] True if present, false if not.
28
+ #
29
+ # @since 1.0.0
30
+ def attribute_present?(name)
31
+ attribute = read_attribute(name)
32
+ !attribute.blank? || attribute == false
33
+ end
34
+
35
+ # Get the attributes that have not been cast.
36
+ #
37
+ # @example Get the attributes before type cast.
38
+ # document.attributes_before_type_cast
39
+ #
40
+ # @return [ Hash ] The uncast attributes.
41
+ #
42
+ # @since 3.1.0
43
+ def attributes_before_type_cast
44
+ @attributes_before_type_cast ||= {}
45
+ end
46
+
47
+ # Does the document have the provided attribute?
48
+ #
49
+ # @example Does the document have the attribute?
50
+ # model.has_attribute?(:name)
51
+ #
52
+ # @param [ String, Symbol ] name The name of the attribute.
53
+ #
54
+ # @return [ true, false ] If the key is present in the attributes.
55
+ #
56
+ # @since 3.0.0
57
+ def has_attribute?(name)
58
+ attributes.has_key?(name.to_s)
59
+ end
60
+
61
+ # Does the document have the provided attribute before it was assigned
62
+ # and type cast?
63
+ #
64
+ # @example Does the document have the attribute before it was assigned?
65
+ # model.has_attribute_before_type_cast?(:name)
66
+ #
67
+ # @param [ String, Symbol ] name The name of the attribute.
68
+ #
69
+ # @return [ true, false ] If the key is present in the
70
+ # attributes_before_type_cast.
71
+ #
72
+ # @since 3.1.0
73
+ def has_attribute_before_type_cast?(name)
74
+ attributes_before_type_cast.has_key?(name.to_s)
75
+ end
76
+
77
+ # Read a value from the document attributes. If the value does not exist
78
+ # it will return nil.
79
+ #
80
+ # @example Read an attribute.
81
+ # person.read_attribute(:title)
82
+ #
83
+ # @example Read an attribute (alternate syntax.)
84
+ # person[:title]
85
+ #
86
+ # @param [ String, Symbol ] name The name of the attribute to get.
87
+ #
88
+ # @return [ Object ] The value of the attribute.
89
+ #
90
+ # @since 1.0.0
91
+ def read_attribute(name)
92
+ normalized = database_field_name(name.to_s)
93
+ if hash_dot_syntax?(normalized)
94
+ attributes.__nested__(normalized)
95
+ else
96
+ attributes[normalized]
97
+ end
98
+ end
99
+ alias :[] :read_attribute
100
+
101
+ # Read a value from the attributes before type cast. If the value has not
102
+ # yet been assigned then this will return the attribute's existing value
103
+ # using read_attribute.
104
+ #
105
+ # @example Read an attribute before type cast.
106
+ # person.read_attribute_before_type_cast(:price)
107
+ #
108
+ # @param [ String, Symbol ] name The name of the attribute to get.
109
+ #
110
+ # @return [ Object ] The value of the attribute before type cast, if
111
+ # available. Otherwise, the value of the attribute.
112
+ #
113
+ # @since 3.1.0
114
+ def read_attribute_before_type_cast(name)
115
+ attr = name.to_s
116
+ if attributes_before_type_cast.has_key?(attr)
117
+ attributes_before_type_cast[attr]
118
+ else
119
+ read_attribute(attr)
120
+ end
121
+ end
122
+
123
+ # Remove a value from the +Document+ attributes. If the value does not exist
124
+ # it will fail gracefully.
125
+ #
126
+ # @example Remove the attribute.
127
+ # person.remove_attribute(:title)
128
+ #
129
+ # @param [ String, Symbol ] name The name of the attribute to remove.
130
+ #
131
+ # @raise [ Errors::ReadonlyAttribute ] If the field cannot be removed due
132
+ # to being flagged as reaodnly.
133
+ #
134
+ # @since 1.0.0
135
+ def remove_attribute(name)
136
+ access = name.to_s
137
+ unless attribute_writable?(name)
138
+ raise Errors::ReadonlyAttribute.new(name, :nil)
139
+ end
140
+ _assigning do
141
+ attribute_will_change!(access)
142
+ delayed_atomic_unsets[atomic_attribute_name(access)] = [] unless new_record?
143
+ attributes.delete(access)
144
+ end
145
+ end
146
+
147
+ # Write a single attribute to the document attribute hash. This will
148
+ # also fire the before and after update callbacks, and perform any
149
+ # necessary typecasting.
150
+ #
151
+ # @example Write the attribute.
152
+ # person.write_attribute(:title, "Mr.")
153
+ #
154
+ # @example Write the attribute (alternate syntax.)
155
+ # person[:title] = "Mr."
156
+ #
157
+ # @param [ String, Symbol ] name The name of the attribute to update.
158
+ # @param [ Object ] value The value to set for the attribute.
159
+ #
160
+ # @since 1.0.0
161
+ def write_attribute(name, value)
162
+ access = database_field_name(name.to_s)
163
+ if attribute_writable?(access)
164
+ _assigning do
165
+ validate_attribute_value(access, value)
166
+ localized = fields[access].try(:localized?)
167
+ attributes_before_type_cast[name.to_s] = value
168
+ typed_value = typed_value_for(access, value)
169
+ unless attributes[access] == typed_value || attribute_changed?(access)
170
+ attribute_will_change!(access)
171
+ end
172
+ if localized
173
+ (attributes[access] ||= {}).merge!(typed_value)
174
+ else
175
+ attributes[access] = typed_value
176
+ end
177
+ typed_value
178
+ end
179
+ end
180
+ end
181
+ alias :[]= :write_attribute
182
+
183
+ # Allows you to set all the attributes for a particular mass-assignment security role
184
+ # by passing in a hash of attributes with keys matching the attribute names
185
+ # (which again matches the column names) and the role name using the :as option.
186
+ # To bypass mass-assignment security you can use the :without_protection => true option.
187
+ #
188
+ # @example Assign the attributes.
189
+ # person.assign_attributes(:title => "Mr.")
190
+ #
191
+ # @example Assign the attributes (with a role).
192
+ # person.assign_attributes({ :title => "Mr." }, :as => :admin)
193
+ #
194
+ # @param [ Hash ] attrs The new attributes to set.
195
+ #
196
+ # @since 2.2.1
197
+ def assign_attributes(attrs = nil)
198
+ _assigning do
199
+ process_attributes(attrs)
200
+ end
201
+ end
202
+
203
+ # Writes the supplied attributes hash to the document. This will only
204
+ # overwrite existing attributes if they are present in the new +Hash+, all
205
+ # others will be preserved.
206
+ #
207
+ # @example Write the attributes.
208
+ # person.write_attributes(:title => "Mr.")
209
+ #
210
+ # @example Write the attributes (alternate syntax.)
211
+ # person.attributes = { :title => "Mr." }
212
+ #
213
+ # @param [ Hash ] attrs The new attributes to set.
214
+ # @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
215
+ #
216
+ # @since 1.0.0
217
+ def write_attributes(attrs = nil)
218
+ assign_attributes(attrs)
219
+ end
220
+ alias :attributes= :write_attributes
221
+
222
+ private
223
+
224
+ # Does the string contain dot syntax for accessing hashes?
225
+ #
226
+ # @api private
227
+ #
228
+ # @example Is the string in dot syntax.
229
+ # model.hash_dot_syntax?
230
+ #
231
+ # @return [ true, false ] If the string contains a "."
232
+ #
233
+ # @since 3.0.15
234
+ def hash_dot_syntax?(string)
235
+ string =~ /\./
236
+ end
237
+
238
+ # Return the typecasted value for a field.
239
+ #
240
+ # @example Get the value typecasted.
241
+ # person.typed_value_for(:title, :sir)
242
+ #
243
+ # @param [ String, Symbol ] key The field name.
244
+ # @param [ Object ] value The uncast value.
245
+ #
246
+ # @return [ Object ] The cast value.
247
+ #
248
+ # @since 1.0.0
249
+ def typed_value_for(key, value)
250
+ fields.has_key?(key) ? fields[key].mongoize(value) : value.mongoize
251
+ end
252
+
253
+ module ClassMethods
254
+
255
+ # Alias the provided name to the original field. This will provide an
256
+ # aliased getter, setter, existance check, and all dirty attribute
257
+ # methods.
258
+ #
259
+ # @example Alias the attribute.
260
+ # class Product
261
+ # include Mongoid::Document
262
+ # field :price, :type => Float
263
+ # alias_attribute :cost, :price
264
+ # end
265
+ #
266
+ # @param [ Symbol ] name The new name.
267
+ # @param [ Symbol ] original The original name.
268
+ #
269
+ # @since 2.3.0
270
+ def alias_attribute(name, original)
271
+ class_eval <<-RUBY
272
+ alias #{name} #{original}
273
+ alias #{name}= #{original}=
274
+ alias #{name}? #{original}?
275
+ alias #{name}_change #{original}_change
276
+ alias #{name}_changed? #{original}_changed?
277
+ alias reset_#{name}! reset_#{original}!
278
+ alias #{name}_was #{original}_was
279
+ alias #{name}_will_change! #{original}_will_change!
280
+ alias #{name}_before_type_cast #{original}_before_type_cast
281
+ RUBY
282
+ end
283
+ end
284
+
285
+ private
286
+
287
+ # Validates an attribute value. This provides validation checking if
288
+ # the value is valid for given a field.
289
+ # For now, only Hash and Array fields are validated.
290
+ #
291
+ # @param [ String, Symbol ] name The name of the attribute to validate.
292
+ # @param [ Object ] value The to be validated.
293
+ #
294
+ # @since 3.0.10
295
+ def validate_attribute_value(access, value)
296
+ return unless fields[access] && value
297
+ validatable_types = [ Hash, Array ]
298
+ if validatable_types.include? fields[access].type
299
+ unless value.is_a? fields[access].type
300
+ raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
301
+ end
302
+ end
303
+ end
304
+ end
305
+ end
@@ -0,0 +1,154 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Attributes
4
+
5
+ # This module contains the behavior for dynamic attributes.
6
+ #
7
+ # @since 4.0.0
8
+ module Dynamic
9
+ extend ActiveSupport::Concern
10
+
11
+ # Override respond_to? so it responds properly for dynamic attributes.
12
+ #
13
+ # @example Does this object respond to the method?
14
+ # person.respond_to?(:title)
15
+ #
16
+ # @param [ Array ] *args The name of the method.
17
+ #
18
+ # @return [ true, false ] True if it does, false if not.
19
+ #
20
+ # @since 4.0.0
21
+ def respond_to?(name, include_private = false)
22
+ super || (
23
+ attributes &&
24
+ attributes.has_key?(name.to_s.reader)
25
+ )
26
+ end
27
+
28
+ # Define a reader method for a dynamic attribute.
29
+ #
30
+ # @api private
31
+ #
32
+ # @example Define a reader method.
33
+ # model.define_dynamic_reader(:field)
34
+ #
35
+ # @param [ String ] name The name of the field.
36
+ #
37
+ # @since 4.0.0
38
+ def define_dynamic_reader(name)
39
+ return unless name.valid_method_name?
40
+ class_eval <<-READER
41
+ def #{name}
42
+ attribute_will_change!(#{name.inspect})
43
+ read_attribute(#{name.inspect})
44
+ end
45
+ READER
46
+ end
47
+
48
+ # Define a reader method for a dynamic attribute before type cast.
49
+ #
50
+ # @api private
51
+ #
52
+ # @example Define a reader method for an attribute.
53
+ # model.define_dynamic_before_type_cast_reader(:field)
54
+ #
55
+ # @param [ String ] name The name of the field.
56
+ #
57
+ # @since 4.0.0
58
+ def define_dynamic_before_type_cast_reader(name)
59
+ class_eval <<-READER
60
+ def #{name}_before_type_cast
61
+ attribute_will_change!(#{name.inspect})
62
+ read_attribute_before_type_cast(#{name.inspect})
63
+ end
64
+ READER
65
+ end
66
+
67
+ # Define a writer method for a dynamic attribute.
68
+ #
69
+ # @api private
70
+ #
71
+ # @example Define a writer method.
72
+ # model.define_dynamic_writer(:field)
73
+ #
74
+ # @param [ String ] name The name of the field.
75
+ #
76
+ # @since 4.0.0
77
+ def define_dynamic_writer(name)
78
+ return unless name.valid_method_name?
79
+
80
+ class_eval <<-WRITER
81
+ def #{name}=(value)
82
+ write_attribute(#{name.inspect}, value)
83
+ end
84
+ WRITER
85
+ end
86
+
87
+ # If the attribute is dynamic, add a field for it with a type of object
88
+ # and set the value.
89
+ #
90
+ # @example Process the attribute.
91
+ # document.process_attribute(name, value)
92
+ #
93
+ # @param [ Symbol ] name The name of the field.
94
+ # @param [ Object ] value The value of the field.
95
+ #
96
+ # @since 4.0.0
97
+ def process_attribute(name, value)
98
+ responds = respond_to?("#{name}=")
99
+ if !responds
100
+ write_attribute(name, value)
101
+ else
102
+ send("#{name}=", value)
103
+ end
104
+ end
105
+
106
+ # Get an array of inspected dynamic fields for the document.
107
+ #
108
+ # @example Inspect the dynamic fields.
109
+ # document.inspect_dynamic_fields
110
+ #
111
+ # @return [ String ] An array of pretty printed dynamic field values.
112
+ #
113
+ # @since 4.0.0
114
+ def inspect_dynamic_fields
115
+ keys = attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
116
+ return keys.map do |name|
117
+ "#{name}: #{attributes[name].inspect}"
118
+ end
119
+ end
120
+
121
+ # Used for allowing accessor methods for dynamic attributes.
122
+ #
123
+ # @api private
124
+ #
125
+ # @example Call through method_missing.
126
+ # document.method_missing(:test)
127
+ #
128
+ # @param [ String, Symbol ] name The name of the method.
129
+ # @param [ Array ] *args The arguments to the method.
130
+ #
131
+ # @return [ Object ] The result of the method call.
132
+ #
133
+ # @since 4.0.0
134
+ def method_missing(name, *args)
135
+ attr = name.to_s
136
+ return super unless attributes.has_key?(attr.reader)
137
+ if attr.writer?
138
+ getter = attr.reader
139
+ define_dynamic_writer(getter)
140
+ write_attribute(getter, args.first)
141
+ elsif attr.before_type_cast?
142
+ define_dynamic_before_type_cast_reader(attr.reader)
143
+ attribute_will_change!(attr.reader)
144
+ read_attribute_before_type_cast(attr.reader)
145
+ else
146
+ getter = attr.reader
147
+ define_dynamic_reader(getter)
148
+ attribute_will_change!(attr.reader)
149
+ read_attribute(getter)
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end