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