mongoid_rails4 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 (659) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3213 -0
  3. data/LICENSE +20 -0
  4. data/README.md +62 -0
  5. data/Rakefile +35 -0
  6. data/lib/config/locales/en.yml +448 -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 +284 -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 +147 -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 +40 -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/inverse_not_found.rb +29 -0
  70. data/lib/mongoid/errors/mixed_relations.rb +32 -0
  71. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  72. data/lib/mongoid/errors/mongoid_error.rb +92 -0
  73. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  74. data/lib/mongoid/errors/no_default_session.rb +23 -0
  75. data/lib/mongoid/errors/no_environment.rb +19 -0
  76. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  77. data/lib/mongoid/errors/no_metadata.rb +21 -0
  78. data/lib/mongoid/errors/no_parent.rb +24 -0
  79. data/lib/mongoid/errors/no_session_config.rb +22 -0
  80. data/lib/mongoid/errors/no_session_database.rb +27 -0
  81. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  82. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  83. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  84. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  85. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  86. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  87. data/lib/mongoid/errors/unsaved_document.rb +19 -0
  88. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  89. data/lib/mongoid/errors/validations.rb +29 -0
  90. data/lib/mongoid/evolvable.rb +19 -0
  91. data/lib/mongoid/extensions.rb +35 -0
  92. data/lib/mongoid/extensions/array.rb +180 -0
  93. data/lib/mongoid/extensions/big_decimal.rb +69 -0
  94. data/lib/mongoid/extensions/boolean.rb +21 -0
  95. data/lib/mongoid/extensions/date.rb +77 -0
  96. data/lib/mongoid/extensions/date_time.rb +73 -0
  97. data/lib/mongoid/extensions/false_class.rb +38 -0
  98. data/lib/mongoid/extensions/float.rb +56 -0
  99. data/lib/mongoid/extensions/hash.rb +209 -0
  100. data/lib/mongoid/extensions/integer.rb +67 -0
  101. data/lib/mongoid/extensions/module.rb +28 -0
  102. data/lib/mongoid/extensions/nil_class.rb +33 -0
  103. data/lib/mongoid/extensions/object.rb +274 -0
  104. data/lib/mongoid/extensions/object_id.rb +54 -0
  105. data/lib/mongoid/extensions/range.rb +79 -0
  106. data/lib/mongoid/extensions/regexp.rb +27 -0
  107. data/lib/mongoid/extensions/set.rb +55 -0
  108. data/lib/mongoid/extensions/string.rb +199 -0
  109. data/lib/mongoid/extensions/symbol.rb +54 -0
  110. data/lib/mongoid/extensions/time.rb +88 -0
  111. data/lib/mongoid/extensions/time_with_zone.rb +56 -0
  112. data/lib/mongoid/extensions/true_class.rb +38 -0
  113. data/lib/mongoid/factory.rb +46 -0
  114. data/lib/mongoid/fields.rb +542 -0
  115. data/lib/mongoid/fields/foreign_key.rb +174 -0
  116. data/lib/mongoid/fields/localized.rb +73 -0
  117. data/lib/mongoid/fields/standard.rb +273 -0
  118. data/lib/mongoid/fields/validators.rb +2 -0
  119. data/lib/mongoid/fields/validators/macro.rb +92 -0
  120. data/lib/mongoid/findable.rb +133 -0
  121. data/lib/mongoid/identity_map.rb +163 -0
  122. data/lib/mongoid/indexable.rb +147 -0
  123. data/lib/mongoid/indexable/specification.rb +115 -0
  124. data/lib/mongoid/indexable/validators/options.rb +103 -0
  125. data/lib/mongoid/inspectable.rb +59 -0
  126. data/lib/mongoid/interceptable.rb +265 -0
  127. data/lib/mongoid/loggable.rb +69 -0
  128. data/lib/mongoid/matchable.rb +152 -0
  129. data/lib/mongoid/matchable/all.rb +27 -0
  130. data/lib/mongoid/matchable/and.rb +30 -0
  131. data/lib/mongoid/matchable/default.rb +72 -0
  132. data/lib/mongoid/matchable/exists.rb +23 -0
  133. data/lib/mongoid/matchable/gt.rb +21 -0
  134. data/lib/mongoid/matchable/gte.rb +21 -0
  135. data/lib/mongoid/matchable/in.rb +24 -0
  136. data/lib/mongoid/matchable/lt.rb +21 -0
  137. data/lib/mongoid/matchable/lte.rb +21 -0
  138. data/lib/mongoid/matchable/ne.rb +21 -0
  139. data/lib/mongoid/matchable/nin.rb +21 -0
  140. data/lib/mongoid/matchable/or.rb +33 -0
  141. data/lib/mongoid/matchable/size.rb +21 -0
  142. data/lib/mongoid/persistable.rb +207 -0
  143. data/lib/mongoid/persistable/creatable.rb +189 -0
  144. data/lib/mongoid/persistable/deletable.rb +149 -0
  145. data/lib/mongoid/persistable/destroyable.rb +55 -0
  146. data/lib/mongoid/persistable/incrementable.rb +36 -0
  147. data/lib/mongoid/persistable/logical.rb +38 -0
  148. data/lib/mongoid/persistable/poppable.rb +39 -0
  149. data/lib/mongoid/persistable/pullable.rb +55 -0
  150. data/lib/mongoid/persistable/pushable.rb +62 -0
  151. data/lib/mongoid/persistable/renamable.rb +35 -0
  152. data/lib/mongoid/persistable/savable.rb +52 -0
  153. data/lib/mongoid/persistable/settable.rb +33 -0
  154. data/lib/mongoid/persistable/unsettable.rb +36 -0
  155. data/lib/mongoid/persistable/updatable.rb +151 -0
  156. data/lib/mongoid/persistable/upsertable.rb +55 -0
  157. data/lib/mongoid/positional.rb +71 -0
  158. data/lib/mongoid/railtie.rb +156 -0
  159. data/lib/mongoid/railties/database.rake +97 -0
  160. data/lib/mongoid/railties/document.rb +12 -0
  161. data/lib/mongoid/relations.rb +162 -0
  162. data/lib/mongoid/relations/accessors.rb +299 -0
  163. data/lib/mongoid/relations/auto_save.rb +106 -0
  164. data/lib/mongoid/relations/binding.rb +218 -0
  165. data/lib/mongoid/relations/bindings.rb +9 -0
  166. data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
  167. data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
  168. data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
  169. data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
  170. data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
  171. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
  172. data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
  173. data/lib/mongoid/relations/builder.rb +57 -0
  174. data/lib/mongoid/relations/builders.rb +104 -0
  175. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  176. data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
  177. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  178. data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
  179. data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
  180. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  181. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  182. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
  183. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  184. data/lib/mongoid/relations/cascading.rb +56 -0
  185. data/lib/mongoid/relations/cascading/delete.rb +44 -0
  186. data/lib/mongoid/relations/cascading/destroy.rb +43 -0
  187. data/lib/mongoid/relations/cascading/nullify.rb +35 -0
  188. data/lib/mongoid/relations/cascading/restrict.rb +39 -0
  189. data/lib/mongoid/relations/constraint.rb +49 -0
  190. data/lib/mongoid/relations/conversions.rb +34 -0
  191. data/lib/mongoid/relations/counter_cache.rb +105 -0
  192. data/lib/mongoid/relations/cyclic.rb +107 -0
  193. data/lib/mongoid/relations/embedded/batchable.rb +355 -0
  194. data/lib/mongoid/relations/embedded/in.rb +231 -0
  195. data/lib/mongoid/relations/embedded/many.rb +639 -0
  196. data/lib/mongoid/relations/embedded/one.rb +223 -0
  197. data/lib/mongoid/relations/macros.rb +356 -0
  198. data/lib/mongoid/relations/many.rb +208 -0
  199. data/lib/mongoid/relations/marshalable.rb +32 -0
  200. data/lib/mongoid/relations/metadata.rb +1174 -0
  201. data/lib/mongoid/relations/nested_builder.rb +74 -0
  202. data/lib/mongoid/relations/one.rb +48 -0
  203. data/lib/mongoid/relations/options.rb +48 -0
  204. data/lib/mongoid/relations/polymorphic.rb +39 -0
  205. data/lib/mongoid/relations/proxy.rb +270 -0
  206. data/lib/mongoid/relations/referenced/in.rb +297 -0
  207. data/lib/mongoid/relations/referenced/many.rb +787 -0
  208. data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
  209. data/lib/mongoid/relations/referenced/one.rb +290 -0
  210. data/lib/mongoid/relations/reflections.rb +62 -0
  211. data/lib/mongoid/relations/synchronization.rb +169 -0
  212. data/lib/mongoid/relations/targets.rb +2 -0
  213. data/lib/mongoid/relations/targets/enumerable.rb +473 -0
  214. data/lib/mongoid/relations/touchable.rb +94 -0
  215. data/lib/mongoid/reloadable.rb +95 -0
  216. data/lib/mongoid/scopable.rb +379 -0
  217. data/lib/mongoid/selectable.rb +59 -0
  218. data/lib/mongoid/serializable.rb +170 -0
  219. data/lib/mongoid/sessions.rb +330 -0
  220. data/lib/mongoid/sessions/factory.rb +129 -0
  221. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  222. data/lib/mongoid/sessions/options.rb +141 -0
  223. data/lib/mongoid/sessions/validators.rb +2 -0
  224. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  225. data/lib/mongoid/shardable.rb +65 -0
  226. data/lib/mongoid/state.rb +97 -0
  227. data/lib/mongoid/threaded.rb +383 -0
  228. data/lib/mongoid/threaded/lifecycle.rb +164 -0
  229. data/lib/mongoid/timestamps.rb +15 -0
  230. data/lib/mongoid/timestamps/created.rb +30 -0
  231. data/lib/mongoid/timestamps/created/short.rb +19 -0
  232. data/lib/mongoid/timestamps/short.rb +10 -0
  233. data/lib/mongoid/timestamps/updated.rb +39 -0
  234. data/lib/mongoid/timestamps/updated/short.rb +19 -0
  235. data/lib/mongoid/traversable.rb +192 -0
  236. data/lib/mongoid/unit_of_work.rb +61 -0
  237. data/lib/mongoid/validatable.rb +180 -0
  238. data/lib/mongoid/validatable/associated.rb +48 -0
  239. data/lib/mongoid/validatable/format.rb +20 -0
  240. data/lib/mongoid/validatable/length.rb +20 -0
  241. data/lib/mongoid/validatable/localizable.rb +30 -0
  242. data/lib/mongoid/validatable/macros.rb +94 -0
  243. data/lib/mongoid/validatable/presence.rb +86 -0
  244. data/lib/mongoid/validatable/queryable.rb +30 -0
  245. data/lib/mongoid/validatable/uniqueness.rb +330 -0
  246. data/lib/mongoid/version.rb +4 -0
  247. data/lib/rack/mongoid.rb +2 -0
  248. data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
  249. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  250. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
  251. data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
  252. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  253. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  254. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  255. data/lib/rails/generators/mongoid_generator.rb +65 -0
  256. data/lib/rails/mongoid.rb +180 -0
  257. data/lib/support/ruby_version.rb +26 -0
  258. data/spec/app/models/account.rb +28 -0
  259. data/spec/app/models/acolyte.rb +17 -0
  260. data/spec/app/models/actor.rb +18 -0
  261. data/spec/app/models/actress.rb +2 -0
  262. data/spec/app/models/address.rb +77 -0
  263. data/spec/app/models/address_component.rb +5 -0
  264. data/spec/app/models/address_number.rb +6 -0
  265. data/spec/app/models/agency.rb +5 -0
  266. data/spec/app/models/agent.rb +12 -0
  267. data/spec/app/models/album.rb +14 -0
  268. data/spec/app/models/alert.rb +5 -0
  269. data/spec/app/models/animal.rb +25 -0
  270. data/spec/app/models/answer.rb +4 -0
  271. data/spec/app/models/appointment.rb +7 -0
  272. data/spec/app/models/article.rb +10 -0
  273. data/spec/app/models/artist.rb +66 -0
  274. data/spec/app/models/artwork.rb +4 -0
  275. data/spec/app/models/audio.rb +5 -0
  276. data/spec/app/models/augmentation.rb +11 -0
  277. data/spec/app/models/author.rb +4 -0
  278. data/spec/app/models/band.rb +26 -0
  279. data/spec/app/models/bar.rb +10 -0
  280. data/spec/app/models/basic.rb +6 -0
  281. data/spec/app/models/bed.rb +1 -0
  282. data/spec/app/models/big_palette.rb +2 -0
  283. data/spec/app/models/birthday.rb +13 -0
  284. data/spec/app/models/book.rb +13 -0
  285. data/spec/app/models/breed.rb +4 -0
  286. data/spec/app/models/browser.rb +6 -0
  287. data/spec/app/models/building.rb +5 -0
  288. data/spec/app/models/building_address.rb +5 -0
  289. data/spec/app/models/bus.rb +7 -0
  290. data/spec/app/models/business.rb +5 -0
  291. data/spec/app/models/callback_recorder.rb +25 -0
  292. data/spec/app/models/callback_test.rb +9 -0
  293. data/spec/app/models/canvas.rb +25 -0
  294. data/spec/app/models/car.rb +1 -0
  295. data/spec/app/models/cat.rb +8 -0
  296. data/spec/app/models/category.rb +8 -0
  297. data/spec/app/models/child.rb +4 -0
  298. data/spec/app/models/child_doc.rb +22 -0
  299. data/spec/app/models/church.rb +4 -0
  300. data/spec/app/models/circle.rb +3 -0
  301. data/spec/app/models/circuit.rb +4 -0
  302. data/spec/app/models/circus.rb +7 -0
  303. data/spec/app/models/code.rb +5 -0
  304. data/spec/app/models/comment.rb +16 -0
  305. data/spec/app/models/contractor.rb +5 -0
  306. data/spec/app/models/cookie.rb +6 -0
  307. data/spec/app/models/country_code.rb +8 -0
  308. data/spec/app/models/definition.rb +7 -0
  309. data/spec/app/models/description.rb +11 -0
  310. data/spec/app/models/dictionary.rb +10 -0
  311. data/spec/app/models/division.rb +10 -0
  312. data/spec/app/models/doctor.rb +12 -0
  313. data/spec/app/models/dog.rb +7 -0
  314. data/spec/app/models/dokument.rb +5 -0
  315. data/spec/app/models/dragon.rb +4 -0
  316. data/spec/app/models/driver.rb +7 -0
  317. data/spec/app/models/drug.rb +6 -0
  318. data/spec/app/models/dungeon.rb +4 -0
  319. data/spec/app/models/email.rb +6 -0
  320. data/spec/app/models/employer.rb +5 -0
  321. data/spec/app/models/entry.rb +6 -0
  322. data/spec/app/models/eraser.rb +1 -0
  323. data/spec/app/models/event.rb +22 -0
  324. data/spec/app/models/exhibition.rb +4 -0
  325. data/spec/app/models/exhibitor.rb +5 -0
  326. data/spec/app/models/eye.rb +9 -0
  327. data/spec/app/models/eye_bowl.rb +9 -0
  328. data/spec/app/models/face.rb +8 -0
  329. data/spec/app/models/favorite.rb +6 -0
  330. data/spec/app/models/filesystem.rb +5 -0
  331. data/spec/app/models/fire_hydrant.rb +6 -0
  332. data/spec/app/models/firefox.rb +4 -0
  333. data/spec/app/models/fish.rb +7 -0
  334. data/spec/app/models/folder.rb +7 -0
  335. data/spec/app/models/folder_item.rb +9 -0
  336. data/spec/app/models/fruits.rb +28 -0
  337. data/spec/app/models/game.rb +19 -0
  338. data/spec/app/models/ghost.rb +7 -0
  339. data/spec/app/models/home.rb +4 -0
  340. data/spec/app/models/house.rb +6 -0
  341. data/spec/app/models/html_writer.rb +3 -0
  342. data/spec/app/models/image.rb +22 -0
  343. data/spec/app/models/implant.rb +16 -0
  344. data/spec/app/models/item.rb +8 -0
  345. data/spec/app/models/jar.rb +7 -0
  346. data/spec/app/models/label.rb +40 -0
  347. data/spec/app/models/language.rb +5 -0
  348. data/spec/app/models/lat_lng.rb +15 -0
  349. data/spec/app/models/league.rb +11 -0
  350. data/spec/app/models/learner.rb +2 -0
  351. data/spec/app/models/line_item.rb +6 -0
  352. data/spec/app/models/location.rb +8 -0
  353. data/spec/app/models/login.rb +8 -0
  354. data/spec/app/models/manufacturer.rb +7 -0
  355. data/spec/app/models/meat.rb +4 -0
  356. data/spec/app/models/membership.rb +4 -0
  357. data/spec/app/models/mixed_drink.rb +4 -0
  358. data/spec/app/models/movie.rb +13 -0
  359. data/spec/app/models/my_hash.rb +2 -0
  360. data/spec/app/models/name.rb +23 -0
  361. data/spec/app/models/node.rb +5 -0
  362. data/spec/app/models/note.rb +12 -0
  363. data/spec/app/models/ordered_post.rb +6 -0
  364. data/spec/app/models/ordered_preference.rb +6 -0
  365. data/spec/app/models/oscar.rb +15 -0
  366. data/spec/app/models/override.rb +16 -0
  367. data/spec/app/models/ownable.rb +6 -0
  368. data/spec/app/models/owner.rb +6 -0
  369. data/spec/app/models/pack.rb +3 -0
  370. data/spec/app/models/page.rb +5 -0
  371. data/spec/app/models/page_question.rb +4 -0
  372. data/spec/app/models/palette.rb +7 -0
  373. data/spec/app/models/parent.rb +5 -0
  374. data/spec/app/models/parent_doc.rb +6 -0
  375. data/spec/app/models/passport.rb +5 -0
  376. data/spec/app/models/patient.rb +9 -0
  377. data/spec/app/models/pdf_writer.rb +3 -0
  378. data/spec/app/models/pencil.rb +1 -0
  379. data/spec/app/models/person.rb +205 -0
  380. data/spec/app/models/pet.rb +23 -0
  381. data/spec/app/models/pet_owner.rb +6 -0
  382. data/spec/app/models/phone.rb +11 -0
  383. data/spec/app/models/pizza.rb +7 -0
  384. data/spec/app/models/player.rb +35 -0
  385. data/spec/app/models/post.rb +44 -0
  386. data/spec/app/models/powerup.rb +11 -0
  387. data/spec/app/models/preference.rb +9 -0
  388. data/spec/app/models/princess.rb +8 -0
  389. data/spec/app/models/product.rb +15 -0
  390. data/spec/app/models/profile.rb +5 -0
  391. data/spec/app/models/pronunciation.rb +5 -0
  392. data/spec/app/models/purchase.rb +4 -0
  393. data/spec/app/models/question.rb +8 -0
  394. data/spec/app/models/quiz.rb +7 -0
  395. data/spec/app/models/rating.rb +8 -0
  396. data/spec/app/models/record.rb +46 -0
  397. data/spec/app/models/registry.rb +4 -0
  398. data/spec/app/models/role.rb +7 -0
  399. data/spec/app/models/root_category.rb +4 -0
  400. data/spec/app/models/sandwich.rb +4 -0
  401. data/spec/app/models/scheduler.rb +7 -0
  402. data/spec/app/models/seo.rb +7 -0
  403. data/spec/app/models/series.rb +4 -0
  404. data/spec/app/models/server.rb +13 -0
  405. data/spec/app/models/service.rb +22 -0
  406. data/spec/app/models/shape.rb +12 -0
  407. data/spec/app/models/shelf.rb +5 -0
  408. data/spec/app/models/shipping_container.rb +5 -0
  409. data/spec/app/models/shipping_pack.rb +3 -0
  410. data/spec/app/models/shop.rb +6 -0
  411. data/spec/app/models/short_agent.rb +4 -0
  412. data/spec/app/models/short_quiz.rb +5 -0
  413. data/spec/app/models/slave.rb +6 -0
  414. data/spec/app/models/song.rb +8 -0
  415. data/spec/app/models/sound.rb +5 -0
  416. data/spec/app/models/square.rb +4 -0
  417. data/spec/app/models/strategy.rb +3 -0
  418. data/spec/app/models/sub_item.rb +3 -0
  419. data/spec/app/models/subscription.rb +4 -0
  420. data/spec/app/models/survey.rb +5 -0
  421. data/spec/app/models/symptom.rb +6 -0
  422. data/spec/app/models/tag.rb +8 -0
  423. data/spec/app/models/target.rb +5 -0
  424. data/spec/app/models/template.rb +5 -0
  425. data/spec/app/models/thing.rb +9 -0
  426. data/spec/app/models/title.rb +3 -0
  427. data/spec/app/models/tool.rb +8 -0
  428. data/spec/app/models/topping.rb +5 -0
  429. data/spec/app/models/track.rb +38 -0
  430. data/spec/app/models/translation.rb +5 -0
  431. data/spec/app/models/tree.rb +9 -0
  432. data/spec/app/models/truck.rb +3 -0
  433. data/spec/app/models/user.rb +21 -0
  434. data/spec/app/models/user_account.rb +10 -0
  435. data/spec/app/models/validation_callback.rb +10 -0
  436. data/spec/app/models/vehicle.rb +11 -0
  437. data/spec/app/models/version.rb +5 -0
  438. data/spec/app/models/vet_visit.rb +5 -0
  439. data/spec/app/models/video.rb +13 -0
  440. data/spec/app/models/weapon.rb +11 -0
  441. data/spec/app/models/wiki_page.rb +14 -0
  442. data/spec/app/models/word.rb +15 -0
  443. data/spec/app/models/word_origin.rb +11 -0
  444. data/spec/app/models/writer.rb +11 -0
  445. data/spec/config/mongoid.yml +38 -0
  446. data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
  447. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
  448. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
  449. data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
  450. data/spec/mongoid/atomic/paths_spec.rb +270 -0
  451. data/spec/mongoid/atomic_spec.rb +365 -0
  452. data/spec/mongoid/attributes/nested_spec.rb +4832 -0
  453. data/spec/mongoid/attributes/readonly_spec.rb +169 -0
  454. data/spec/mongoid/attributes_spec.rb +1412 -0
  455. data/spec/mongoid/changeable_spec.rb +1507 -0
  456. data/spec/mongoid/composable_spec.rb +24 -0
  457. data/spec/mongoid/config/environment_spec.rb +83 -0
  458. data/spec/mongoid/config/options_spec.rb +56 -0
  459. data/spec/mongoid/config_spec.rb +318 -0
  460. data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
  461. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
  462. data/spec/mongoid/contextual/atomic_spec.rb +529 -0
  463. data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
  464. data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
  465. data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
  466. data/spec/mongoid/contextual/memory_spec.rb +1236 -0
  467. data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
  468. data/spec/mongoid/contextual/text_search_spec.rb +207 -0
  469. data/spec/mongoid/copyable_spec.rb +393 -0
  470. data/spec/mongoid/criteria/findable_spec.rb +1189 -0
  471. data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
  472. data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
  473. data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
  474. data/spec/mongoid/criteria/scopable_spec.rb +391 -0
  475. data/spec/mongoid/criteria_spec.rb +3821 -0
  476. data/spec/mongoid/document_spec.rb +1205 -0
  477. data/spec/mongoid/equality_spec.rb +241 -0
  478. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
  479. data/spec/mongoid/errors/callback_spec.rb +29 -0
  480. data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
  481. data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
  482. data/spec/mongoid/errors/eager_load_spec.rb +29 -0
  483. data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
  484. data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
  485. data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
  486. data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
  487. data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
  488. data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
  489. data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
  490. data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
  491. data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
  492. data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
  493. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
  494. data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
  495. data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
  496. data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
  497. data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
  498. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
  499. data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
  500. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
  501. data/spec/mongoid/errors/no_environment_spec.rb +29 -0
  502. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
  503. data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
  504. data/spec/mongoid/errors/no_parent_spec.rb +29 -0
  505. data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
  506. data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
  507. data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
  508. data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
  509. data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
  510. data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
  511. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
  512. data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
  513. data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
  514. data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
  515. data/spec/mongoid/errors/validations_spec.rb +45 -0
  516. data/spec/mongoid/extensions/array_spec.rb +638 -0
  517. data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
  518. data/spec/mongoid/extensions/binary_spec.rb +60 -0
  519. data/spec/mongoid/extensions/boolean_spec.rb +135 -0
  520. data/spec/mongoid/extensions/date_spec.rb +235 -0
  521. data/spec/mongoid/extensions/date_time_spec.rb +155 -0
  522. data/spec/mongoid/extensions/false_class_spec.rb +42 -0
  523. data/spec/mongoid/extensions/float_spec.rb +133 -0
  524. data/spec/mongoid/extensions/hash_spec.rb +333 -0
  525. data/spec/mongoid/extensions/integer_spec.rb +136 -0
  526. data/spec/mongoid/extensions/module_spec.rb +42 -0
  527. data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
  528. data/spec/mongoid/extensions/object_id_spec.rb +946 -0
  529. data/spec/mongoid/extensions/object_spec.rb +292 -0
  530. data/spec/mongoid/extensions/range_spec.rb +105 -0
  531. data/spec/mongoid/extensions/regexp_spec.rb +47 -0
  532. data/spec/mongoid/extensions/set_spec.rb +33 -0
  533. data/spec/mongoid/extensions/string_spec.rb +357 -0
  534. data/spec/mongoid/extensions/symbol_spec.rb +76 -0
  535. data/spec/mongoid/extensions/time_spec.rb +467 -0
  536. data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
  537. data/spec/mongoid/extensions/true_class_spec.rb +42 -0
  538. data/spec/mongoid/extensions_spec.rb +15 -0
  539. data/spec/mongoid/factory_spec.rb +185 -0
  540. data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
  541. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
  542. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
  543. data/spec/mongoid/fields/localized_spec.rb +386 -0
  544. data/spec/mongoid/fields/standard_spec.rb +166 -0
  545. data/spec/mongoid/fields_spec.rb +1229 -0
  546. data/spec/mongoid/findable_spec.rb +342 -0
  547. data/spec/mongoid/identity_map_spec.rb +564 -0
  548. data/spec/mongoid/indexable/specification_spec.rb +87 -0
  549. data/spec/mongoid/indexable_spec.rb +504 -0
  550. data/spec/mongoid/inspectable_spec.rb +49 -0
  551. data/spec/mongoid/interceptable_spec.rb +1564 -0
  552. data/spec/mongoid/loggable_spec.rb +21 -0
  553. data/spec/mongoid/matchable/all_spec.rb +31 -0
  554. data/spec/mongoid/matchable/and_spec.rb +162 -0
  555. data/spec/mongoid/matchable/default_spec.rb +130 -0
  556. data/spec/mongoid/matchable/exists_spec.rb +57 -0
  557. data/spec/mongoid/matchable/gt_spec.rb +75 -0
  558. data/spec/mongoid/matchable/gte_spec.rb +74 -0
  559. data/spec/mongoid/matchable/in_spec.rb +25 -0
  560. data/spec/mongoid/matchable/lt_spec.rb +74 -0
  561. data/spec/mongoid/matchable/lte_spec.rb +74 -0
  562. data/spec/mongoid/matchable/ne_spec.rb +25 -0
  563. data/spec/mongoid/matchable/nin_spec.rb +25 -0
  564. data/spec/mongoid/matchable/or_spec.rb +106 -0
  565. data/spec/mongoid/matchable/size_spec.rb +25 -0
  566. data/spec/mongoid/matchable_spec.rb +532 -0
  567. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  568. data/spec/mongoid/persistable/deletable_spec.rb +205 -0
  569. data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
  570. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  571. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  572. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  573. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  574. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  575. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  576. data/spec/mongoid/persistable/savable_spec.rb +432 -0
  577. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  578. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  579. data/spec/mongoid/persistable/updatable_spec.rb +522 -0
  580. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  581. data/spec/mongoid/persistable_spec.rb +206 -0
  582. data/spec/mongoid/positional_spec.rb +227 -0
  583. data/spec/mongoid/railties/document_spec.rb +24 -0
  584. data/spec/mongoid/relations/accessors_spec.rb +736 -0
  585. data/spec/mongoid/relations/auto_save_spec.rb +261 -0
  586. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
  587. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
  588. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
  589. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
  590. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
  591. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
  592. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
  593. data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
  594. data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
  595. data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
  596. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
  597. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
  598. data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
  599. data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
  600. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
  601. data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
  602. data/spec/mongoid/relations/builders_spec.rb +226 -0
  603. data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
  604. data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
  605. data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
  606. data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
  607. data/spec/mongoid/relations/cascading_spec.rb +355 -0
  608. data/spec/mongoid/relations/constraint_spec.rb +74 -0
  609. data/spec/mongoid/relations/conversions_spec.rb +126 -0
  610. data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
  611. data/spec/mongoid/relations/cyclic_spec.rb +156 -0
  612. data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
  613. data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
  614. data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
  615. data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
  616. data/spec/mongoid/relations/macros_spec.rb +613 -0
  617. data/spec/mongoid/relations/metadata_spec.rb +1917 -0
  618. data/spec/mongoid/relations/options_spec.rb +35 -0
  619. data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
  620. data/spec/mongoid/relations/proxy_spec.rb +48 -0
  621. data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
  622. data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
  623. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
  624. data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
  625. data/spec/mongoid/relations/reflections_spec.rb +101 -0
  626. data/spec/mongoid/relations/synchronization_spec.rb +449 -0
  627. data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
  628. data/spec/mongoid/relations/touchable_spec.rb +296 -0
  629. data/spec/mongoid/relations_spec.rb +188 -0
  630. data/spec/mongoid/reloadable_spec.rb +305 -0
  631. data/spec/mongoid/scopable_spec.rb +926 -0
  632. data/spec/mongoid/selectable_spec.rb +134 -0
  633. data/spec/mongoid/serializable_spec.rb +862 -0
  634. data/spec/mongoid/sessions/factory_spec.rb +312 -0
  635. data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
  636. data/spec/mongoid/sessions/options_spec.rb +71 -0
  637. data/spec/mongoid/sessions_spec.rb +1078 -0
  638. data/spec/mongoid/shardable_spec.rb +61 -0
  639. data/spec/mongoid/state_spec.rb +102 -0
  640. data/spec/mongoid/threaded_spec.rb +258 -0
  641. data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
  642. data/spec/mongoid/timestamps/created_spec.rb +44 -0
  643. data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
  644. data/spec/mongoid/timestamps/updated_spec.rb +86 -0
  645. data/spec/mongoid/timestamps_spec.rb +112 -0
  646. data/spec/mongoid/traversable_spec.rb +244 -0
  647. data/spec/mongoid/unit_of_work_spec.rb +196 -0
  648. data/spec/mongoid/validatable/associated_spec.rb +183 -0
  649. data/spec/mongoid/validatable/format_spec.rb +83 -0
  650. data/spec/mongoid/validatable/length_spec.rb +119 -0
  651. data/spec/mongoid/validatable/numericality_spec.rb +30 -0
  652. data/spec/mongoid/validatable/presence_spec.rb +511 -0
  653. data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
  654. data/spec/mongoid/validatable_spec.rb +309 -0
  655. data/spec/mongoid_spec.rb +74 -0
  656. data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
  657. data/spec/rails/mongoid_spec.rb +462 -0
  658. data/spec/spec_helper.rb +103 -0
  659. metadata +1159 -0
@@ -0,0 +1,297 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
+
6
+ # This class handles all behaviour for relations that are either
7
+ # one-to-many or one-to-one, where the foreign key is store on this side
8
+ # of the relation and the reference is to document(s) in another
9
+ # collection.
10
+ class In < Relations::One
11
+ include Evolvable
12
+
13
+ # Instantiate a new referenced_in relation.
14
+ #
15
+ # @example Create the new relation.
16
+ # Referenced::In.new(game, person, metadata)
17
+ #
18
+ # @param [ Document ] base The document this relation hangs off of.
19
+ # @param [ Document, Array<Document> ] target The target (parent) of the
20
+ # relation.
21
+ # @param [ Metadata ] metadata The relation's metadata.
22
+ def initialize(base, target, metadata)
23
+ init(base, target, metadata) do
24
+ characterize_one(target)
25
+ bind_one
26
+ end
27
+ end
28
+
29
+ # Removes the association between the base document and the target
30
+ # document by deleting the foreign key and the reference, orphaning
31
+ # the target document in the process.
32
+ #
33
+ # @example Nullify the relation.
34
+ # person.game.nullify
35
+ #
36
+ def nullify
37
+ unbind_one
38
+ target.save
39
+ end
40
+
41
+ # Substitutes the supplied target documents for the existing document
42
+ # in the relation.
43
+ #
44
+ # @example Substitute the relation.
45
+ # name.substitute(new_name)
46
+ #
47
+ # @param [ Document, Array<Document> ] new_target The replacement.
48
+ # @param [ true, false ] building Are we in build mode?
49
+ #
50
+ # @return [ In, nil ] The relation or nil.
51
+ #
52
+ # @since 2.0.0.rc.1
53
+ def substitute(replacement)
54
+ unbind_one
55
+ return nil unless replacement
56
+ self.target = replacement
57
+ bind_one
58
+ self
59
+ end
60
+
61
+ private
62
+
63
+ # Instantiate the binding associated with this relation.
64
+ #
65
+ # @example Get the binding object.
66
+ # binding([ address ])
67
+ #
68
+ # @param [ Document, Array<Document> ] new_target The replacement.
69
+ #
70
+ # @return [ Binding ] The binding object.
71
+ #
72
+ # @since 2.0.0.rc.1
73
+ def binding
74
+ Bindings::Referenced::In.new(base, target, metadata)
75
+ end
76
+
77
+ # Are we able to persist this relation?
78
+ #
79
+ # @example Can we persist the relation?
80
+ # relation.persistable?
81
+ #
82
+ # @return [ true, false ] If the relation is persistable.
83
+ #
84
+ # @since 2.1.0
85
+ def persistable?
86
+ target.persisted? && !_binding? && !_building?
87
+ end
88
+
89
+ class << self
90
+
91
+ # Return the builder that is responsible for generating the documents
92
+ # that will be used by this relation.
93
+ #
94
+ # @example Get the builder.
95
+ # Referenced::In.builder(meta, object)
96
+ #
97
+ # @param [ Document ] base The base document.
98
+ # @param [ Metadata ] meta The metadata of the relation.
99
+ # @param [ Document, Hash ] object A document or attributes to build
100
+ # with.
101
+ #
102
+ # @return [ Builder ] A new builder object.
103
+ #
104
+ # @since 2.0.0.rc.1
105
+ def builder(base, meta, object)
106
+ Builders::Referenced::In.new(base, meta, object)
107
+ end
108
+
109
+ # Get the standard criteria used for querying this relation.
110
+ #
111
+ # @example Get the criteria.
112
+ # Proxy.criteria(meta, id, Model)
113
+ #
114
+ # @param [ Metadata ] metadata The metadata.
115
+ # @param [ Object ] object The value of the foreign key.
116
+ # @param [ Class ] type The optional type.
117
+ #
118
+ # @return [ Criteria ] The criteria.
119
+ #
120
+ # @since 2.1.0
121
+ def criteria(metadata, object, type = nil)
122
+ type.where(metadata.primary_key => object)
123
+ end
124
+
125
+ # Get the criteria that is used to eager load a relation of this
126
+ # type.
127
+ #
128
+ # @example Get the eager load criteria.
129
+ # Proxy.eager_load(metadata, criteria)
130
+ #
131
+ # @param [ Metadata ] metadata The relation metadata.
132
+ # @param [ Array<Object> ] ids The ids of the target docs.
133
+ #
134
+ # @return [ Criteria ] The criteria to eager load the relation.
135
+ #
136
+ # @since 2.2.0
137
+ def eager_load(metadata, ids)
138
+ raise Errors::EagerLoad.new(metadata.name) if metadata.polymorphic?
139
+ klass, _ = metadata.klass, metadata.foreign_key
140
+ klass.any_in("_id" => ids.uniq).each do |doc|
141
+ IdentityMap.set(doc)
142
+ end
143
+ end
144
+
145
+ # Returns true if the relation is an embedded one. In this case
146
+ # always false.
147
+ #
148
+ # @example Is this relation embedded?
149
+ # Referenced::In.embedded?
150
+ #
151
+ # @return [ false ] Always false.
152
+ #
153
+ # @since 2.0.0.rc.1
154
+ def embedded?
155
+ false
156
+ end
157
+
158
+ # Get the foreign key for the provided name.
159
+ #
160
+ # @example Get the foreign key.
161
+ # Referenced::In.foreign_key(:person)
162
+ #
163
+ # @param [ Symbol ] name The name.
164
+ #
165
+ # @return [ String ] The foreign key.
166
+ #
167
+ # @since 3.0.0
168
+ def foreign_key(name)
169
+ "#{name}#{foreign_key_suffix}"
170
+ end
171
+
172
+ # Get the default value for the foreign key.
173
+ #
174
+ # @example Get the default.
175
+ # Referenced::In.foreign_key_default
176
+ #
177
+ # @return [ nil ] Always nil.
178
+ #
179
+ # @since 2.0.0.rc.1
180
+ def foreign_key_default
181
+ nil
182
+ end
183
+
184
+ # Returns the suffix of the foreign key field, either "_id" or "_ids".
185
+ #
186
+ # @example Get the suffix for the foreign key.
187
+ # Referenced::In.foreign_key_suffix
188
+ #
189
+ # @return [ String ] "_id"
190
+ #
191
+ # @since 2.0.0.rc.1
192
+ def foreign_key_suffix
193
+ "_id"
194
+ end
195
+
196
+ # Returns the macro for this relation. Used mostly as a helper in
197
+ # reflection.
198
+ #
199
+ # @example Get the macro.
200
+ # Referenced::In.macro
201
+ #
202
+ # @return [ Symbol ] :belongs_to
203
+ def macro
204
+ :belongs_to
205
+ end
206
+
207
+ # Return the nested builder that is responsible for generating the documents
208
+ # that will be used by this relation.
209
+ #
210
+ # @example Get the nested builder.
211
+ # Referenced::In.builder(attributes, options)
212
+ #
213
+ # @param [ Metadata ] metadata The relation metadata.
214
+ # @param [ Hash ] attributes The attributes to build with.
215
+ # @param [ Hash ] options The options for the builder.
216
+ #
217
+ # @option options [ true, false ] :allow_destroy Can documents be
218
+ # deleted?
219
+ # @option options [ Integer ] :limit Max number of documents to
220
+ # create at once.
221
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
222
+ # option then they are ignored.
223
+ # @option options [ true, false ] :update_only Only existing documents
224
+ # can be modified.
225
+ #
226
+ # @return [ NestedBuilder ] A newly instantiated nested builder object.
227
+ #
228
+ # @since 2.0.0.rc.1
229
+ def nested_builder(metadata, attributes, options)
230
+ Builders::NestedAttributes::One.new(metadata, attributes, options)
231
+ end
232
+
233
+ # Get the path calculator for the supplied document.
234
+ #
235
+ # @example Get the path calculator.
236
+ # Proxy.path(document)
237
+ #
238
+ # @param [ Document ] document The document to calculate on.
239
+ #
240
+ # @return [ Root ] The root atomic path calculator.
241
+ #
242
+ # @since 2.1.0
243
+ def path(document)
244
+ Mongoid::Atomic::Paths::Root.new(document)
245
+ end
246
+
247
+ # Tells the caller if this relation is one that stores the foreign
248
+ # key on its own objects.
249
+ #
250
+ # @example Does this relation store a foreign key?
251
+ # Referenced::In.stores_foreign_key?
252
+ #
253
+ # @return [ true ] Always true.
254
+ #
255
+ # @since 2.0.0.rc.1
256
+ def stores_foreign_key?
257
+ true
258
+ end
259
+
260
+ # Get the valid options allowed with this relation.
261
+ #
262
+ # @example Get the valid options.
263
+ # Relation.valid_options
264
+ #
265
+ # @return [ Array<Symbol> ] The valid options.
266
+ #
267
+ # @since 2.1.0
268
+ def valid_options
269
+ [
270
+ :autobuild,
271
+ :autosave,
272
+ :dependent,
273
+ :foreign_key,
274
+ :index,
275
+ :polymorphic,
276
+ :primary_key,
277
+ :touch
278
+ ]
279
+ end
280
+
281
+ # Get the default validation setting for the relation. Determines if
282
+ # by default a validates associated will occur.
283
+ #
284
+ # @example Get the validation default.
285
+ # Proxy.validation_default
286
+ #
287
+ # @return [ true, false ] The validation default.
288
+ #
289
+ # @since 2.1.9
290
+ def validation_default
291
+ false
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,787 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
+
6
+ # This class defines the behaviour for all relations that are a
7
+ # one-to-many between documents in different collections.
8
+ class Many < Relations::Many
9
+
10
+ delegate :count, to: :criteria
11
+ delegate :first, :in_memory, :last, :reset, :uniq, to: :target
12
+
13
+ # Appends a document or array of documents to the relation. Will set
14
+ # the parent and update the index in the process.
15
+ #
16
+ # @example Append a document.
17
+ # person.posts << post
18
+ #
19
+ # @example Push a document.
20
+ # person.posts.push(post)
21
+ #
22
+ # @example Concat with other documents.
23
+ # person.posts.concat([ post_one, post_two ])
24
+ #
25
+ # @param [ Document, Array<Document> ] *args Any number of documents.
26
+ #
27
+ # @return [ Array<Document> ] The loaded docs.
28
+ #
29
+ # @since 2.0.0.beta.1
30
+ def <<(*args)
31
+ docs = args.flatten
32
+ return concat(docs) if docs.size > 1
33
+ if doc = docs.first
34
+ append(doc)
35
+ doc.save if persistable? && !_assigning? && !doc.validated?
36
+ end
37
+ self
38
+ end
39
+ alias :push :<<
40
+
41
+ # Appends an array of documents to the relation. Performs a batch
42
+ # insert of the documents instead of persisting one at a time.
43
+ #
44
+ # @example Concat with other documents.
45
+ # person.posts.concat([ post_one, post_two ])
46
+ #
47
+ # @param [ Array<Document> ] documents The docs to add.
48
+ #
49
+ # @return [ Array<Document> ] The documents.
50
+ #
51
+ # @since 2.4.0
52
+ def concat(documents)
53
+ docs, inserts = [], []
54
+ documents.each do |doc|
55
+ next unless doc
56
+ append(doc)
57
+ save_or_delay(doc, docs, inserts) if persistable?
58
+ end
59
+ persist_delayed(docs, inserts)
60
+ self
61
+ end
62
+
63
+ # Build a new document from the attributes and append it to this
64
+ # relation without saving.
65
+ #
66
+ # @example Build a new document on the relation.
67
+ # person.posts.build(:title => "A new post")
68
+ #
69
+ # @overload build(attributes = {}, options = {}, type = nil)
70
+ # @param [ Hash ] attributes The attributes of the new document.
71
+ # @param [ Hash ] options The scoped assignment options.
72
+ # @param [ Class ] type The optional subclass to build.
73
+ #
74
+ # @overload build(attributes = {}, type = nil)
75
+ # @param [ Hash ] attributes The attributes of the new document.
76
+ # @param [ Class ] type The optional subclass to build.
77
+ #
78
+ # @return [ Document ] The new document.
79
+ #
80
+ # @since 2.0.0.beta.1
81
+ def build(attributes = {}, type = nil)
82
+ doc = Factory.build(type || klass, attributes)
83
+ append(doc)
84
+ doc.apply_post_processed_defaults
85
+ yield(doc) if block_given?
86
+ doc.run_callbacks(:build) { doc }
87
+ doc
88
+ end
89
+ alias :new :build
90
+
91
+ # Delete the document from the relation. This will set the foreign key
92
+ # on the document to nil. If the dependent options on the relation are
93
+ # :delete or :destroy the appropriate removal will occur.
94
+ #
95
+ # @example Delete the document.
96
+ # person.posts.delete(post)
97
+ #
98
+ # @param [ Document ] document The document to remove.
99
+ #
100
+ # @return [ Document ] The matching document.
101
+ #
102
+ # @since 2.1.0
103
+ def delete(document)
104
+ execute_callback :before_remove, document
105
+ target.delete(document) do |doc|
106
+ if doc
107
+ unbind_one(doc)
108
+ cascade!(doc) if !_assigning?
109
+ end
110
+ execute_callback :after_remove, doc
111
+ end
112
+ end
113
+
114
+ # Deletes all related documents from the database given the supplied
115
+ # conditions.
116
+ #
117
+ # @example Delete all documents in the relation.
118
+ # person.posts.delete_all
119
+ #
120
+ # @example Conditonally delete all documents in the relation.
121
+ # person.posts.delete_all({ :title => "Testing" })
122
+ #
123
+ # @param [ Hash ] conditions Optional conditions to delete with.
124
+ #
125
+ # @return [ Integer ] The number of documents deleted.
126
+ #
127
+ # @since 2.0.0.beta.1
128
+ def delete_all(conditions = nil)
129
+ remove_all(conditions, :delete_all)
130
+ end
131
+
132
+ # Destroys all related documents from the database given the supplied
133
+ # conditions.
134
+ #
135
+ # @example Destroy all documents in the relation.
136
+ # person.posts.destroy_all
137
+ #
138
+ # @example Conditonally destroy all documents in the relation.
139
+ # person.posts.destroy_all({ :title => "Testing" })
140
+ #
141
+ # @param [ Hash ] conditions Optional conditions to destroy with.
142
+ #
143
+ # @return [ Integer ] The number of documents destroyd.
144
+ #
145
+ # @since 2.0.0.beta.1
146
+ def destroy_all(conditions = nil)
147
+ remove_all(conditions, :destroy_all)
148
+ end
149
+
150
+ # Iterate over each document in the relation and yield to the provided
151
+ # block.
152
+ #
153
+ # @note This will load the entire relation into memory.
154
+ #
155
+ # @example Iterate over the documents.
156
+ # person.posts.each do |post|
157
+ # post.save
158
+ # end
159
+ #
160
+ # @return [ Array<Document> ] The loaded docs.
161
+ #
162
+ # @since 2.1.0
163
+ def each
164
+ if block_given?
165
+ target.each { |doc| yield(doc) }
166
+ else
167
+ to_enum
168
+ end
169
+ end
170
+
171
+ # Determine if any documents in this relation exist in the database.
172
+ #
173
+ # @example Are there persisted documents?
174
+ # person.posts.exists?
175
+ #
176
+ # @return [ true, false ] True is persisted documents exist, false if not.
177
+ def exists?
178
+ criteria.exists?
179
+ end
180
+
181
+ # Find the matchind document on the association, either based on id or
182
+ # conditions.
183
+ #
184
+ # @example Find by an id.
185
+ # person.posts.find(Moped::BSON::ObjectId.new)
186
+ #
187
+ # @example Find by multiple ids.
188
+ # person.posts.find([ Moped::BSON::ObjectId.new, Moped::BSON::ObjectId.new ])
189
+ #
190
+ # @note This will keep matching documents in memory for iteration
191
+ # later.
192
+ #
193
+ # @param [ Moped::BSON::ObjectId, Array<Moped::BSON::ObjectId> ] arg The ids.
194
+ #
195
+ # @return [ Document, Criteria ] The matching document(s).
196
+ #
197
+ # @since 2.0.0.beta.1
198
+ def find(*args)
199
+ matching = criteria.find(*args)
200
+ Array(matching).each { |doc| target.push(doc) }
201
+ matching
202
+ end
203
+
204
+ # Instantiate a new references_many relation. Will set the foreign key
205
+ # and the base on the inverse object.
206
+ #
207
+ # @example Create the new relation.
208
+ # Referenced::Many.new(base, target, metadata)
209
+ #
210
+ # @param [ Document ] base The document this relation hangs off of.
211
+ # @param [ Array<Document> ] target The target of the relation.
212
+ # @param [ Metadata ] metadata The relation's metadata.
213
+ #
214
+ # @since 2.0.0.beta.1
215
+ def initialize(base, target, metadata)
216
+ init(base, Targets::Enumerable.new(target), metadata) do
217
+ raise_mixed if klass.embedded? && !klass.cyclic?
218
+ end
219
+ end
220
+
221
+ # Removes all associations between the base document and the target
222
+ # documents by deleting the foreign keys and the references, orphaning
223
+ # the target documents in the process.
224
+ #
225
+ # @example Nullify the relation.
226
+ # person.posts.nullify
227
+ #
228
+ # @since 2.0.0.rc.1
229
+ def nullify
230
+ criteria.update_all(foreign_key => nil)
231
+ target.clear do |doc|
232
+ unbind_one(doc)
233
+ doc.changed_attributes.delete(foreign_key)
234
+ end
235
+ end
236
+ alias :nullify_all :nullify
237
+
238
+ # Clear the relation. Will delete the documents from the db if they are
239
+ # already persisted.
240
+ #
241
+ # @example Clear the relation.
242
+ # person.posts.clear
243
+ #
244
+ # @return [ Many ] The relation emptied.
245
+ #
246
+ # @since 2.0.0.beta.1
247
+ def purge
248
+ unless metadata.destructive?
249
+ nullify
250
+ else
251
+ after_remove_error = nil
252
+ criteria.delete_all
253
+ many = target.clear do |doc|
254
+ execute_callback :before_remove, doc
255
+ unbind_one(doc)
256
+ doc.destroyed = true
257
+ begin
258
+ execute_callback :after_remove, doc
259
+ rescue => e
260
+ after_remove_error = e
261
+ end
262
+ end
263
+ raise after_remove_error if after_remove_error
264
+ many
265
+ end
266
+ end
267
+ alias :clear :purge
268
+
269
+ # Substitutes the supplied target documents for the existing documents
270
+ # in the relation. If the new target is nil, perform the necessary
271
+ # deletion.
272
+ #
273
+ # @example Replace the relation.
274
+ # person.posts.substitute([ new_post ])
275
+ #
276
+ # @param [ Array<Document> ] replacement The replacement target.
277
+ #
278
+ # @return [ Many ] The relation.
279
+ #
280
+ # @since 2.0.0.rc.1
281
+ def substitute(replacement)
282
+ if replacement
283
+ new_docs, docs = replacement.compact, []
284
+ new_ids = new_docs.map { |doc| doc.id }
285
+ remove_not_in(new_ids)
286
+ new_docs.each do |doc|
287
+ docs.push(doc) if doc.send(foreign_key) != base.id
288
+ end
289
+ concat(docs)
290
+ else
291
+ purge
292
+ end
293
+ self
294
+ end
295
+
296
+ # Get a criteria for the documents without the default scoping
297
+ # applied.
298
+ #
299
+ # @example Get the unscoped criteria.
300
+ # person.posts.unscoped
301
+ #
302
+ # @return [ Criteria ] The unscoped criteria.
303
+ #
304
+ # @since 2.4.0
305
+ def unscoped
306
+ klass.unscoped.where(
307
+ foreign_key => Conversions.flag(base.id, metadata)
308
+ )
309
+ end
310
+
311
+ private
312
+
313
+ # Appends the document to the target array, updating the index on the
314
+ # document at the same time.
315
+ #
316
+ # @example Append the document to the relation.
317
+ # relation.append(document)
318
+ #
319
+ # @param [ Document ] document The document to append to the target.
320
+ #
321
+ # @since 2.0.0.rc.1
322
+ def append(document)
323
+ document.with(@persistence_options) if @persistence_options
324
+
325
+ execute_callback :before_add, document
326
+ target.push(document)
327
+ characterize_one(document)
328
+ bind_one(document)
329
+ execute_callback :after_add, document
330
+ end
331
+
332
+ # Instantiate the binding associated with this relation.
333
+ #
334
+ # @example Get the binding.
335
+ # relation.binding([ address ])
336
+ #
337
+ # @param [ Array<Document> ] new_target The new documents to bind with.
338
+ #
339
+ # @return [ Binding ] The binding.
340
+ #
341
+ # @since 2.0.0.rc.1
342
+ def binding
343
+ Bindings::Referenced::Many.new(base, target, metadata)
344
+ end
345
+
346
+ # Get the collection of the relation in question.
347
+ #
348
+ # @example Get the collection of the relation.
349
+ # relation.collection
350
+ #
351
+ # @return [ Collection ] The collection of the relation.
352
+ #
353
+ # @since 2.0.2
354
+ def collection
355
+ klass.collection
356
+ end
357
+
358
+ # Returns the criteria object for the target class with its documents set
359
+ # to target.
360
+ #
361
+ # @example Get a criteria for the relation.
362
+ # relation.criteria
363
+ #
364
+ # @return [ Criteria ] A new criteria.
365
+ #
366
+ # @since 2.0.0.beta.1
367
+ def criteria
368
+ Many.criteria(
369
+ metadata,
370
+ Conversions.flag(base.send(metadata.primary_key), metadata),
371
+ base.class
372
+ )
373
+ end
374
+
375
+ # Perform the necessary cascade operations for documents that just got
376
+ # deleted or nullified.
377
+ #
378
+ # @example Cascade the change.
379
+ # relation.cascade!(document)
380
+ #
381
+ # @param [ Document ] document The document to cascade on.
382
+ #
383
+ # @return [ true, false ] If the metadata is destructive.
384
+ #
385
+ # @since 2.1.0
386
+ def cascade!(document)
387
+ if persistable?
388
+ if metadata.destructive?
389
+ document.send(metadata.dependent)
390
+ else
391
+ document.save
392
+ end
393
+ end
394
+ end
395
+
396
+ # If the target array does not respond to the supplied method then try to
397
+ # find a named scope or criteria on the class and send the call there.
398
+ #
399
+ # If the method exists on the array, use the default proxy behavior.
400
+ #
401
+ # @param [ Symbol, String ] name The name of the method.
402
+ # @param [ Array ] args The method args
403
+ # @param [ Proc ] block Optional block to pass.
404
+ #
405
+ # @return [ Criteria, Object ] A Criteria or return value from the target.
406
+ #
407
+ # @since 2.0.0.beta.1
408
+ def method_missing(name, *args, &block)
409
+ if target.respond_to?(name)
410
+ target.send(name, *args, &block)
411
+ else
412
+ klass.send(:with_scope, criteria) do
413
+ criteria.send(name, *args, &block)
414
+ end
415
+ end
416
+ end
417
+
418
+ # Persist all the delayed batch inserts.
419
+ #
420
+ # @api private
421
+ #
422
+ # @example Persist the delayed batch inserts.
423
+ # relation.persist_delayed([ doc ])
424
+ #
425
+ # @param [ Array<Document> ] docs The delayed inserts.
426
+ # @param [ Array<Hash> ] inserts The raw insert document.
427
+ #
428
+ # @since 3.0.0
429
+ def persist_delayed(docs, inserts)
430
+ unless docs.empty?
431
+ collection.insert(inserts)
432
+ docs.each do |doc|
433
+ doc.new_record = false
434
+ doc.run_after_callbacks(:create, :save)
435
+ doc.post_persist
436
+ end
437
+ end
438
+ end
439
+
440
+ # Are we able to persist this relation?
441
+ #
442
+ # @example Can we persist the relation?
443
+ # relation.persistable?
444
+ #
445
+ # @return [ true, false ] If the relation is persistable.
446
+ #
447
+ # @since 2.1.0
448
+ def persistable?
449
+ !_binding? && (_creating? || base.persisted? && !_building?)
450
+ end
451
+
452
+ # Deletes all related documents from the database given the supplied
453
+ # conditions.
454
+ #
455
+ # @example Delete all documents in the relation.
456
+ # person.posts.delete_all
457
+ #
458
+ # @example Conditonally delete all documents in the relation.
459
+ # person.posts.delete_all({ :title => "Testing" })
460
+ #
461
+ # @param [ Hash ] conditions Optional conditions to delete with.
462
+ # @param [ Symbol ] The deletion method to call.
463
+ #
464
+ # @return [ Integer ] The number of documents deleted.
465
+ #
466
+ # @since 2.1.0
467
+ def remove_all(conditions = nil, method = :delete_all)
468
+ selector = conditions || {}
469
+ removed = klass.send(method, selector.merge!(criteria.selector))
470
+ target.delete_if do |doc|
471
+ if doc.matches?(selector)
472
+ unbind_one(doc) and true
473
+ end
474
+ end
475
+ removed
476
+ end
477
+
478
+ # Remove all the documents in the proxy that do not have the provided
479
+ # ids.
480
+ #
481
+ # @example Remove all documents without the ids.
482
+ # proxy.remove_not_in([ id ])
483
+ #
484
+ # @param [ Array<Object> ] ids The ids.
485
+ #
486
+ # @since 2.4.0
487
+ def remove_not_in(ids)
488
+ removed = criteria.not_in(_id: ids)
489
+ if metadata.destructive?
490
+ removed.delete_all
491
+ else
492
+ removed.update_all(foreign_key => nil)
493
+ end
494
+ in_memory.each do |doc|
495
+ if !ids.include?(doc.id)
496
+ unbind_one(doc)
497
+ target.delete(doc)
498
+ if metadata.destructive?
499
+ doc.destroyed = true
500
+ end
501
+ end
502
+ end
503
+ end
504
+
505
+ # Save a persisted document immediately or delay a new document for
506
+ # batch insert.
507
+ #
508
+ # @api private
509
+ #
510
+ # @example Save or delay the document.
511
+ # relation.save_or_delay(doc, [])
512
+ #
513
+ # @param [ Document ] doc The document.
514
+ # @param [ Array<Document> ] inserts The inserts.
515
+ #
516
+ # @since 3.0.0
517
+ def save_or_delay(doc, docs, inserts)
518
+ if doc.new_record? && doc.valid?(:create)
519
+ doc.run_before_callbacks(:save, :create)
520
+ docs.push(doc)
521
+ inserts.push(doc.as_document)
522
+ else
523
+ doc.save
524
+ end
525
+ end
526
+
527
+ class << self
528
+
529
+ # Return the builder that is responsible for generating the documents
530
+ # that will be used by this relation.
531
+ #
532
+ # @example Get the builder.
533
+ # Referenced::Many.builder(meta, object)
534
+ #
535
+ # @param [ Document ] base The base document.
536
+ # @param [ Metadata ] meta The metadata of the relation.
537
+ # @param [ Document, Hash ] object A document or attributes to build
538
+ # with.
539
+ #
540
+ # @return [ Builder ] A new builder object.
541
+ #
542
+ # @since 2.0.0.rc.1
543
+ def builder(base, meta, object)
544
+ Builders::Referenced::Many.new(base, meta, object || [])
545
+ end
546
+
547
+ # Get the standard criteria used for querying this relation.
548
+ #
549
+ # @example Get the criteria.
550
+ # Proxy.criteria(meta, id, Model)
551
+ #
552
+ # @param [ Metadata ] metadata The metadata.
553
+ # @param [ Object ] object The value of the foreign key.
554
+ # @param [ Class ] type The optional type.
555
+ #
556
+ # @return [ Criteria ] The criteria.
557
+ #
558
+ # @since 2.1.0
559
+ def criteria(metadata, object, type = nil)
560
+ apply_ordering(
561
+ with_inverse_field_criterion(
562
+ with_polymorphic_criterion(
563
+ metadata.klass.where(metadata.foreign_key => object),
564
+ metadata,
565
+ type
566
+ ),
567
+ metadata
568
+ ), metadata
569
+ )
570
+ end
571
+
572
+ # Eager load the relation based on the criteria.
573
+ #
574
+ # @example Eager load the criteria.
575
+ # Proxy.eager_load(metadata, criteria)
576
+ #
577
+ # @param [ Metadata ] metadata The relation metadata.
578
+ # @param [ Array<Object> ] ids The ids of the base docs.
579
+ #
580
+ # @return [ Criteria ] The criteria to eager load the relation.
581
+ #
582
+ # @since 2.2.0
583
+ def eager_load(metadata, ids)
584
+ eager_load_ids(metadata, ids) { |doc, key| IdentityMap.set_many(doc, key) }
585
+ end
586
+
587
+ # Returns true if the relation is an embedded one. In this case
588
+ # always false.
589
+ #
590
+ # @example Is this relation embedded?
591
+ # Referenced::Many.embedded?
592
+ #
593
+ # @return [ false ] Always false.
594
+ #
595
+ # @since 2.0.0.rc.1
596
+ def embedded?
597
+ false
598
+ end
599
+
600
+ # Get the foreign key for the provided name.
601
+ #
602
+ # @example Get the foreign key.
603
+ # Referenced::Many.foreign_key(:person)
604
+ #
605
+ # @param [ Symbol ] name The name.
606
+ #
607
+ # @return [ String ] The foreign key.
608
+ #
609
+ # @since 3.0.0
610
+ def foreign_key(name)
611
+ "#{name}#{foreign_key_suffix}"
612
+ end
613
+
614
+ # Get the default value for the foreign key.
615
+ #
616
+ # @example Get the default.
617
+ # Referenced::Many.foreign_key_default
618
+ #
619
+ # @return [ nil ] Always nil.
620
+ #
621
+ # @since 2.0.0.rc.1
622
+ def foreign_key_default
623
+ nil
624
+ end
625
+
626
+ # Returns the suffix of the foreign key field, either "_id" or "_ids".
627
+ #
628
+ # @example Get the suffix for the foreign key.
629
+ # Referenced::Many.foreign_key_suffix
630
+ #
631
+ # @return [ String ] "_id"
632
+ #
633
+ # @since 2.0.0.rc.1
634
+ def foreign_key_suffix
635
+ "_id"
636
+ end
637
+
638
+ # Returns the macro for this relation. Used mostly as a helper in
639
+ # reflection.
640
+ #
641
+ # @example Get the macro.
642
+ # Referenced::Many.macro
643
+ #
644
+ # @return [ Symbol ] :has_many
645
+ def macro
646
+ :has_many
647
+ end
648
+
649
+ # Return the nested builder that is responsible for generating the documents
650
+ # that will be used by this relation.
651
+ #
652
+ # @example Get the nested builder.
653
+ # Referenced::Many.builder(attributes, options)
654
+ #
655
+ # @param [ Metadata ] metadata The relation metadata.
656
+ # @param [ Hash ] attributes The attributes to build with.
657
+ # @param [ Hash ] options The options for the builder.
658
+ #
659
+ # @option options [ true, false ] :allow_destroy Can documents be
660
+ # deleted?
661
+ # @option options [ Integer ] :limit Max number of documents to
662
+ # create at once.
663
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
664
+ # option then they are ignored.
665
+ # @option options [ true, false ] :update_only Only existing documents
666
+ # can be modified.
667
+ #
668
+ # @return [ NestedBuilder ] A newly instantiated nested builder object.
669
+ #
670
+ # @since 2.0.0.rc.1
671
+ def nested_builder(metadata, attributes, options)
672
+ Builders::NestedAttributes::Many.new(metadata, attributes, options)
673
+ end
674
+
675
+ # Get the path calculator for the supplied document.
676
+ #
677
+ # @example Get the path calculator.
678
+ # Proxy.path(document)
679
+ #
680
+ # @param [ Document ] document The document to calculate on.
681
+ #
682
+ # @return [ Root ] The root atomic path calculator.
683
+ #
684
+ # @since 2.1.0
685
+ def path(document)
686
+ Mongoid::Atomic::Paths::Root.new(document)
687
+ end
688
+
689
+ # Tells the caller if this relation is one that stores the foreign
690
+ # key on its own objects.
691
+ #
692
+ # @example Does this relation store a foreign key?
693
+ # Referenced::Many.stores_foreign_key?
694
+ #
695
+ # @return [ false ] Always false.
696
+ #
697
+ # @since 2.0.0.rc.1
698
+ def stores_foreign_key?
699
+ false
700
+ end
701
+
702
+ # Get the valid options allowed with this relation.
703
+ #
704
+ # @example Get the valid options.
705
+ # Relation.valid_options
706
+ #
707
+ # @return [ Array<Symbol> ] The valid options.
708
+ #
709
+ # @since 2.1.0
710
+ def valid_options
711
+ [
712
+ :after_add,
713
+ :after_remove,
714
+ :as,
715
+ :autosave,
716
+ :before_add,
717
+ :before_remove,
718
+ :dependent,
719
+ :foreign_key,
720
+ :order,
721
+ :primary_key
722
+ ]
723
+ end
724
+
725
+ # Get the default validation setting for the relation. Determines if
726
+ # by default a validates associated will occur.
727
+ #
728
+ # @example Get the validation default.
729
+ # Proxy.validation_default
730
+ #
731
+ # @return [ true, false ] The validation default.
732
+ #
733
+ # @since 2.1.9
734
+ def validation_default
735
+ true
736
+ end
737
+
738
+ private
739
+
740
+ # Decorate the criteria with polymorphic criteria, if applicable.
741
+ #
742
+ # @api private
743
+ #
744
+ # @example Get the criteria with polymorphic criterion.
745
+ # Proxy.with_polymorphic_criterion(criteria, metadata)
746
+ #
747
+ # @param [ Criteria ] criteria The criteria to decorate.
748
+ # @param [ Metadata ] metadata The metadata.
749
+ # @param [ Class ] type The optional type.
750
+ #
751
+ # @return [ Criteria ] The criteria.
752
+ #
753
+ # @since 3.0.0
754
+ def with_polymorphic_criterion(criteria, metadata, type = nil)
755
+ if metadata.polymorphic?
756
+ criteria.where(metadata.type => type.name)
757
+ else
758
+ criteria
759
+ end
760
+ end
761
+
762
+ # Decorate the criteria with inverse field criteria, if applicable.
763
+ #
764
+ # @api private
765
+ #
766
+ # @example Get the criteria with polymorphic criterion.
767
+ # Proxy.with_inverse_field_criterion(criteria, metadata)
768
+ #
769
+ # @param [ Criteria ] criteria The criteria to decorate.
770
+ # @param [ Metadata ] metadata The metadata.
771
+ #
772
+ # @return [ Criteria ] The criteria.
773
+ #
774
+ # @since 3.0.0
775
+ def with_inverse_field_criterion(criteria, metadata)
776
+ inverse_metadata = metadata.inverse_metadata(metadata.klass)
777
+ if inverse_metadata.try(:inverse_of_field)
778
+ criteria.any_in(inverse_metadata.inverse_of_field => [ metadata.name, nil ])
779
+ else
780
+ criteria
781
+ end
782
+ end
783
+ end
784
+ end
785
+ end
786
+ end
787
+ end