activerecord 6.1.7 → 7.2.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 (332) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +520 -1385
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +31 -31
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +17 -14
  7. data/lib/active_record/association_relation.rb +2 -12
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +60 -21
  10. data/lib/active_record/associations/association_scope.rb +17 -12
  11. data/lib/active_record/associations/belongs_to_association.rb +37 -11
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -4
  13. data/lib/active_record/associations/builder/association.rb +11 -5
  14. data/lib/active_record/associations/builder/belongs_to.rb +41 -14
  15. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +4 -4
  19. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  20. data/lib/active_record/associations/collection_association.rb +46 -36
  21. data/lib/active_record/associations/collection_proxy.rb +44 -16
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/errors.rb +265 -0
  24. data/lib/active_record/associations/foreign_association.rb +10 -3
  25. data/lib/active_record/associations/has_many_association.rb +29 -19
  26. data/lib/active_record/associations/has_many_through_association.rb +12 -7
  27. data/lib/active_record/associations/has_one_association.rb +20 -10
  28. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  29. data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
  30. data/lib/active_record/associations/join_dependency.rb +23 -15
  31. data/lib/active_record/associations/nested_error.rb +47 -0
  32. data/lib/active_record/associations/preloader/association.rb +212 -53
  33. data/lib/active_record/associations/preloader/batch.rb +48 -0
  34. data/lib/active_record/associations/preloader/branch.rb +153 -0
  35. data/lib/active_record/associations/preloader/through_association.rb +50 -16
  36. data/lib/active_record/associations/preloader.rb +50 -121
  37. data/lib/active_record/associations/singular_association.rb +15 -3
  38. data/lib/active_record/associations/through_association.rb +25 -14
  39. data/lib/active_record/associations.rb +404 -509
  40. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  41. data/lib/active_record/attribute_assignment.rb +2 -14
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  43. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  44. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  45. data/lib/active_record/attribute_methods/primary_key.rb +47 -27
  46. data/lib/active_record/attribute_methods/query.rb +31 -19
  47. data/lib/active_record/attribute_methods/read.rb +14 -11
  48. data/lib/active_record/attribute_methods/serialization.rb +174 -37
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -9
  50. data/lib/active_record/attribute_methods/write.rb +12 -15
  51. data/lib/active_record/attribute_methods.rb +164 -52
  52. data/lib/active_record/attributes.rb +51 -49
  53. data/lib/active_record/autosave_association.rb +74 -57
  54. data/lib/active_record/base.rb +27 -5
  55. data/lib/active_record/callbacks.rb +18 -34
  56. data/lib/active_record/coders/column_serializer.rb +61 -0
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +70 -46
  59. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +327 -612
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -60
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +201 -64
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -131
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +377 -142
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +361 -76
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +624 -163
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +345 -166
  75. data/lib/active_record/connection_adapters/column.rb +13 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -130
  78. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -55
  79. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  81. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  82. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
  83. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +107 -68
  85. data/lib/active_record/connection_adapters/pool_config.rb +26 -16
  86. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  87. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  88. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +114 -54
  89. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  94. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  100. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/quoting.rb +137 -104
  103. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  104. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  105. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +173 -3
  106. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  107. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +401 -77
  108. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  109. data/lib/active_record/connection_adapters/postgresql_adapter.rb +518 -251
  110. data/lib/active_record/connection_adapters/schema_cache.rb +326 -102
  111. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  112. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +78 -55
  113. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +68 -54
  114. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  116. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  117. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +66 -22
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +372 -130
  119. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  120. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  121. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  122. data/lib/active_record/connection_adapters.rb +130 -6
  123. data/lib/active_record/connection_handling.rb +132 -146
  124. data/lib/active_record/core.rb +276 -251
  125. data/lib/active_record/counter_cache.rb +68 -34
  126. data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -3
  127. data/lib/active_record/database_configurations/database_config.rb +34 -10
  128. data/lib/active_record/database_configurations/hash_config.rb +107 -31
  129. data/lib/active_record/database_configurations/url_config.rb +38 -13
  130. data/lib/active_record/database_configurations.rb +96 -60
  131. data/lib/active_record/delegated_type.rb +90 -20
  132. data/lib/active_record/deprecator.rb +7 -0
  133. data/lib/active_record/destroy_association_async_job.rb +4 -2
  134. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  135. data/lib/active_record/dynamic_matchers.rb +3 -3
  136. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +68 -0
  140. data/lib/active_record/encryption/configurable.rb +60 -0
  141. data/lib/active_record/encryption/context.rb +42 -0
  142. data/lib/active_record/encryption/contexts.rb +76 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +170 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +53 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  159. data/lib/active_record/encryption/message_serializer.rb +96 -0
  160. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  161. data/lib/active_record/encryption/properties.rb +76 -0
  162. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  163. data/lib/active_record/encryption/scheme.rb +100 -0
  164. data/lib/active_record/encryption.rb +56 -0
  165. data/lib/active_record/enum.rb +163 -63
  166. data/lib/active_record/errors.rb +210 -27
  167. data/lib/active_record/explain.rb +21 -12
  168. data/lib/active_record/explain_registry.rb +11 -6
  169. data/lib/active_record/explain_subscriber.rb +1 -1
  170. data/lib/active_record/fixture_set/file.rb +15 -1
  171. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  172. data/lib/active_record/fixture_set/render_context.rb +2 -0
  173. data/lib/active_record/fixture_set/table_row.rb +70 -14
  174. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  175. data/lib/active_record/fixtures.rb +179 -112
  176. data/lib/active_record/future_result.rb +178 -0
  177. data/lib/active_record/gem_version.rb +4 -4
  178. data/lib/active_record/inheritance.rb +85 -31
  179. data/lib/active_record/insert_all.rb +148 -32
  180. data/lib/active_record/integration.rb +14 -10
  181. data/lib/active_record/internal_metadata.rb +123 -23
  182. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  183. data/lib/active_record/locking/optimistic.rb +43 -27
  184. data/lib/active_record/locking/pessimistic.rb +15 -6
  185. data/lib/active_record/log_subscriber.rb +41 -29
  186. data/lib/active_record/marshalling.rb +56 -0
  187. data/lib/active_record/message_pack.rb +124 -0
  188. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  189. data/lib/active_record/middleware/database_selector.rb +23 -13
  190. data/lib/active_record/middleware/shard_selector.rb +62 -0
  191. data/lib/active_record/migration/command_recorder.rb +113 -16
  192. data/lib/active_record/migration/compatibility.rb +235 -46
  193. data/lib/active_record/migration/default_strategy.rb +22 -0
  194. data/lib/active_record/migration/execution_strategy.rb +19 -0
  195. data/lib/active_record/migration/join_table.rb +1 -1
  196. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  197. data/lib/active_record/migration.rb +374 -177
  198. data/lib/active_record/model_schema.rb +143 -159
  199. data/lib/active_record/nested_attributes.rb +48 -21
  200. data/lib/active_record/no_touching.rb +3 -3
  201. data/lib/active_record/normalization.rb +163 -0
  202. data/lib/active_record/persistence.rb +282 -283
  203. data/lib/active_record/promise.rb +84 -0
  204. data/lib/active_record/query_cache.rb +19 -25
  205. data/lib/active_record/query_logs.rb +189 -0
  206. data/lib/active_record/query_logs_formatter.rb +41 -0
  207. data/lib/active_record/querying.rb +44 -9
  208. data/lib/active_record/railtie.rb +234 -71
  209. data/lib/active_record/railties/controller_runtime.rb +25 -11
  210. data/lib/active_record/railties/databases.rake +189 -256
  211. data/lib/active_record/railties/job_runtime.rb +23 -0
  212. data/lib/active_record/readonly_attributes.rb +41 -3
  213. data/lib/active_record/reflection.rb +325 -103
  214. data/lib/active_record/relation/batches/batch_enumerator.rb +38 -9
  215. data/lib/active_record/relation/batches.rb +198 -63
  216. data/lib/active_record/relation/calculations.rb +300 -111
  217. data/lib/active_record/relation/delegation.rb +33 -22
  218. data/lib/active_record/relation/finder_methods.rb +123 -52
  219. data/lib/active_record/relation/merger.rb +26 -19
  220. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  221. data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
  222. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  223. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  224. data/lib/active_record/relation/predicate_builder.rb +29 -22
  225. data/lib/active_record/relation/query_attribute.rb +30 -12
  226. data/lib/active_record/relation/query_methods.rb +842 -150
  227. data/lib/active_record/relation/record_fetch_warning.rb +10 -9
  228. data/lib/active_record/relation/spawn_methods.rb +7 -6
  229. data/lib/active_record/relation/where_clause.rb +15 -36
  230. data/lib/active_record/relation.rb +736 -145
  231. data/lib/active_record/result.rb +67 -54
  232. data/lib/active_record/runtime_registry.rb +71 -13
  233. data/lib/active_record/sanitization.rb +84 -34
  234. data/lib/active_record/schema.rb +39 -23
  235. data/lib/active_record/schema_dumper.rb +90 -31
  236. data/lib/active_record/schema_migration.rb +74 -23
  237. data/lib/active_record/scoping/default.rb +72 -15
  238. data/lib/active_record/scoping/named.rb +5 -13
  239. data/lib/active_record/scoping.rb +65 -34
  240. data/lib/active_record/secure_password.rb +60 -0
  241. data/lib/active_record/secure_token.rb +21 -3
  242. data/lib/active_record/serialization.rb +6 -1
  243. data/lib/active_record/signed_id.rb +30 -9
  244. data/lib/active_record/statement_cache.rb +7 -7
  245. data/lib/active_record/store.rb +10 -10
  246. data/lib/active_record/suppressor.rb +13 -15
  247. data/lib/active_record/table_metadata.rb +7 -3
  248. data/lib/active_record/tasks/database_tasks.rb +277 -149
  249. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  250. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  251. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  252. data/lib/active_record/test_databases.rb +1 -1
  253. data/lib/active_record/test_fixtures.rb +173 -155
  254. data/lib/active_record/testing/query_assertions.rb +121 -0
  255. data/lib/active_record/timestamp.rb +32 -19
  256. data/lib/active_record/token_for.rb +123 -0
  257. data/lib/active_record/touch_later.rb +12 -7
  258. data/lib/active_record/transaction.rb +132 -0
  259. data/lib/active_record/transactions.rb +118 -41
  260. data/lib/active_record/translation.rb +3 -5
  261. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  262. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  263. data/lib/active_record/type/internal/timezone.rb +7 -2
  264. data/lib/active_record/type/serialized.rb +9 -7
  265. data/lib/active_record/type/time.rb +4 -0
  266. data/lib/active_record/type/type_map.rb +17 -20
  267. data/lib/active_record/type.rb +1 -2
  268. data/lib/active_record/type_caster/connection.rb +4 -4
  269. data/lib/active_record/validations/absence.rb +1 -1
  270. data/lib/active_record/validations/associated.rb +13 -7
  271. data/lib/active_record/validations/numericality.rb +5 -4
  272. data/lib/active_record/validations/presence.rb +5 -28
  273. data/lib/active_record/validations/uniqueness.rb +64 -15
  274. data/lib/active_record/validations.rb +12 -5
  275. data/lib/active_record/version.rb +1 -1
  276. data/lib/active_record.rb +444 -32
  277. data/lib/arel/alias_predication.rb +1 -1
  278. data/lib/arel/attributes/attribute.rb +0 -8
  279. data/lib/arel/collectors/bind.rb +2 -0
  280. data/lib/arel/collectors/composite.rb +7 -0
  281. data/lib/arel/collectors/sql_string.rb +1 -1
  282. data/lib/arel/collectors/substitute_binds.rb +1 -1
  283. data/lib/arel/crud.rb +28 -22
  284. data/lib/arel/delete_manager.rb +18 -4
  285. data/lib/arel/errors.rb +10 -0
  286. data/lib/arel/factory_methods.rb +4 -0
  287. data/lib/arel/filter_predications.rb +9 -0
  288. data/lib/arel/insert_manager.rb +2 -3
  289. data/lib/arel/nodes/binary.rb +6 -7
  290. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  291. data/lib/arel/nodes/casted.rb +1 -1
  292. data/lib/arel/nodes/cte.rb +36 -0
  293. data/lib/arel/nodes/delete_statement.rb +12 -13
  294. data/lib/arel/nodes/filter.rb +10 -0
  295. data/lib/arel/nodes/fragments.rb +35 -0
  296. data/lib/arel/nodes/function.rb +1 -0
  297. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  298. data/lib/arel/nodes/insert_statement.rb +2 -2
  299. data/lib/arel/nodes/leading_join.rb +8 -0
  300. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  301. data/lib/arel/nodes/node.rb +115 -5
  302. data/lib/arel/nodes/select_core.rb +2 -2
  303. data/lib/arel/nodes/select_statement.rb +2 -2
  304. data/lib/arel/nodes/sql_literal.rb +13 -0
  305. data/lib/arel/nodes/table_alias.rb +4 -0
  306. data/lib/arel/nodes/update_statement.rb +8 -3
  307. data/lib/arel/nodes.rb +7 -2
  308. data/lib/arel/predications.rb +14 -4
  309. data/lib/arel/select_manager.rb +11 -5
  310. data/lib/arel/table.rb +9 -6
  311. data/lib/arel/tree_manager.rb +8 -15
  312. data/lib/arel/update_manager.rb +20 -5
  313. data/lib/arel/visitors/dot.rb +81 -90
  314. data/lib/arel/visitors/mysql.rb +23 -5
  315. data/lib/arel/visitors/postgresql.rb +1 -22
  316. data/lib/arel/visitors/to_sql.rb +170 -36
  317. data/lib/arel/visitors/visitor.rb +2 -2
  318. data/lib/arel.rb +23 -4
  319. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  320. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  321. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  322. data/lib/rails/generators/active_record/migration.rb +3 -1
  323. data/lib/rails/generators/active_record/model/USAGE +113 -0
  324. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  325. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  326. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  327. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  328. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  329. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  330. metadata +100 -14
  331. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  332. data/lib/active_record/null_relation.rb +0 -67
@@ -15,6 +15,7 @@ module ActiveRecord
15
15
  # = Active Record Railtie
16
16
  class Railtie < Rails::Railtie # :nodoc:
17
17
  config.active_record = ActiveSupport::OrderedOptions.new
18
+ config.active_record.encryption = ActiveSupport::OrderedOptions.new
18
19
 
19
20
  config.app_generators.orm :active_record, migration: true,
20
21
  timestamps: true
@@ -30,6 +31,13 @@ module ActiveRecord
30
31
  config.active_record.check_schema_cache_dump_version = true
31
32
  config.active_record.maintain_test_schema = true
32
33
  config.active_record.has_many_inversing = false
34
+ config.active_record.query_log_tags_enabled = false
35
+ config.active_record.query_log_tags = [ :application ]
36
+ config.active_record.query_log_tags_format = :legacy
37
+ config.active_record.cache_query_log_tags = false
38
+ config.active_record.raise_on_assign_to_attr_readonly = false
39
+ config.active_record.belongs_to_required_validates_foreign_key = true
40
+ config.active_record.generate_secure_token_on = :create
33
41
 
34
42
  config.active_record.queues = ActiveSupport::InheritableOptions.new
35
43
 
@@ -58,19 +66,30 @@ module ActiveRecord
58
66
  unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
59
67
  console = ActiveSupport::Logger.new(STDERR)
60
68
  console.level = Rails.logger.level
61
- Rails.logger.extend ActiveSupport::Logger.broadcast console
69
+ Rails.logger.broadcast_to(console)
62
70
  end
63
- ActiveRecord::Base.verbose_query_logs = false
71
+ ActiveRecord.verbose_query_logs = false
64
72
  end
65
73
 
66
74
  runner do
67
75
  require "active_record/base"
68
76
  end
69
77
 
78
+ initializer "active_record.deprecator", before: :load_environment_config do |app|
79
+ app.deprecators[:active_record] = ActiveRecord.deprecator
80
+ end
81
+
70
82
  initializer "active_record.initialize_timezone" do
71
83
  ActiveSupport.on_load(:active_record) do
72
84
  self.time_zone_aware_attributes = true
73
- self.default_timezone = :utc
85
+ end
86
+ end
87
+
88
+ initializer "active_record.postgresql_time_zone_aware_types" do
89
+ ActiveSupport.on_load(:active_record_postgresqladapter) do
90
+ ActiveSupport.on_load(:active_record) do
91
+ ActiveRecord::Base.time_zone_aware_types << :timestamptz
92
+ end
74
93
  end
75
94
  end
76
95
 
@@ -83,22 +102,14 @@ module ActiveRecord
83
102
  end
84
103
 
85
104
  initializer "active_record.migration_error" do |app|
86
- if config.active_record.delete(:migration_error) == :page_load
105
+ if config.active_record.migration_error == :page_load
87
106
  config.app_middleware.insert_after ::ActionDispatch::Callbacks,
88
107
  ActiveRecord::Migration::CheckPending,
89
108
  file_watcher: app.config.file_watcher
90
109
  end
91
110
  end
92
111
 
93
- initializer "active_record.database_selector" do
94
- if options = config.active_record.delete(:database_selector)
95
- resolver = config.active_record.delete(:database_resolver)
96
- operations = config.active_record.delete(:database_resolver_context)
97
- config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
98
- end
99
- end
100
-
101
- initializer "Check for cache versioning support" do
112
+ initializer "active_record.cache_versioning_support" do
102
113
  config.after_initialize do |app|
103
114
  ActiveSupport.on_load(:active_record) do
104
115
  if app.config.active_record.cache_versioning && Rails.cache
@@ -123,62 +134,41 @@ To keep using the current cache store, you can turn off cache versioning entirel
123
134
  end
124
135
  end
125
136
 
126
- initializer "active_record.check_schema_cache_dump" do
127
- check_schema_cache_dump_version = config.active_record.delete(:check_schema_cache_dump_version)
128
-
129
- if config.active_record.delete(:use_schema_cache_dump)
130
- config.after_initialize do |app|
131
- ActiveSupport.on_load(:active_record) do
132
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
133
-
134
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
135
- db_config.name,
136
- schema_cache_path: db_config&.schema_cache_path
137
- )
137
+ initializer "active_record.copy_schema_cache_config" do
138
+ active_record_config = config.active_record
138
139
 
139
- cache = ActiveRecord::ConnectionAdapters::SchemaCache.load_from(filename)
140
- next if cache.nil?
141
-
142
- if check_schema_cache_dump_version
143
- current_version = begin
144
- ActiveRecord::Migrator.current_version
145
- rescue ActiveRecordError => error
146
- warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
147
- nil
148
- end
149
- next if current_version.nil?
150
-
151
- if cache.version != current_version
152
- warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
153
- next
154
- end
155
- end
156
-
157
- connection_pool.set_schema_cache(cache)
158
- end
159
- end
160
- end
140
+ ActiveRecord::ConnectionAdapters::SchemaReflection.use_schema_cache_dump = active_record_config.use_schema_cache_dump
141
+ ActiveRecord::ConnectionAdapters::SchemaReflection.check_schema_cache_dump_version = active_record_config.check_schema_cache_dump_version
161
142
  end
162
143
 
163
144
  initializer "active_record.define_attribute_methods" do |app|
145
+ # For resiliency, it is critical that a Rails application should be
146
+ # able to boot without depending on the database (or any other service)
147
+ # being responsive.
148
+ #
149
+ # Otherwise a bad deploy adding a lot of load on the database may require to
150
+ # entirely shutdown the application so the database can recover before a fixed
151
+ # version can be deployed again.
152
+ #
153
+ # This is why this initializer tries hard not to query the database, and if it
154
+ # does, it makes sure to rescue any possible database error.
155
+ check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
164
156
  config.after_initialize do
165
157
  ActiveSupport.on_load(:active_record) do
166
- if app.config.eager_load
158
+ # In development and test we shouldn't eagerly define attribute methods because
159
+ # db:test:prepare will trigger later and might change the schema.
160
+ #
161
+ # Additionally if `check_schema_cache_dump_version` is enabled (which is the default),
162
+ # loading the schema cache dump trigger a database connection to compare the schema
163
+ # versions.
164
+ # This means the attribute methods will be lazily defined when the model is accessed,
165
+ # likely as part of the first few requests or jobs. This isn't good for performance
166
+ # but we unfortunately have to arbitrate between resiliency and performance, and chose
167
+ # resiliency.
168
+ if !check_schema_cache_dump_version && app.config.eager_load && !Rails.env.local?
167
169
  begin
168
170
  descendants.each do |model|
169
- # SchemaMigration and InternalMetadata both override `table_exists?`
170
- # to bypass the schema cache, so skip them to avoid the extra queries.
171
- next if model._internal?
172
-
173
- # If the schema cache was loaded from a dump, we can use it without connecting
174
- schema_cache = model.connection_pool.schema_cache
175
-
176
- # If there's no connection yet, we avoid connecting.
177
- schema_cache ||= model.connected? && model.connection.schema_cache
178
-
179
- # If the schema cache doesn't have the columns
180
- # hash for the model cached, `define_attribute_methods` would trigger a query.
181
- if schema_cache && schema_cache.columns_hash?(model.table_name)
171
+ if model.connection_pool.schema_reflection.cached?(model.table_name)
182
172
  model.define_attribute_methods
183
173
  end
184
174
  end
@@ -195,18 +185,91 @@ To keep using the current cache store, you can turn off cache versioning entirel
195
185
 
196
186
  initializer "active_record.warn_on_records_fetched_greater_than" do
197
187
  if config.active_record.warn_on_records_fetched_greater_than
188
+ ActiveRecord.deprecator.warn <<~MSG.squish
189
+ `config.active_record.warn_on_records_fetched_greater_than` is deprecated and will be
190
+ removed in Rails 8.0.
191
+ Please subscribe to `sql.active_record` notifications and access the row count field to
192
+ detect large result set sizes.
193
+ MSG
198
194
  ActiveSupport.on_load(:active_record) do
199
195
  require "active_record/relation/record_fetch_warning"
200
196
  end
201
197
  end
202
198
  end
203
199
 
200
+ initializer "active_record.sqlite3_deprecated_warning" do
201
+ if config.active_record.key?(:sqlite3_production_warning)
202
+ config.active_record.delete(:sqlite3_production_warning)
203
+ ActiveRecord.deprecator.warn <<~MSG.squish
204
+ The `config.active_record.sqlite3_production_warning` configuration no longer has any effect
205
+ and can be safely removed.
206
+ MSG
207
+ end
208
+ end
209
+
210
+ initializer "active_record.sqlite3_adapter_strict_strings_by_default" do
211
+ config.after_initialize do
212
+ if config.active_record.sqlite3_adapter_strict_strings_by_default
213
+ ActiveSupport.on_load(:active_record_sqlite3adapter) do
214
+ self.strict_strings_by_default = true
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ initializer "active_record.postgresql_adapter_decode_dates" do
221
+ config.after_initialize do
222
+ if config.active_record.postgresql_adapter_decode_dates
223
+ ActiveSupport.on_load(:active_record_postgresqladapter) do
224
+ self.decode_dates = true
225
+ end
226
+ end
227
+ end
228
+ end
229
+
204
230
  initializer "active_record.set_configs" do |app|
205
- ActiveSupport.on_load(:active_record) do
206
- configs = app.config.active_record
231
+ configs = app.config.active_record
207
232
 
233
+ config.after_initialize do
208
234
  configs.each do |k, v|
209
- send "#{k}=", v
235
+ next if k == :encryption
236
+ setter = "#{k}="
237
+ if ActiveRecord.respond_to?(setter)
238
+ ActiveRecord.send(setter, v)
239
+ end
240
+ end
241
+ end
242
+
243
+ ActiveSupport.on_load(:active_record) do
244
+ configs_used_in_other_initializers = configs.except(
245
+ :migration_error,
246
+ :database_selector,
247
+ :database_resolver,
248
+ :database_resolver_context,
249
+ :shard_selector,
250
+ :shard_resolver,
251
+ :query_log_tags_enabled,
252
+ :query_log_tags,
253
+ :query_log_tags_format,
254
+ :cache_query_log_tags,
255
+ :sqlite3_adapter_strict_strings_by_default,
256
+ :check_schema_cache_dump_version,
257
+ :use_schema_cache_dump,
258
+ :postgresql_adapter_decode_dates,
259
+ )
260
+
261
+ configs_used_in_other_initializers.each do |k, v|
262
+ next if k == :encryption
263
+ setter = "#{k}="
264
+ # Some existing initializers might rely on Active Record configuration
265
+ # being copied from the config object to their actual destination when
266
+ # `ActiveRecord::Base` is loaded.
267
+ # So to preserve backward compatibility we copy the config a second time.
268
+ if ActiveRecord.respond_to?(setter)
269
+ ActiveRecord.send(setter, v)
270
+ else
271
+ send(setter, v)
272
+ end
210
273
  end
211
274
  end
212
275
  end
@@ -215,20 +278,23 @@ To keep using the current cache store, you can turn off cache versioning entirel
215
278
  # and then establishes the connection.
216
279
  initializer "active_record.initialize_database" do
217
280
  ActiveSupport.on_load(:active_record) do
218
- if ActiveRecord::Base.legacy_connection_handling
219
- self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
220
- end
221
281
  self.configurations = Rails.application.config.database_configuration
282
+
222
283
  establish_connection
223
284
  end
224
285
  end
225
286
 
226
- # Expose database runtime to controller for logging.
287
+ # Expose database runtime for logging.
227
288
  initializer "active_record.log_runtime" do
228
289
  require "active_record/railties/controller_runtime"
229
290
  ActiveSupport.on_load(:action_controller) do
230
291
  include ActiveRecord::Railties::ControllerRuntime
231
292
  end
293
+
294
+ require "active_record/railties/job_runtime"
295
+ ActiveSupport.on_load(:active_job) do
296
+ include ActiveRecord::Railties::JobRuntime
297
+ end
232
298
  end
233
299
 
234
300
  initializer "active_record.set_reloader_hooks" do
@@ -236,7 +302,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
236
302
  ActiveSupport::Reloader.before_class_unload do
237
303
  if ActiveRecord::Base.connected?
238
304
  ActiveRecord::Base.clear_cache!
239
- ActiveRecord::Base.clear_reloadable_connections!
305
+ ActiveRecord::Base.connection_handler.clear_reloadable_connections!(:all)
240
306
  end
241
307
  end
242
308
  end
@@ -244,6 +310,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
244
310
 
245
311
  initializer "active_record.set_executor_hooks" do
246
312
  ActiveRecord::QueryCache.install_executor_hooks
313
+ ActiveRecord::AsynchronousQueriesTracker.install_executor_hooks
247
314
  end
248
315
 
249
316
  initializer "active_record.add_watchable_files" do |app|
@@ -262,8 +329,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
262
329
  # this connection is trivial: the rest of the pool would need to be
263
330
  # populated anyway.
264
331
 
265
- clear_active_connections!
266
- flush_idle_connections!
332
+ connection_handler.clear_active_connections!(:all)
333
+ connection_handler.flush_idle_connections!(:all)
267
334
  end
268
335
  end
269
336
  end
@@ -279,5 +346,101 @@ To keep using the current cache store, you can turn off cache versioning entirel
279
346
  self.signed_id_verifier_secret ||= -> { Rails.application.key_generator.generate_key("active_record/signed_id") }
280
347
  end
281
348
  end
349
+
350
+ initializer "active_record.generated_token_verifier" do
351
+ config.after_initialize do |app|
352
+ ActiveSupport.on_load(:active_record) do
353
+ self.generated_token_verifier ||= app.message_verifier("active_record/token_for")
354
+ end
355
+ end
356
+ end
357
+
358
+ initializer "active_record_encryption.configuration" do |app|
359
+ ActiveSupport.on_load(:active_record) do
360
+ ActiveRecord::Encryption.configure \
361
+ primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
362
+ deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
363
+ key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
364
+ **app.config.active_record.encryption
365
+
366
+ auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
367
+ auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
368
+
369
+ # Support extended queries for deterministic attributes and validations
370
+ if ActiveRecord::Encryption.config.extend_queries
371
+ ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
372
+ ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
373
+ end
374
+ end
375
+
376
+ ActiveSupport.on_load(:active_record_fixture_set) do
377
+ # Encrypt Active Record fixtures
378
+ if ActiveRecord::Encryption.config.encrypt_fixtures
379
+ ActiveRecord::Fixture.prepend ActiveRecord::Encryption::EncryptedFixtures
380
+ end
381
+ end
382
+ end
383
+
384
+ initializer "active_record.query_log_tags_config" do |app|
385
+ config.after_initialize do
386
+ if app.config.active_record.query_log_tags_enabled
387
+ ActiveRecord.query_transformers << ActiveRecord::QueryLogs
388
+ ActiveRecord::QueryLogs.taggings.merge!(
389
+ application: Rails.application.class.name.split("::").first,
390
+ pid: -> { Process.pid.to_s },
391
+ socket: ->(context) { context[:connection].pool.db_config.socket },
392
+ db_host: ->(context) { context[:connection].pool.db_config.host },
393
+ database: ->(context) { context[:connection].pool.db_config.database },
394
+ source_location: -> { QueryLogs.query_source_location }
395
+ )
396
+ ActiveRecord.disable_prepared_statements = true
397
+
398
+ if app.config.active_record.query_log_tags.present?
399
+ ActiveRecord::QueryLogs.tags = app.config.active_record.query_log_tags
400
+ end
401
+
402
+ if app.config.active_record.query_log_tags_format
403
+ ActiveRecord::QueryLogs.update_formatter(app.config.active_record.query_log_tags_format)
404
+ end
405
+
406
+ if app.config.active_record.cache_query_log_tags
407
+ ActiveRecord::QueryLogs.cache_query_log_tags = true
408
+ end
409
+ end
410
+ end
411
+ end
412
+
413
+ initializer "active_record.unregister_current_scopes_on_unload" do |app|
414
+ config.after_initialize do
415
+ if app.config.reloading_enabled?
416
+ Rails.autoloaders.main.on_unload do |_cpath, value, _abspath|
417
+ # Conditions are written this way to be robust against custom
418
+ # implementations of value#is_a? or value#<.
419
+ if Class === value && ActiveRecord::Base > value
420
+ value.current_scope = nil
421
+ end
422
+ end
423
+ end
424
+ end
425
+ end
426
+
427
+ initializer "active_record.message_pack" do
428
+ ActiveSupport.on_load(:message_pack) do
429
+ ActiveSupport.on_load(:active_record) do
430
+ require "active_record/message_pack"
431
+ ActiveRecord::MessagePack::Extensions.install(ActiveSupport::MessagePack::CacheSerializer)
432
+ end
433
+ end
434
+ end
435
+
436
+ initializer "active_record.attributes_for_inspect" do |app|
437
+ ActiveSupport.on_load(:active_record) do
438
+ if app.config.consider_all_requests_local
439
+ if app.config.active_record.attributes_for_inspect.nil?
440
+ ActiveRecord::Base.attributes_for_inspect = :all
441
+ end
442
+ end
443
+ end
444
+ end
282
445
  end
283
446
  end
@@ -1,21 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/module/attr_internal"
4
- require "active_record/log_subscriber"
4
+ require "active_record/runtime_registry"
5
5
 
6
6
  module ActiveRecord
7
7
  module Railties # :nodoc:
8
- module ControllerRuntime #:nodoc:
8
+ module ControllerRuntime # :nodoc:
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  module ClassMethods # :nodoc:
12
12
  def log_process_action(payload)
13
13
  messages, db_runtime = super, payload[:db_runtime]
14
- messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
14
+
15
+ if db_runtime
16
+ queries_count = payload[:queries_count] || 0
17
+ cached_queries_count = payload[:cached_queries_count] || 0
18
+ messages << ("ActiveRecord: %.1fms (%d %s, %d cached)" % [db_runtime.to_f, queries_count,
19
+ "query".pluralize(queries_count), cached_queries_count])
20
+ end
21
+
15
22
  messages
16
23
  end
17
24
  end
18
25
 
26
+ def initialize(...) # :nodoc:
27
+ super
28
+ self.db_runtime = nil
29
+ end
30
+
19
31
  private
20
32
  attr_internal :db_runtime
21
33
 
@@ -23,18 +35,19 @@ module ActiveRecord
23
35
  # We also need to reset the runtime before each action
24
36
  # because of queries in middleware or in cases we are streaming
25
37
  # and it won't be cleaned up by the method below.
26
- ActiveRecord::LogSubscriber.reset_runtime
38
+ ActiveRecord::RuntimeRegistry.reset
27
39
  super
28
40
  end
29
41
 
30
42
  def cleanup_view_runtime
31
- if logger && logger.info? && ActiveRecord::Base.connected?
32
- db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
43
+ if logger && logger.info?
44
+ db_rt_before_render = ActiveRecord::RuntimeRegistry.reset_runtimes
33
45
  self.db_runtime = (db_runtime || 0) + db_rt_before_render
34
46
  runtime = super
35
- db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
47
+ queries_rt = ActiveRecord::RuntimeRegistry.sql_runtime - ActiveRecord::RuntimeRegistry.async_sql_runtime
48
+ db_rt_after_render = ActiveRecord::RuntimeRegistry.reset_runtimes
36
49
  self.db_runtime += db_rt_after_render
37
- runtime - db_rt_after_render
50
+ runtime - queries_rt
38
51
  else
39
52
  super
40
53
  end
@@ -42,9 +55,10 @@ module ActiveRecord
42
55
 
43
56
  def append_info_to_payload(payload)
44
57
  super
45
- if ActiveRecord::Base.connected?
46
- payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
47
- end
58
+
59
+ payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::RuntimeRegistry.reset_runtimes
60
+ payload[:queries_count] = ActiveRecord::RuntimeRegistry.reset_queries_count
61
+ payload[:cached_queries_count] = ActiveRecord::RuntimeRegistry.reset_cached_queries_count
48
62
  end
49
63
  end
50
64
  end