activerecord 5.0.7.2 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Autosave Association
3
5
  #
@@ -27,9 +29,9 @@ module ActiveRecord
27
29
  # == Callbacks
28
30
  #
29
31
  # Association with autosave option defines several callbacks on your
30
- # model (before_save, after_create, after_update). Please note that
32
+ # model (around_save, before_save, after_create, after_update). Please note that
31
33
  # callbacks are executed in the order they were defined in
32
- # model. You should avoid modifying the association content, before
34
+ # model. You should avoid modifying the association content before
33
35
  # autosave callbacks are executed. Placing your callbacks after
34
36
  # associations is usually a good practice.
35
37
  #
@@ -89,8 +91,9 @@ module ActiveRecord
89
91
  # post.save # => saves both post and comment
90
92
  #
91
93
  # post = Post.create(title: 'ruby rocks')
92
- # post.comments.create(body: 'hello world')
93
- # post.save # => saves both post and comment
94
+ # comment = post.comments.create(body: 'hello world')
95
+ # comment.body = 'hi everyone'
96
+ # post.save # => saves post, but not comment
94
97
  #
95
98
  # When <tt>:autosave</tt> is true all children are saved, no matter whether they
96
99
  # are new records or not:
@@ -100,11 +103,10 @@ module ActiveRecord
100
103
  # end
101
104
  #
102
105
  # post = Post.create(title: 'ruby rocks')
103
- # post.comments.create(body: 'hello world')
104
- # post.comments[0].body = 'hi everyone'
106
+ # comment = post.comments.create(body: 'hello world')
107
+ # comment.body = 'hi everyone'
105
108
  # post.comments.build(body: "good morning.")
106
- # post.title += "!"
107
- # post.save # => saves both post and comments.
109
+ # post.save # => saves post and both comments.
108
110
  #
109
111
  # Destroying one of the associated models as part of the parent's save action
110
112
  # is as simple as marking it for destruction:
@@ -125,6 +127,14 @@ module ActiveRecord
125
127
  # Now it _is_ removed from the database:
126
128
  #
127
129
  # Comment.find_by(id: id).nil? # => true
130
+ #
131
+ # === Caveats
132
+ #
133
+ # Note that autosave will only trigger for already-persisted association records
134
+ # if the records themselves have been changed. This is to protect against
135
+ # <tt>SystemStackError</tt> caused by circular association validations. The one
136
+ # exception is if a custom validation context is used, in which case the validations
137
+ # will always fire on the associated records.
128
138
  module AutosaveAssociation
129
139
  extend ActiveSupport::Concern
130
140
 
@@ -140,24 +150,37 @@ module ActiveRecord
140
150
 
141
151
  included do
142
152
  Associations::Builder::Association.extensions << AssociationBuilderExtension
143
- mattr_accessor :index_nested_attribute_errors, instance_writer: false
144
- self.index_nested_attribute_errors = false
153
+ mattr_accessor :index_nested_attribute_errors, instance_writer: false, default: false
145
154
  end
146
155
 
147
156
  module ClassMethods # :nodoc:
148
157
  private
158
+ if Module.method(:method_defined?).arity == 1 # MRI 2.5 and older
159
+ using Module.new {
160
+ refine Module do
161
+ def method_defined?(method, inherit = true)
162
+ if inherit
163
+ super(method)
164
+ else
165
+ instance_methods(false).include?(method.to_sym)
166
+ end
167
+ end
168
+ end
169
+ }
170
+ end
149
171
 
150
172
  def define_non_cyclic_method(name, &block)
151
- return if method_defined?(name)
173
+ return if method_defined?(name, false)
174
+
152
175
  define_method(name) do |*args|
153
176
  result = true; @_already_called ||= {}
154
177
  # Loop prevention for validation of associations
155
178
  unless @_already_called[name]
156
179
  begin
157
- @_already_called[name]=true
180
+ @_already_called[name] = true
158
181
  result = instance_eval(&block)
159
182
  ensure
160
- @_already_called[name]=false
183
+ @_already_called[name] = false
161
184
  end
162
185
  end
163
186
 
@@ -180,7 +203,7 @@ module ActiveRecord
180
203
  save_method = :"autosave_associated_records_for_#{reflection.name}"
181
204
 
182
205
  if reflection.collection?
183
- before_save :before_save_collection_association
206
+ around_save :around_save_collection_association
184
207
 
185
208
  define_non_cyclic_method(save_method) { save_collection_association(reflection) }
186
209
  # Doesn't use after_save as that would save associations added in after_create/after_update twice
@@ -215,13 +238,7 @@ module ActiveRecord
215
238
  method = :validate_single_association
216
239
  end
217
240
 
218
- define_non_cyclic_method(validation_method) do
219
- send(method, reflection)
220
- # TODO: remove the following line as soon as the return value of
221
- # callbacks is ignored, that is, returning `false` does not
222
- # display a deprecation warning or halts the callback chain.
223
- true
224
- end
241
+ define_non_cyclic_method(validation_method) { send(method, reflection) }
225
242
  validate validation_method
226
243
  after_validation :_ensure_no_duplicate_errors
227
244
  end
@@ -267,16 +284,15 @@ module ActiveRecord
267
284
  # Returns whether or not this record has been changed in any way (including whether
268
285
  # any of its nested autosave associations are likewise changed)
269
286
  def changed_for_autosave?
270
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
287
+ new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
271
288
  end
272
289
 
273
290
  private
274
-
275
291
  # Returns the record for an association collection that should be validated
276
292
  # or saved. If +autosave+ is +false+ only new records will be returned,
277
293
  # unless the parent is/was a new record itself.
278
294
  def associated_records_to_validate_or_save(association, new_record, autosave)
279
- if new_record
295
+ if new_record || custom_validation_context?
280
296
  association && association.target
281
297
  elsif autosave
282
298
  association.target.find_all(&:changed_for_autosave?)
@@ -285,8 +301,9 @@ module ActiveRecord
285
301
  end
286
302
  end
287
303
 
288
- # go through nested autosave associations that are loaded in memory (without loading
289
- # any new ones), and return true if is changed for autosave
304
+ # Go through nested autosave associations that are loaded in memory (without loading
305
+ # any new ones), and return true if any are changed for autosave.
306
+ # Returns false if already called to prevent an infinite loop.
290
307
  def nested_records_changed_for_autosave?
291
308
  @_nested_records_changed_for_autosave_already_called ||= false
292
309
  return false if @_nested_records_changed_for_autosave_already_called
@@ -308,7 +325,7 @@ module ActiveRecord
308
325
  def validate_single_association(reflection)
309
326
  association = association_instance_get(reflection.name)
310
327
  record = association && association.reader
311
- association_valid?(reflection, record) if record
328
+ association_valid?(reflection, record) if record && (record.changed_for_autosave? || custom_validation_context?)
312
329
  end
313
330
 
314
331
  # Validate the associated records if <tt>:validate</tt> or
@@ -325,30 +342,25 @@ module ActiveRecord
325
342
  # Returns whether or not the association is valid and applies any errors to
326
343
  # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
327
344
  # enabled records if they're marked_for_destruction? or destroyed.
328
- def association_valid?(reflection, record, index=nil)
345
+ def association_valid?(reflection, record, index = nil)
329
346
  return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
330
347
 
331
- validation_context = self.validation_context unless [:create, :update].include?(self.validation_context)
348
+ context = validation_context if custom_validation_context?
332
349
 
333
- unless valid = record.valid?(validation_context)
350
+ unless valid = record.valid?(context)
334
351
  if reflection.options[:autosave]
335
352
  indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
336
353
 
337
- record.errors.each do |attribute, message|
354
+ record.errors.group_by_attribute.each { |attribute, errors|
338
355
  attribute = normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
339
- errors[attribute] << message
340
- errors[attribute].uniq!
341
- end
342
-
343
- record.errors.details.each_key do |attribute|
344
- reflection_attribute =
345
- normalize_reflection_attribute(indexed_attribute, reflection, index, attribute).to_sym
346
356
 
347
- record.errors.details[attribute].each do |error|
348
- errors.details[reflection_attribute] << error
349
- errors.details[reflection_attribute].uniq!
350
- end
351
- end
357
+ errors.each { |error|
358
+ self.errors.import(
359
+ error,
360
+ attribute: attribute
361
+ )
362
+ }
363
+ }
352
364
  else
353
365
  errors.add(reflection.name)
354
366
  end
@@ -364,11 +376,15 @@ module ActiveRecord
364
376
  end
365
377
  end
366
378
 
367
- # Is used as a before_save callback to check while saving a collection
379
+ # Is used as an around_save callback to check while saving a collection
368
380
  # association whether or not the parent was a new record before saving.
369
- def before_save_collection_association
370
- @new_record_before_save = new_record?
371
- true
381
+ def around_save_collection_association
382
+ previously_new_record_before_save = (@new_record_before_save ||= false)
383
+ @new_record_before_save = !previously_new_record_before_save && new_record?
384
+
385
+ yield
386
+ ensure
387
+ @new_record_before_save = previously_new_record_before_save
372
388
  end
373
389
 
374
390
  # Saves any new associated records, or all loaded autosave associations if
@@ -383,7 +399,14 @@ module ActiveRecord
383
399
  if association = association_instance_get(reflection.name)
384
400
  autosave = reflection.options[:autosave]
385
401
 
386
- if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
402
+ # By saving the instance variable in a local variable,
403
+ # we make the whole callback re-entrant.
404
+ new_record_before_save = @new_record_before_save
405
+
406
+ # reconstruct the scope now that we know the owner's id
407
+ association.reset_scope
408
+
409
+ if records = associated_records_to_validate_or_save(association, new_record_before_save, autosave)
387
410
  if autosave
388
411
  records_to_destroy = records.select(&:marked_for_destruction?)
389
412
  records_to_destroy.each { |record| association.destroy(record) }
@@ -395,22 +418,24 @@ module ActiveRecord
395
418
 
396
419
  saved = true
397
420
 
398
- if autosave != false && (@new_record_before_save || record.new_record?)
421
+ if autosave != false && (new_record_before_save || record.new_record?)
399
422
  if autosave
400
423
  saved = association.insert_record(record, false)
401
- else
402
- association.insert_record(record) unless reflection.nested?
424
+ elsif !reflection.nested?
425
+ association_saved = association.insert_record(record)
426
+
427
+ if reflection.validate?
428
+ errors.add(reflection.name) unless association_saved
429
+ saved = association_saved
430
+ end
403
431
  end
404
432
  elsif autosave
405
- saved = record.save(:validate => false)
433
+ saved = record.save(validate: false)
406
434
  end
407
435
 
408
- raise ActiveRecord::Rollback unless saved
436
+ raise(RecordInvalid.new(association.owner)) unless saved
409
437
  end
410
438
  end
411
-
412
- # reconstruct the scope now that we know the owner's id
413
- association.reset_scope if association.respond_to?(:reset_scope)
414
439
  end
415
440
  end
416
441
 
@@ -432,14 +457,17 @@ module ActiveRecord
432
457
  if autosave && record.marked_for_destruction?
433
458
  record.destroy
434
459
  elsif autosave != false
435
- key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
460
+ key = reflection.options[:primary_key] ? public_send(reflection.options[:primary_key]) : id
436
461
 
437
- if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
462
+ if (autosave && record.changed_for_autosave?) || record_changed?(reflection, record, key)
438
463
  unless reflection.through_reflection
439
464
  record[reflection.foreign_key] = key
465
+ if inverse_reflection = reflection.inverse_of
466
+ record.association(inverse_reflection.name).inversed_from(self)
467
+ end
440
468
  end
441
469
 
442
- saved = record.save(:validate => !autosave)
470
+ saved = record.save(validate: !autosave)
443
471
  raise ActiveRecord::Rollback if !saved && autosave
444
472
  saved
445
473
  end
@@ -450,8 +478,14 @@ module ActiveRecord
450
478
  # If the record is new or it has changed, returns true.
451
479
  def record_changed?(reflection, record, key)
452
480
  record.new_record? ||
453
- (record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key) ||
454
- record.attribute_changed?(reflection.foreign_key)
481
+ association_foreign_key_changed?(reflection, record, key) ||
482
+ record.will_save_change_to_attribute?(reflection.foreign_key)
483
+ end
484
+
485
+ def association_foreign_key_changed?(reflection, record, key)
486
+ return false if reflection.through_reflection?
487
+
488
+ record._has_attribute?(reflection.foreign_key) && record._read_attribute(reflection.foreign_key) != key
455
489
  end
456
490
 
457
491
  # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
@@ -469,10 +503,10 @@ module ActiveRecord
469
503
  self[reflection.foreign_key] = nil
470
504
  record.destroy
471
505
  elsif autosave != false
472
- saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
506
+ saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
473
507
 
474
508
  if association.updated?
475
- association_id = record.send(reflection.options[:primary_key] || :id)
509
+ association_id = record.public_send(reflection.options[:primary_key] || :id)
476
510
  self[reflection.foreign_key] = association_id
477
511
  association.loaded!
478
512
  end
@@ -482,10 +516,12 @@ module ActiveRecord
482
516
  end
483
517
  end
484
518
 
519
+ def custom_validation_context?
520
+ validation_context && [:create, :update].exclude?(validation_context)
521
+ end
522
+
485
523
  def _ensure_no_duplicate_errors
486
- errors.messages.each_key do |attribute|
487
- errors[attribute].uniq!
488
- end
524
+ errors.uniq!
489
525
  end
490
526
  end
491
527
  end
@@ -1,25 +1,16 @@
1
- require 'yaml'
2
- require 'active_support/benchmarkable'
3
- require 'active_support/dependencies'
4
- require 'active_support/descendants_tracker'
5
- require 'active_support/time'
6
- require 'active_support/core_ext/module/attribute_accessors'
7
- require 'active_support/core_ext/array/extract_options'
8
- require 'active_support/core_ext/hash/deep_merge'
9
- require 'active_support/core_ext/hash/slice'
10
- require 'active_support/core_ext/hash/transform_values'
11
- require 'active_support/core_ext/string/behavior'
12
- require 'active_support/core_ext/kernel/singleton_class'
13
- require 'active_support/core_ext/module/introspection'
14
- require 'active_support/core_ext/object/duplicable'
15
- require 'active_support/core_ext/class/subclasses'
16
- require 'active_record/attribute_decorators'
17
- require 'active_record/errors'
18
- require 'active_record/log_subscriber'
19
- require 'active_record/explain_subscriber'
20
- require 'active_record/relation/delegation'
21
- require 'active_record/attributes'
22
- require 'active_record/type_caster'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/benchmarkable"
4
+ require "active_support/dependencies"
5
+ require "active_support/descendants_tracker"
6
+ require "active_support/time"
7
+ require "active_support/core_ext/class/subclasses"
8
+ require "active_record/log_subscriber"
9
+ require "active_record/explain_subscriber"
10
+ require "active_record/relation/delegation"
11
+ require "active_record/attributes"
12
+ require "active_record/type_caster"
13
+ require "active_record/database_configurations"
23
14
 
24
15
  module ActiveRecord #:nodoc:
25
16
  # = Active Record
@@ -282,10 +273,11 @@ module ActiveRecord #:nodoc:
282
273
  extend Querying
283
274
  extend Translation
284
275
  extend DynamicMatchers
276
+ extend DelegatedType
285
277
  extend Explain
286
278
  extend Enum
287
279
  extend Delegation::DelegateCache
288
- extend CollectionCacheKey
280
+ extend Aggregations::ClassMethods
289
281
 
290
282
  include Core
291
283
  include Persistence
@@ -300,7 +292,6 @@ module ActiveRecord #:nodoc:
300
292
  include Validations
301
293
  include CounterCache
302
294
  include Attributes
303
- include AttributeDecorators
304
295
  include Locking::Optimistic
305
296
  include Locking::Pessimistic
306
297
  include AttributeMethods
@@ -310,7 +301,6 @@ module ActiveRecord #:nodoc:
310
301
  include ActiveModel::SecurePassword
311
302
  include AutosaveAssociation
312
303
  include NestedAttributes
313
- include Aggregations
314
304
  include Transactions
315
305
  include TouchLater
316
306
  include NoTouching
@@ -318,6 +308,7 @@ module ActiveRecord #:nodoc:
318
308
  include Serialization
319
309
  include Store
320
310
  include SecureToken
311
+ include SignedId
321
312
  include Suppressor
322
313
  end
323
314
 
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record \Callbacks
3
5
  #
4
6
  # \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
5
- # before or after an alteration of the object state. This can be used to make sure that associated and
7
+ # before or after a change in the object state. This can be used to make sure that associated and
6
8
  # dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
7
9
  # to massage attributes before they're validated (by overwriting +before_validation+).
8
10
  # As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
@@ -30,7 +32,7 @@ module ActiveRecord
30
32
  # is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
31
33
  # are instantiated as well.
32
34
  #
33
- # There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the
35
+ # There are nineteen callbacks in total, which give a lot of control over how to react and prepare for each state in the
34
36
  # Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
35
37
  # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
36
38
  #
@@ -62,7 +64,7 @@ module ActiveRecord
62
64
  #
63
65
  # Besides the overwritable callback methods, it's also possible to register callbacks through the
64
66
  # use of the callback macros. Their main advantage is that the macros add behavior into a callback
65
- # queue that is kept intact down through an inheritance hierarchy.
67
+ # queue that is kept intact through an inheritance hierarchy.
66
68
  #
67
69
  # class Topic < ActiveRecord::Base
68
70
  # before_destroy :destroy_author
@@ -72,22 +74,8 @@ module ActiveRecord
72
74
  # before_destroy :destroy_readers
73
75
  # end
74
76
  #
75
- # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
76
- # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
77
- # where the +before_destroy+ method is overridden:
78
- #
79
- # class Topic < ActiveRecord::Base
80
- # def before_destroy() destroy_author end
81
- # end
82
- #
83
- # class Reply < Topic
84
- # def before_destroy() destroy_readers end
85
- # end
86
- #
87
- # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
88
- # So, use the callback macros when you want to ensure that a certain callback is called for the entire
89
- # hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
90
- # to decide whether they want to call +super+ and trigger the inherited callbacks.
77
+ # When <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
78
+ # run, both +destroy_author+ and +destroy_readers+ are called.
91
79
  #
92
80
  # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
93
81
  # callbacks before specifying the associations. Otherwise, you might trigger the loading of a
@@ -95,10 +83,9 @@ module ActiveRecord
95
83
  #
96
84
  # == Types of callbacks
97
85
  #
98
- # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
99
- # inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects
100
- # are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
101
- # creating mix-ins), and inline eval methods are deprecated.
86
+ # There are three types of callbacks accepted by the callback macros: method references (symbol), callback objects,
87
+ # inline methods (using a proc). Method references and callback objects are the recommended approaches,
88
+ # inline methods using a proc are sometimes appropriate (such as for creating mix-ins).
102
89
  #
103
90
  # The method reference callbacks work by specifying a protected or private method available in the object, like this:
104
91
  #
@@ -107,7 +94,7 @@ module ActiveRecord
107
94
  #
108
95
  # private
109
96
  # def delete_parents
110
- # self.class.delete_all "parent_id = #{id}"
97
+ # self.class.delete_by(parent_id: id)
111
98
  # end
112
99
  # end
113
100
  #
@@ -140,7 +127,7 @@ module ActiveRecord
140
127
  # end
141
128
  # end
142
129
  #
143
- # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
130
+ # So you specify the object you want to be messaged on a given callback. When that callback is triggered, the object has
144
131
  # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
145
132
  # initialization data such as the name of the attribute to work with:
146
133
  #
@@ -191,8 +178,8 @@ module ActiveRecord
191
178
  #
192
179
  # == Ordering callbacks
193
180
  #
194
- # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
195
- # callback (+log_children+ in this case) should be executed before the children get destroyed by the
181
+ # Sometimes application code requires that callbacks execute in a specific order. For example, a +before_destroy+
182
+ # callback (+log_children+ in this case) should be executed before records in the +children+ association are destroyed by the
196
183
  # <tt>dependent: :destroy</tt> option.
197
184
  #
198
185
  # Let's look at the code below:
@@ -208,8 +195,8 @@ module ActiveRecord
208
195
  # end
209
196
  # end
210
197
  #
211
- # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
212
- # because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first.
198
+ # In this case, the problem is that when the +before_destroy+ callback is executed, records in the +children+ association no
199
+ # longer exist because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback was executed first.
213
200
  # You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
214
201
  #
215
202
  # class Topic < ActiveRecord::Base
@@ -223,16 +210,65 @@ module ActiveRecord
223
210
  # end
224
211
  # end
225
212
  #
226
- # This way, the +before_destroy+ gets executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
213
+ # This way, the +before_destroy+ is executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
214
+ #
215
+ # Also, there are cases when you want several callbacks of the same type to
216
+ # be executed in order.
217
+ #
218
+ # For example:
219
+ #
220
+ # class Topic < ActiveRecord::Base
221
+ # has_many :children
222
+ #
223
+ # after_save :log_children
224
+ # after_save :do_something_else
225
+ #
226
+ # private
227
+ #
228
+ # def log_children
229
+ # # Child processing
230
+ # end
231
+ #
232
+ # def do_something_else
233
+ # # Something else
234
+ # end
235
+ # end
236
+ #
237
+ # In this case the +log_children+ is executed before +do_something_else+.
238
+ # The same applies to all non-transactional callbacks.
239
+ #
240
+ # As seen below, in case there are multiple transactional callbacks the order
241
+ # is reversed.
242
+ #
243
+ # For example:
244
+ #
245
+ # class Topic < ActiveRecord::Base
246
+ # has_many :children
247
+ #
248
+ # after_commit :log_children
249
+ # after_commit :do_something_else
250
+ #
251
+ # private
252
+ #
253
+ # def log_children
254
+ # # Child processing
255
+ # end
256
+ #
257
+ # def do_something_else
258
+ # # Something else
259
+ # end
260
+ # end
261
+ #
262
+ # In this case the +do_something_else+ is executed before +log_children+.
227
263
  #
228
264
  # == \Transactions
229
265
  #
230
266
  # The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
231
267
  # or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks.
232
- # If everything goes fine a COMMIT is executed once the chain has been completed.
268
+ # If everything goes fine a +COMMIT+ is executed once the chain has been completed.
233
269
  #
234
- # If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
235
- # can also trigger a ROLLBACK raising an exception in any of the callbacks,
270
+ # If a <tt>before_*</tt> callback cancels the action a +ROLLBACK+ is issued. You
271
+ # can also trigger a +ROLLBACK+ raising an exception in any of the callbacks,
236
272
  # including <tt>after_*</tt> hooks. Note, however, that in that case the client
237
273
  # needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
238
274
  # instead of quietly returning +false+.
@@ -243,17 +279,17 @@ module ActiveRecord
243
279
  # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
244
280
  # defines what part of the chain the callback runs in.
245
281
  #
246
- # To find all callbacks in the before_save callback chain:
282
+ # To find all callbacks in the +before_save+ callback chain:
247
283
  #
248
284
  # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
249
285
  #
250
- # Returns an array of callback objects that form the before_save chain.
286
+ # Returns an array of callback objects that form the +before_save+ chain.
251
287
  #
252
288
  # To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
253
289
  #
254
290
  # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
255
291
  #
256
- # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
292
+ # Returns true or false depending on whether the proc is contained in the +before_save+ callback chain on a Topic model.
257
293
  #
258
294
  module Callbacks
259
295
  extend ActiveSupport::Concern
@@ -265,14 +301,134 @@ module ActiveRecord
265
301
  :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
266
302
  ]
267
303
 
268
- module ClassMethods # :nodoc:
304
+ module ClassMethods
269
305
  include ActiveModel::Callbacks
306
+
307
+ ##
308
+ # :method: after_initialize
309
+ #
310
+ # :call-seq: after_initialize(*args, &block)
311
+ #
312
+ # Registers a callback to be called after a record is instantiated. See
313
+ # ActiveRecord::Callbacks for more information.
314
+
315
+ ##
316
+ # :method: after_find
317
+ #
318
+ # :call-seq: after_find(*args, &block)
319
+ #
320
+ # Registers a callback to be called after a record is instantiated
321
+ # via a finder. See ActiveRecord::Callbacks for more information.
322
+
323
+ ##
324
+ # :method: after_touch
325
+ #
326
+ # :call-seq: after_touch(*args, &block)
327
+ #
328
+ # Registers a callback to be called after a record is touched. See
329
+ # ActiveRecord::Callbacks for more information.
330
+
331
+ ##
332
+ # :method: before_save
333
+ #
334
+ # :call-seq: before_save(*args, &block)
335
+ #
336
+ # Registers a callback to be called before a record is saved. See
337
+ # ActiveRecord::Callbacks for more information.
338
+
339
+ ##
340
+ # :method: around_save
341
+ #
342
+ # :call-seq: around_save(*args, &block)
343
+ #
344
+ # Registers a callback to be called around the save of a record. See
345
+ # ActiveRecord::Callbacks for more information.
346
+
347
+ ##
348
+ # :method: after_save
349
+ #
350
+ # :call-seq: after_save(*args, &block)
351
+ #
352
+ # Registers a callback to be called after a record is saved. See
353
+ # ActiveRecord::Callbacks for more information.
354
+
355
+ ##
356
+ # :method: before_create
357
+ #
358
+ # :call-seq: before_create(*args, &block)
359
+ #
360
+ # Registers a callback to be called before a record is created. See
361
+ # ActiveRecord::Callbacks for more information.
362
+
363
+ ##
364
+ # :method: around_create
365
+ #
366
+ # :call-seq: around_create(*args, &block)
367
+ #
368
+ # Registers a callback to be called around the creation of a record. See
369
+ # ActiveRecord::Callbacks for more information.
370
+
371
+ ##
372
+ # :method: after_create
373
+ #
374
+ # :call-seq: after_create(*args, &block)
375
+ #
376
+ # Registers a callback to be called after a record is created. See
377
+ # ActiveRecord::Callbacks for more information.
378
+
379
+ ##
380
+ # :method: before_update
381
+ #
382
+ # :call-seq: before_update(*args, &block)
383
+ #
384
+ # Registers a callback to be called before a record is updated. See
385
+ # ActiveRecord::Callbacks for more information.
386
+
387
+ ##
388
+ # :method: around_update
389
+ #
390
+ # :call-seq: around_update(*args, &block)
391
+ #
392
+ # Registers a callback to be called around the update of a record. See
393
+ # ActiveRecord::Callbacks for more information.
394
+
395
+ ##
396
+ # :method: after_update
397
+ #
398
+ # :call-seq: after_update(*args, &block)
399
+ #
400
+ # Registers a callback to be called after a record is updated. See
401
+ # ActiveRecord::Callbacks for more information.
402
+
403
+ ##
404
+ # :method: before_destroy
405
+ #
406
+ # :call-seq: before_destroy(*args, &block)
407
+ #
408
+ # Registers a callback to be called before a record is destroyed. See
409
+ # ActiveRecord::Callbacks for more information.
410
+
411
+ ##
412
+ # :method: around_destroy
413
+ #
414
+ # :call-seq: around_destroy(*args, &block)
415
+ #
416
+ # Registers a callback to be called around the destruction of a record.
417
+ # See ActiveRecord::Callbacks for more information.
418
+
419
+ ##
420
+ # :method: after_destroy
421
+ #
422
+ # :call-seq: after_destroy(*args, &block)
423
+ #
424
+ # Registers a callback to be called after a record is destroyed. See
425
+ # ActiveRecord::Callbacks for more information.
270
426
  end
271
427
 
272
428
  included do
273
429
  include ActiveModel::Validations::Callbacks
274
430
 
275
- define_model_callbacks :initialize, :find, :touch, :only => :after
431
+ define_model_callbacks :initialize, :find, :touch, only: :after
276
432
  define_model_callbacks :save, :create, :update, :destroy
277
433
  end
278
434
 
@@ -288,21 +444,24 @@ module ActiveRecord
288
444
  @_destroy_callback_already_called = false
289
445
  end
290
446
 
291
- def touch(*) #:nodoc:
447
+ def touch(*, **) #:nodoc:
292
448
  _run_touch_callbacks { super }
293
449
  end
294
450
 
295
- private
451
+ def increment!(attribute, by = 1, touch: nil) # :nodoc:
452
+ touch ? _run_touch_callbacks { super } : super
453
+ end
296
454
 
297
- def create_or_update(*) #:nodoc:
455
+ private
456
+ def create_or_update(**)
298
457
  _run_save_callbacks { super }
299
458
  end
300
459
 
301
- def _create_record #:nodoc:
460
+ def _create_record
302
461
  _run_create_callbacks { super }
303
462
  end
304
463
 
305
- def _update_record(*) #:nodoc:
464
+ def _update_record
306
465
  _run_update_callbacks { super }
307
466
  end
308
467
  end