activerecord 7.0.0 → 7.2.1

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 (289) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +515 -1268
  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 +16 -13
  7. data/lib/active_record/association_relation.rb +2 -2
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +35 -12
  10. data/lib/active_record/associations/association_scope.rb +16 -9
  11. data/lib/active_record/associations/belongs_to_association.rb +23 -8
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  13. data/lib/active_record/associations/builder/association.rb +3 -3
  14. data/lib/active_record/associations/builder/belongs_to.rb +22 -8
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  16. data/lib/active_record/associations/builder/has_many.rb +3 -4
  17. data/lib/active_record/associations/builder/has_one.rb +3 -4
  18. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  19. data/lib/active_record/associations/collection_association.rb +28 -17
  20. data/lib/active_record/associations/collection_proxy.rb +36 -13
  21. data/lib/active_record/associations/errors.rb +265 -0
  22. data/lib/active_record/associations/foreign_association.rb +10 -3
  23. data/lib/active_record/associations/has_many_association.rb +28 -18
  24. data/lib/active_record/associations/has_many_through_association.rb +10 -6
  25. data/lib/active_record/associations/has_one_association.rb +10 -3
  26. data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
  27. data/lib/active_record/associations/join_dependency.rb +18 -14
  28. data/lib/active_record/associations/nested_error.rb +47 -0
  29. data/lib/active_record/associations/preloader/association.rb +33 -8
  30. data/lib/active_record/associations/preloader/branch.rb +7 -1
  31. data/lib/active_record/associations/preloader/through_association.rb +2 -4
  32. data/lib/active_record/associations/preloader.rb +13 -10
  33. data/lib/active_record/associations/singular_association.rb +7 -1
  34. data/lib/active_record/associations/through_association.rb +22 -11
  35. data/lib/active_record/associations.rb +378 -491
  36. data/lib/active_record/attribute_assignment.rb +1 -13
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  38. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  39. data/lib/active_record/attribute_methods/dirty.rb +53 -35
  40. data/lib/active_record/attribute_methods/primary_key.rb +45 -25
  41. data/lib/active_record/attribute_methods/query.rb +28 -16
  42. data/lib/active_record/attribute_methods/read.rb +8 -7
  43. data/lib/active_record/attribute_methods/serialization.rb +153 -70
  44. data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -6
  45. data/lib/active_record/attribute_methods/write.rb +6 -6
  46. data/lib/active_record/attribute_methods.rb +153 -40
  47. data/lib/active_record/attributes.rb +63 -48
  48. data/lib/active_record/autosave_association.rb +70 -38
  49. data/lib/active_record/base.rb +12 -8
  50. data/lib/active_record/callbacks.rb +16 -32
  51. data/lib/active_record/coders/column_serializer.rb +61 -0
  52. data/lib/active_record/coders/json.rb +1 -1
  53. data/lib/active_record/coders/yaml_column.rb +70 -34
  54. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +124 -132
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +297 -88
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +215 -63
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +83 -65
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +163 -29
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +319 -135
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +512 -126
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +282 -119
  70. data/lib/active_record/connection_adapters/column.rb +9 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +27 -140
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +64 -52
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
  78. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
  80. data/lib/active_record/connection_adapters/pool_config.rb +20 -10
  81. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +16 -3
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +101 -48
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
  87. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +94 -61
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +6 -10
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +379 -66
  98. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  99. data/lib/active_record/connection_adapters/postgresql_adapter.rb +370 -203
  100. data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
  101. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  102. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
  103. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +61 -46
  104. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  105. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  106. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  107. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +64 -22
  108. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +321 -110
  109. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  110. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  111. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  112. data/lib/active_record/connection_adapters.rb +124 -1
  113. data/lib/active_record/connection_handling.rb +98 -106
  114. data/lib/active_record/core.rb +220 -177
  115. data/lib/active_record/counter_cache.rb +68 -34
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -2
  117. data/lib/active_record/database_configurations/database_config.rb +26 -5
  118. data/lib/active_record/database_configurations/hash_config.rb +52 -34
  119. data/lib/active_record/database_configurations/url_config.rb +37 -12
  120. data/lib/active_record/database_configurations.rb +88 -35
  121. data/lib/active_record/delegated_type.rb +40 -11
  122. data/lib/active_record/deprecator.rb +7 -0
  123. data/lib/active_record/destroy_association_async_job.rb +3 -1
  124. data/lib/active_record/disable_joins_association_relation.rb +1 -1
  125. data/lib/active_record/dynamic_matchers.rb +2 -2
  126. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  127. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  128. data/lib/active_record/encryption/config.rb +25 -1
  129. data/lib/active_record/encryption/configurable.rb +13 -14
  130. data/lib/active_record/encryption/context.rb +10 -3
  131. data/lib/active_record/encryption/contexts.rb +8 -4
  132. data/lib/active_record/encryption/derived_secret_key_provider.rb +9 -3
  133. data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
  134. data/lib/active_record/encryption/encryptable_record.rb +47 -25
  135. data/lib/active_record/encryption/encrypted_attribute_type.rb +49 -14
  136. data/lib/active_record/encryption/encryptor.rb +25 -10
  137. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
  138. data/lib/active_record/encryption/extended_deterministic_queries.rb +83 -86
  139. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  140. data/lib/active_record/encryption/key_generator.rb +12 -1
  141. data/lib/active_record/encryption/message.rb +1 -1
  142. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  143. data/lib/active_record/encryption/message_serializer.rb +6 -0
  144. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  145. data/lib/active_record/encryption/properties.rb +4 -4
  146. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  147. data/lib/active_record/encryption/scheme.rb +23 -22
  148. data/lib/active_record/encryption.rb +1 -0
  149. data/lib/active_record/enum.rb +131 -27
  150. data/lib/active_record/errors.rb +151 -31
  151. data/lib/active_record/explain.rb +21 -12
  152. data/lib/active_record/explain_subscriber.rb +1 -1
  153. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  154. data/lib/active_record/fixture_set/render_context.rb +2 -0
  155. data/lib/active_record/fixture_set/table_row.rb +29 -8
  156. data/lib/active_record/fixtures.rb +169 -99
  157. data/lib/active_record/future_result.rb +47 -8
  158. data/lib/active_record/gem_version.rb +3 -3
  159. data/lib/active_record/inheritance.rb +34 -18
  160. data/lib/active_record/insert_all.rb +72 -22
  161. data/lib/active_record/integration.rb +13 -10
  162. data/lib/active_record/internal_metadata.rb +124 -20
  163. data/lib/active_record/locking/optimistic.rb +39 -24
  164. data/lib/active_record/locking/pessimistic.rb +8 -5
  165. data/lib/active_record/log_subscriber.rb +28 -27
  166. data/lib/active_record/marshalling.rb +56 -0
  167. data/lib/active_record/message_pack.rb +124 -0
  168. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  169. data/lib/active_record/middleware/database_selector.rb +18 -13
  170. data/lib/active_record/middleware/shard_selector.rb +7 -5
  171. data/lib/active_record/migration/command_recorder.rb +110 -13
  172. data/lib/active_record/migration/compatibility.rb +174 -64
  173. data/lib/active_record/migration/default_strategy.rb +22 -0
  174. data/lib/active_record/migration/execution_strategy.rb +19 -0
  175. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  176. data/lib/active_record/migration.rb +292 -125
  177. data/lib/active_record/model_schema.rb +113 -112
  178. data/lib/active_record/nested_attributes.rb +35 -9
  179. data/lib/active_record/normalization.rb +163 -0
  180. data/lib/active_record/persistence.rb +177 -345
  181. data/lib/active_record/promise.rb +84 -0
  182. data/lib/active_record/query_cache.rb +19 -25
  183. data/lib/active_record/query_logs.rb +102 -51
  184. data/lib/active_record/query_logs_formatter.rb +41 -0
  185. data/lib/active_record/querying.rb +34 -9
  186. data/lib/active_record/railtie.rb +153 -100
  187. data/lib/active_record/railties/controller_runtime.rb +24 -10
  188. data/lib/active_record/railties/databases.rake +148 -152
  189. data/lib/active_record/railties/job_runtime.rb +23 -0
  190. data/lib/active_record/readonly_attributes.rb +32 -5
  191. data/lib/active_record/reflection.rb +278 -69
  192. data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
  193. data/lib/active_record/relation/batches.rb +198 -63
  194. data/lib/active_record/relation/calculations.rb +293 -108
  195. data/lib/active_record/relation/delegation.rb +31 -20
  196. data/lib/active_record/relation/finder_methods.rb +93 -18
  197. data/lib/active_record/relation/merger.rb +6 -6
  198. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  199. data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
  200. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  201. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  202. data/lib/active_record/relation/predicate_builder.rb +28 -16
  203. data/lib/active_record/relation/query_attribute.rb +25 -1
  204. data/lib/active_record/relation/query_methods.rb +625 -107
  205. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  206. data/lib/active_record/relation/spawn_methods.rb +5 -4
  207. data/lib/active_record/relation/where_clause.rb +7 -19
  208. data/lib/active_record/relation.rb +602 -96
  209. data/lib/active_record/result.rb +55 -52
  210. data/lib/active_record/runtime_registry.rb +63 -1
  211. data/lib/active_record/sanitization.rb +76 -30
  212. data/lib/active_record/schema.rb +39 -23
  213. data/lib/active_record/schema_dumper.rb +82 -30
  214. data/lib/active_record/schema_migration.rb +75 -24
  215. data/lib/active_record/scoping/default.rb +20 -12
  216. data/lib/active_record/scoping/named.rb +3 -2
  217. data/lib/active_record/scoping.rb +2 -1
  218. data/lib/active_record/secure_password.rb +60 -0
  219. data/lib/active_record/secure_token.rb +21 -3
  220. data/lib/active_record/serialization.rb +5 -0
  221. data/lib/active_record/signed_id.rb +29 -8
  222. data/lib/active_record/statement_cache.rb +7 -7
  223. data/lib/active_record/store.rb +16 -11
  224. data/lib/active_record/suppressor.rb +3 -1
  225. data/lib/active_record/table_metadata.rb +7 -3
  226. data/lib/active_record/tasks/database_tasks.rb +191 -121
  227. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  228. data/lib/active_record/tasks/postgresql_database_tasks.rb +17 -15
  229. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  230. data/lib/active_record/test_fixtures.rb +174 -152
  231. data/lib/active_record/testing/query_assertions.rb +121 -0
  232. data/lib/active_record/timestamp.rb +31 -17
  233. data/lib/active_record/token_for.rb +123 -0
  234. data/lib/active_record/touch_later.rb +12 -7
  235. data/lib/active_record/transaction.rb +132 -0
  236. data/lib/active_record/transactions.rb +109 -27
  237. data/lib/active_record/translation.rb +1 -3
  238. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  239. data/lib/active_record/type/internal/timezone.rb +7 -2
  240. data/lib/active_record/type/serialized.rb +9 -7
  241. data/lib/active_record/type/time.rb +4 -0
  242. data/lib/active_record/type_caster/connection.rb +4 -4
  243. data/lib/active_record/validations/absence.rb +1 -1
  244. data/lib/active_record/validations/associated.rb +12 -6
  245. data/lib/active_record/validations/numericality.rb +5 -4
  246. data/lib/active_record/validations/presence.rb +5 -28
  247. data/lib/active_record/validations/uniqueness.rb +63 -14
  248. data/lib/active_record/validations.rb +12 -5
  249. data/lib/active_record/version.rb +1 -1
  250. data/lib/active_record.rb +266 -30
  251. data/lib/arel/alias_predication.rb +1 -1
  252. data/lib/arel/collectors/bind.rb +2 -0
  253. data/lib/arel/collectors/composite.rb +7 -0
  254. data/lib/arel/collectors/sql_string.rb +1 -1
  255. data/lib/arel/collectors/substitute_binds.rb +1 -1
  256. data/lib/arel/errors.rb +10 -0
  257. data/lib/arel/factory_methods.rb +4 -0
  258. data/lib/arel/filter_predications.rb +1 -1
  259. data/lib/arel/nodes/binary.rb +6 -7
  260. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  261. data/lib/arel/nodes/cte.rb +36 -0
  262. data/lib/arel/nodes/filter.rb +1 -1
  263. data/lib/arel/nodes/fragments.rb +35 -0
  264. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  265. data/lib/arel/nodes/leading_join.rb +8 -0
  266. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  267. data/lib/arel/nodes/node.rb +115 -5
  268. data/lib/arel/nodes/sql_literal.rb +13 -0
  269. data/lib/arel/nodes/table_alias.rb +4 -0
  270. data/lib/arel/nodes.rb +6 -2
  271. data/lib/arel/predications.rb +3 -1
  272. data/lib/arel/select_manager.rb +1 -1
  273. data/lib/arel/table.rb +9 -5
  274. data/lib/arel/tree_manager.rb +8 -3
  275. data/lib/arel/update_manager.rb +2 -1
  276. data/lib/arel/visitors/dot.rb +1 -0
  277. data/lib/arel/visitors/mysql.rb +17 -5
  278. data/lib/arel/visitors/postgresql.rb +1 -12
  279. data/lib/arel/visitors/to_sql.rb +112 -34
  280. data/lib/arel/visitors/visitor.rb +2 -2
  281. data/lib/arel.rb +21 -3
  282. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  283. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  284. data/lib/rails/generators/active_record/migration.rb +3 -1
  285. data/lib/rails/generators/active_record/model/USAGE +113 -0
  286. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  287. metadata +59 -17
  288. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  289. data/lib/active_record/null_relation.rb +0 -63
@@ -31,10 +31,13 @@ module ActiveRecord
31
31
  config.active_record.check_schema_cache_dump_version = true
32
32
  config.active_record.maintain_test_schema = true
33
33
  config.active_record.has_many_inversing = false
34
- config.active_record.sqlite3_production_warning = true
35
34
  config.active_record.query_log_tags_enabled = false
36
35
  config.active_record.query_log_tags = [ :application ]
36
+ config.active_record.query_log_tags_format = :legacy
37
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
38
41
 
39
42
  config.active_record.queues = ActiveSupport::InheritableOptions.new
40
43
 
@@ -63,7 +66,7 @@ module ActiveRecord
63
66
  unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
64
67
  console = ActiveSupport::Logger.new(STDERR)
65
68
  console.level = Rails.logger.level
66
- Rails.logger.extend ActiveSupport::Logger.broadcast console
69
+ Rails.logger.broadcast_to(console)
67
70
  end
68
71
  ActiveRecord.verbose_query_logs = false
69
72
  end
@@ -72,12 +75,24 @@ module ActiveRecord
72
75
  require "active_record/base"
73
76
  end
74
77
 
78
+ initializer "active_record.deprecator", before: :load_environment_config do |app|
79
+ app.deprecators[:active_record] = ActiveRecord.deprecator
80
+ end
81
+
75
82
  initializer "active_record.initialize_timezone" do
76
83
  ActiveSupport.on_load(:active_record) do
77
84
  self.time_zone_aware_attributes = true
78
85
  end
79
86
  end
80
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
93
+ end
94
+ end
95
+
81
96
  initializer "active_record.logger" do
82
97
  ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
83
98
  end
@@ -94,23 +109,7 @@ module ActiveRecord
94
109
  end
95
110
  end
96
111
 
97
- initializer "active_record.database_selector" do
98
- if options = config.active_record.database_selector
99
- resolver = config.active_record.database_resolver
100
- operations = config.active_record.database_resolver_context
101
- config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
102
- end
103
- end
104
-
105
- initializer "active_record.shard_selector" do
106
- if resolver = config.active_record.shard_resolver
107
- options = config.active_record.shard_selector || {}
108
-
109
- config.app_middleware.use ActiveRecord::Middleware::ShardSelector, resolver, options
110
- end
111
- end
112
-
113
- initializer "Check for cache versioning support" do
112
+ initializer "active_record.cache_versioning_support" do
114
113
  config.after_initialize do |app|
115
114
  ActiveSupport.on_load(:active_record) do
116
115
  if app.config.active_record.cache_versioning && Rails.cache
@@ -135,59 +134,41 @@ To keep using the current cache store, you can turn off cache versioning entirel
135
134
  end
136
135
  end
137
136
 
138
- initializer "active_record.check_schema_cache_dump" do
139
- check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
137
+ initializer "active_record.copy_schema_cache_config" do
138
+ active_record_config = config.active_record
140
139
 
141
- if config.active_record.use_schema_cache_dump && !config.active_record.lazily_load_schema_cache
142
- config.after_initialize do |app|
143
- ActiveSupport.on_load(:active_record) do
144
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
145
-
146
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
147
- db_config.name,
148
- schema_cache_path: db_config&.schema_cache_path
149
- )
150
-
151
- cache = ActiveRecord::ConnectionAdapters::SchemaCache.load_from(filename)
152
- next if cache.nil?
153
-
154
- if check_schema_cache_dump_version
155
- current_version = begin
156
- ActiveRecord::Migrator.current_version
157
- rescue ActiveRecordError => error
158
- warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
159
- nil
160
- end
161
- next if current_version.nil?
162
-
163
- if cache.version != current_version
164
- warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the schema cache file is #{cache.version}."
165
- next
166
- end
167
- end
168
-
169
- Rails.logger.info("Using schema cache file #{filename}")
170
- connection_pool.set_schema_cache(cache)
171
- end
172
- end
173
- 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
174
142
  end
175
143
 
176
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
177
156
  config.after_initialize do
178
157
  ActiveSupport.on_load(:active_record) do
179
- 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?
180
169
  begin
181
170
  descendants.each do |model|
182
- # If the schema cache was loaded from a dump, we can use it without connecting
183
- schema_cache = model.connection_pool.schema_cache
184
-
185
- # If there's no connection yet, we avoid connecting.
186
- schema_cache ||= model.connected? && model.connection.schema_cache
187
-
188
- # If the schema cache doesn't have the columns
189
- # hash for the model cached, `define_attribute_methods` would trigger a query.
190
- if schema_cache && schema_cache.columns_hash?(model.table_name)
171
+ if model.connection_pool.schema_reflection.cached?(model.table_name)
191
172
  model.define_attribute_methods
192
173
  end
193
174
  end
@@ -204,18 +185,44 @@ To keep using the current cache store, you can turn off cache versioning entirel
204
185
 
205
186
  initializer "active_record.warn_on_records_fetched_greater_than" do
206
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
207
194
  ActiveSupport.on_load(:active_record) do
208
195
  require "active_record/relation/record_fetch_warning"
209
196
  end
210
197
  end
211
198
  end
212
199
 
213
- SQLITE3_PRODUCTION_WARN = "You are running SQLite in production, this is generally not recommended."\
214
- " You can disable this warning by setting \"config.active_record.sqlite3_production_warning=false\"."
215
- initializer "active_record.sqlite3_production_warning" do
216
- if config.active_record.sqlite3_production_warning && Rails.env.production?
217
- ActiveSupport.on_load(:active_record_sqlite3adapter) do
218
- Rails.logger.warn(SQLITE3_PRODUCTION_WARN)
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
219
226
  end
220
227
  end
221
228
  end
@@ -234,8 +241,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
234
241
  end
235
242
 
236
243
  ActiveSupport.on_load(:active_record) do
237
- # Configs used in other initializers
238
- configs = configs.except(
244
+ configs_used_in_other_initializers = configs.except(
239
245
  :migration_error,
240
246
  :database_selector,
241
247
  :database_resolver,
@@ -244,13 +250,15 @@ To keep using the current cache store, you can turn off cache versioning entirel
244
250
  :shard_resolver,
245
251
  :query_log_tags_enabled,
246
252
  :query_log_tags,
253
+ :query_log_tags_format,
247
254
  :cache_query_log_tags,
248
- :sqlite3_production_warning,
255
+ :sqlite3_adapter_strict_strings_by_default,
249
256
  :check_schema_cache_dump_version,
250
- :use_schema_cache_dump
257
+ :use_schema_cache_dump,
258
+ :postgresql_adapter_decode_dates,
251
259
  )
252
260
 
253
- configs.each do |k, v|
261
+ configs_used_in_other_initializers.each do |k, v|
254
262
  next if k == :encryption
255
263
  setter = "#{k}="
256
264
  # Some existing initializers might rely on Active Record configuration
@@ -270,21 +278,23 @@ To keep using the current cache store, you can turn off cache versioning entirel
270
278
  # and then establishes the connection.
271
279
  initializer "active_record.initialize_database" do
272
280
  ActiveSupport.on_load(:active_record) do
273
- if ActiveRecord.legacy_connection_handling
274
- self.connection_handlers = { ActiveRecord.writing_role => ActiveRecord::Base.default_connection_handler }
275
- end
276
281
  self.configurations = Rails.application.config.database_configuration
277
282
 
278
283
  establish_connection
279
284
  end
280
285
  end
281
286
 
282
- # Expose database runtime to controller for logging.
287
+ # Expose database runtime for logging.
283
288
  initializer "active_record.log_runtime" do
284
289
  require "active_record/railties/controller_runtime"
285
290
  ActiveSupport.on_load(:action_controller) do
286
291
  include ActiveRecord::Railties::ControllerRuntime
287
292
  end
293
+
294
+ require "active_record/railties/job_runtime"
295
+ ActiveSupport.on_load(:active_job) do
296
+ include ActiveRecord::Railties::JobRuntime
297
+ end
288
298
  end
289
299
 
290
300
  initializer "active_record.set_reloader_hooks" do
@@ -292,7 +302,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
292
302
  ActiveSupport::Reloader.before_class_unload do
293
303
  if ActiveRecord::Base.connected?
294
304
  ActiveRecord::Base.clear_cache!
295
- ActiveRecord::Base.clear_reloadable_connections!
305
+ ActiveRecord::Base.connection_handler.clear_reloadable_connections!(:all)
296
306
  end
297
307
  end
298
308
  end
@@ -319,8 +329,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
319
329
  # this connection is trivial: the rest of the pool would need to be
320
330
  # populated anyway.
321
331
 
322
- clear_active_connections!
323
- flush_idle_connections!
332
+ connection_handler.clear_active_connections!(:all)
333
+ connection_handler.flush_idle_connections!(:all)
324
334
  end
325
335
  end
326
336
  end
@@ -337,14 +347,25 @@ To keep using the current cache store, you can turn off cache versioning entirel
337
347
  end
338
348
  end
339
349
 
340
- initializer "active_record_encryption.configuration" do |app|
341
- ActiveRecord::Encryption.configure \
342
- primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
343
- deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
344
- key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
345
- **config.active_record.encryption
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
346
357
 
358
+ initializer "active_record_encryption.configuration" do |app|
347
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
+
348
369
  # Support extended queries for deterministic attributes and validations
349
370
  if ActiveRecord::Encryption.config.extend_queries
350
371
  ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
@@ -353,18 +374,11 @@ To keep using the current cache store, you can turn off cache versioning entirel
353
374
  end
354
375
 
355
376
  ActiveSupport.on_load(:active_record_fixture_set) do
356
- # Encrypt active record fixtures
377
+ # Encrypt Active Record fixtures
357
378
  if ActiveRecord::Encryption.config.encrypt_fixtures
358
379
  ActiveRecord::Fixture.prepend ActiveRecord::Encryption::EncryptedFixtures
359
380
  end
360
381
  end
361
-
362
- # Filtered params
363
- ActiveSupport.on_load(:action_controller) do
364
- if ActiveRecord::Encryption.config.add_to_filter_parameters
365
- ActiveRecord::Encryption.install_auto_filtered_parameters(app)
366
- end
367
- end
368
382
  end
369
383
 
370
384
  initializer "active_record.query_log_tags_config" do |app|
@@ -373,21 +387,60 @@ To keep using the current cache store, you can turn off cache versioning entirel
373
387
  ActiveRecord.query_transformers << ActiveRecord::QueryLogs
374
388
  ActiveRecord::QueryLogs.taggings.merge!(
375
389
  application: Rails.application.class.name.split("::").first,
376
- pid: -> { Process.pid },
377
- socket: -> { ActiveRecord::Base.connection_db_config.socket },
378
- db_host: -> { ActiveRecord::Base.connection_db_config.host },
379
- database: -> { ActiveRecord::Base.connection_db_config.database }
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 }
380
395
  )
396
+ ActiveRecord.disable_prepared_statements = true
381
397
 
382
398
  if app.config.active_record.query_log_tags.present?
383
399
  ActiveRecord::QueryLogs.tags = app.config.active_record.query_log_tags
384
400
  end
385
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
+
386
406
  if app.config.active_record.cache_query_log_tags
387
407
  ActiveRecord::QueryLogs.cache_query_log_tags = true
388
408
  end
389
409
  end
390
410
  end
391
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
392
445
  end
393
446
  end
@@ -1,7 +1,7 @@
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:
@@ -11,11 +11,23 @@ module ActiveRecord
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