activerecord 6.1.7 → 7.1.5

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 (311) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2030 -1020
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  5. data/lib/active_record/aggregations.rb +17 -14
  6. data/lib/active_record/association_relation.rb +1 -11
  7. data/lib/active_record/associations/association.rb +51 -19
  8. data/lib/active_record/associations/association_scope.rb +17 -12
  9. data/lib/active_record/associations/belongs_to_association.rb +28 -9
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +11 -5
  12. data/lib/active_record/associations/builder/belongs_to.rb +40 -14
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  15. data/lib/active_record/associations/builder/has_many.rb +3 -2
  16. data/lib/active_record/associations/builder/has_one.rb +2 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  18. data/lib/active_record/associations/collection_association.rb +39 -35
  19. data/lib/active_record/associations/collection_proxy.rb +30 -15
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  21. data/lib/active_record/associations/foreign_association.rb +10 -3
  22. data/lib/active_record/associations/has_many_association.rb +28 -18
  23. data/lib/active_record/associations/has_many_through_association.rb +12 -7
  24. data/lib/active_record/associations/has_one_association.rb +20 -10
  25. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  26. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  27. data/lib/active_record/associations/join_dependency.rb +28 -20
  28. data/lib/active_record/associations/preloader/association.rb +210 -52
  29. data/lib/active_record/associations/preloader/batch.rb +48 -0
  30. data/lib/active_record/associations/preloader/branch.rb +147 -0
  31. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  32. data/lib/active_record/associations/preloader.rb +50 -121
  33. data/lib/active_record/associations/singular_association.rb +9 -3
  34. data/lib/active_record/associations/through_association.rb +25 -14
  35. data/lib/active_record/associations.rb +446 -306
  36. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  37. data/lib/active_record/attribute_assignment.rb +1 -3
  38. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  39. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  40. data/lib/active_record/attribute_methods/primary_key.rb +78 -26
  41. data/lib/active_record/attribute_methods/query.rb +31 -19
  42. data/lib/active_record/attribute_methods/read.rb +27 -12
  43. data/lib/active_record/attribute_methods/serialization.rb +194 -37
  44. data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
  45. data/lib/active_record/attribute_methods/write.rb +12 -15
  46. data/lib/active_record/attribute_methods.rb +161 -40
  47. data/lib/active_record/attributes.rb +27 -38
  48. data/lib/active_record/autosave_association.rb +65 -31
  49. data/lib/active_record/base.rb +25 -2
  50. data/lib/active_record/callbacks.rb +18 -34
  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 -46
  54. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +113 -597
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -27
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +367 -141
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -150
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +317 -164
  70. data/lib/active_record/connection_adapters/column.rb +13 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
  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 +39 -14
  78. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +112 -55
  80. data/lib/active_record/connection_adapters/pool_config.rb +20 -11
  81. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
  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/date.rb +8 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  89. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +397 -75
  101. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  102. data/lib/active_record/connection_adapters/postgresql_adapter.rb +508 -246
  103. data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
  104. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  105. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
  106. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
  107. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  108. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
  109. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +296 -104
  110. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  111. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  112. data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
  113. data/lib/active_record/connection_adapters.rb +9 -6
  114. data/lib/active_record/connection_handling.rb +108 -137
  115. data/lib/active_record/core.rb +242 -233
  116. data/lib/active_record/counter_cache.rb +52 -27
  117. data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -2
  118. data/lib/active_record/database_configurations/database_config.rb +21 -12
  119. data/lib/active_record/database_configurations/hash_config.rb +88 -16
  120. data/lib/active_record/database_configurations/url_config.rb +18 -12
  121. data/lib/active_record/database_configurations.rb +95 -59
  122. data/lib/active_record/delegated_type.rb +66 -20
  123. data/lib/active_record/deprecator.rb +7 -0
  124. data/lib/active_record/destroy_association_async_job.rb +4 -2
  125. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  126. data/lib/active_record/dynamic_matchers.rb +1 -1
  127. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  128. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  129. data/lib/active_record/encryption/cipher.rb +53 -0
  130. data/lib/active_record/encryption/config.rb +68 -0
  131. data/lib/active_record/encryption/configurable.rb +60 -0
  132. data/lib/active_record/encryption/context.rb +42 -0
  133. data/lib/active_record/encryption/contexts.rb +76 -0
  134. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  135. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  136. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  137. data/lib/active_record/encryption/encrypted_attribute_type.rb +155 -0
  138. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  139. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  140. data/lib/active_record/encryption/encryptor.rb +155 -0
  141. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  142. data/lib/active_record/encryption/errors.rb +15 -0
  143. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  144. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  145. data/lib/active_record/encryption/key.rb +28 -0
  146. data/lib/active_record/encryption/key_generator.rb +53 -0
  147. data/lib/active_record/encryption/key_provider.rb +46 -0
  148. data/lib/active_record/encryption/message.rb +33 -0
  149. data/lib/active_record/encryption/message_serializer.rb +92 -0
  150. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  151. data/lib/active_record/encryption/properties.rb +76 -0
  152. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  153. data/lib/active_record/encryption/scheme.rb +100 -0
  154. data/lib/active_record/encryption.rb +58 -0
  155. data/lib/active_record/enum.rb +154 -63
  156. data/lib/active_record/errors.rb +172 -15
  157. data/lib/active_record/explain.rb +23 -3
  158. data/lib/active_record/explain_registry.rb +11 -6
  159. data/lib/active_record/explain_subscriber.rb +1 -1
  160. data/lib/active_record/fixture_set/file.rb +15 -1
  161. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  162. data/lib/active_record/fixture_set/render_context.rb +2 -0
  163. data/lib/active_record/fixture_set/table_row.rb +70 -14
  164. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  165. data/lib/active_record/fixtures.rb +147 -86
  166. data/lib/active_record/future_result.rb +174 -0
  167. data/lib/active_record/gem_version.rb +3 -3
  168. data/lib/active_record/inheritance.rb +81 -29
  169. data/lib/active_record/insert_all.rb +135 -22
  170. data/lib/active_record/integration.rb +11 -10
  171. data/lib/active_record/internal_metadata.rb +119 -33
  172. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  173. data/lib/active_record/locking/optimistic.rb +37 -22
  174. data/lib/active_record/locking/pessimistic.rb +15 -6
  175. data/lib/active_record/log_subscriber.rb +52 -19
  176. data/lib/active_record/marshalling.rb +59 -0
  177. data/lib/active_record/message_pack.rb +124 -0
  178. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  179. data/lib/active_record/middleware/database_selector.rb +23 -13
  180. data/lib/active_record/middleware/shard_selector.rb +62 -0
  181. data/lib/active_record/migration/command_recorder.rb +112 -14
  182. data/lib/active_record/migration/compatibility.rb +233 -46
  183. data/lib/active_record/migration/default_strategy.rb +23 -0
  184. data/lib/active_record/migration/execution_strategy.rb +19 -0
  185. data/lib/active_record/migration/join_table.rb +1 -1
  186. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  187. data/lib/active_record/migration.rb +361 -173
  188. data/lib/active_record/model_schema.rb +125 -101
  189. data/lib/active_record/nested_attributes.rb +50 -20
  190. data/lib/active_record/no_touching.rb +3 -3
  191. data/lib/active_record/normalization.rb +167 -0
  192. data/lib/active_record/persistence.rb +409 -88
  193. data/lib/active_record/promise.rb +84 -0
  194. data/lib/active_record/query_cache.rb +4 -22
  195. data/lib/active_record/query_logs.rb +174 -0
  196. data/lib/active_record/query_logs_formatter.rb +41 -0
  197. data/lib/active_record/querying.rb +29 -6
  198. data/lib/active_record/railtie.rb +220 -44
  199. data/lib/active_record/railties/controller_runtime.rb +15 -10
  200. data/lib/active_record/railties/databases.rake +188 -252
  201. data/lib/active_record/railties/job_runtime.rb +23 -0
  202. data/lib/active_record/readonly_attributes.rb +41 -3
  203. data/lib/active_record/reflection.rb +248 -81
  204. data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
  205. data/lib/active_record/relation/batches.rb +192 -63
  206. data/lib/active_record/relation/calculations.rb +246 -90
  207. data/lib/active_record/relation/delegation.rb +28 -14
  208. data/lib/active_record/relation/finder_methods.rb +108 -51
  209. data/lib/active_record/relation/merger.rb +22 -13
  210. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  211. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  212. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  213. data/lib/active_record/relation/predicate_builder.rb +27 -20
  214. data/lib/active_record/relation/query_attribute.rb +30 -12
  215. data/lib/active_record/relation/query_methods.rb +670 -129
  216. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  217. data/lib/active_record/relation/spawn_methods.rb +20 -3
  218. data/lib/active_record/relation/where_clause.rb +10 -19
  219. data/lib/active_record/relation.rb +287 -120
  220. data/lib/active_record/result.rb +37 -11
  221. data/lib/active_record/runtime_registry.rb +32 -13
  222. data/lib/active_record/sanitization.rb +65 -20
  223. data/lib/active_record/schema.rb +36 -22
  224. data/lib/active_record/schema_dumper.rb +73 -24
  225. data/lib/active_record/schema_migration.rb +68 -33
  226. data/lib/active_record/scoping/default.rb +72 -15
  227. data/lib/active_record/scoping/named.rb +5 -13
  228. data/lib/active_record/scoping.rb +65 -34
  229. data/lib/active_record/secure_password.rb +60 -0
  230. data/lib/active_record/secure_token.rb +21 -3
  231. data/lib/active_record/serialization.rb +6 -1
  232. data/lib/active_record/signed_id.rb +10 -8
  233. data/lib/active_record/store.rb +10 -10
  234. data/lib/active_record/suppressor.rb +13 -15
  235. data/lib/active_record/table_metadata.rb +16 -3
  236. data/lib/active_record/tasks/database_tasks.rb +251 -140
  237. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  238. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  239. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  240. data/lib/active_record/test_databases.rb +1 -1
  241. data/lib/active_record/test_fixtures.rb +117 -96
  242. data/lib/active_record/timestamp.rb +32 -19
  243. data/lib/active_record/token_for.rb +113 -0
  244. data/lib/active_record/touch_later.rb +11 -6
  245. data/lib/active_record/transactions.rb +48 -27
  246. data/lib/active_record/translation.rb +3 -3
  247. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  248. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  249. data/lib/active_record/type/internal/timezone.rb +7 -2
  250. data/lib/active_record/type/serialized.rb +9 -5
  251. data/lib/active_record/type/time.rb +4 -0
  252. data/lib/active_record/type/type_map.rb +17 -20
  253. data/lib/active_record/type.rb +1 -2
  254. data/lib/active_record/validations/absence.rb +1 -1
  255. data/lib/active_record/validations/associated.rb +4 -4
  256. data/lib/active_record/validations/numericality.rb +5 -4
  257. data/lib/active_record/validations/presence.rb +5 -28
  258. data/lib/active_record/validations/uniqueness.rb +51 -6
  259. data/lib/active_record/validations.rb +8 -4
  260. data/lib/active_record/version.rb +1 -1
  261. data/lib/active_record.rb +335 -32
  262. data/lib/arel/attributes/attribute.rb +0 -8
  263. data/lib/arel/crud.rb +28 -22
  264. data/lib/arel/delete_manager.rb +18 -4
  265. data/lib/arel/errors.rb +10 -0
  266. data/lib/arel/factory_methods.rb +4 -0
  267. data/lib/arel/filter_predications.rb +9 -0
  268. data/lib/arel/insert_manager.rb +2 -3
  269. data/lib/arel/nodes/and.rb +4 -0
  270. data/lib/arel/nodes/binary.rb +6 -1
  271. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  272. data/lib/arel/nodes/casted.rb +1 -1
  273. data/lib/arel/nodes/cte.rb +36 -0
  274. data/lib/arel/nodes/delete_statement.rb +12 -13
  275. data/lib/arel/nodes/filter.rb +10 -0
  276. data/lib/arel/nodes/fragments.rb +35 -0
  277. data/lib/arel/nodes/function.rb +1 -0
  278. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  279. data/lib/arel/nodes/insert_statement.rb +2 -2
  280. data/lib/arel/nodes/leading_join.rb +8 -0
  281. data/lib/arel/nodes/node.rb +111 -2
  282. data/lib/arel/nodes/select_core.rb +2 -2
  283. data/lib/arel/nodes/select_statement.rb +2 -2
  284. data/lib/arel/nodes/sql_literal.rb +6 -0
  285. data/lib/arel/nodes/table_alias.rb +4 -0
  286. data/lib/arel/nodes/update_statement.rb +8 -3
  287. data/lib/arel/nodes.rb +5 -0
  288. data/lib/arel/predications.rb +13 -3
  289. data/lib/arel/select_manager.rb +10 -4
  290. data/lib/arel/table.rb +9 -6
  291. data/lib/arel/tree_manager.rb +5 -13
  292. data/lib/arel/update_manager.rb +18 -4
  293. data/lib/arel/visitors/dot.rb +80 -90
  294. data/lib/arel/visitors/mysql.rb +16 -3
  295. data/lib/arel/visitors/postgresql.rb +0 -10
  296. data/lib/arel/visitors/to_sql.rb +141 -20
  297. data/lib/arel/visitors/visitor.rb +2 -2
  298. data/lib/arel.rb +18 -3
  299. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  300. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  301. data/lib/rails/generators/active_record/migration.rb +3 -1
  302. data/lib/rails/generators/active_record/model/USAGE +113 -0
  303. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  304. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  305. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  306. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  307. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  308. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  309. metadata +96 -16
  310. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  311. data/lib/active_record/null_relation.rb +0 -67
data/CHANGELOG.md CHANGED
@@ -1,1767 +1,2777 @@
1
- ## Rails 6.1.7 (September 09, 2022) ##
1
+ ## Rails 7.1.5 (October 30, 2024) ##
2
2
 
3
- * Symbol is allowed by default for YAML columns
3
+ * Fix marshalling of unsaved associated records in 7.1 format.
4
4
 
5
- *Étienne Barrié*
6
-
7
- * Fix `ActiveRecord::Store` to serialize as a regular Hash
8
-
9
- Previously it would serialize as an `ActiveSupport::HashWithIndifferentAccess`
10
- which is wasteful and cause problem with YAML safe_load.
5
+ The 7.1 format would only marshal associated records if the association was loaded.
6
+ But associations that would only contain unsaved records would be skipped.
11
7
 
12
8
  *Jean Boussier*
13
9
 
14
- * Fix PG.connect keyword arguments deprecation warning on ruby 2.7
15
-
16
- Fixes #44307.
10
+ * Fix an issue where `.left_outer_joins` used with multiple associations that have
11
+ the same child association but different parents does not join all parents.
17
12
 
18
- *Nikita Vasilevsky*
13
+ Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
19
14
 
20
- ## Rails 6.1.6.1 (July 12, 2022) ##
15
+ Now it will correctly join both parents.
21
16
 
22
- * Change ActiveRecord::Coders::YAMLColumn default to safe_load
17
+ Fixes #41498.
23
18
 
24
- This adds two new configuration options The configuration options are as
25
- follows:
26
-
27
- * `config.active_storage.use_yaml_unsafe_load`
28
-
29
- When set to true, this configuration option tells Rails to use the old
30
- "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
31
- the possible escalation vulnerability in place. Setting this option to true
32
- is *not* recommended, but can aid in upgrading.
33
-
34
- * `config.active_record.yaml_column_permitted_classes`
35
-
36
- The "safe YAML" loading method does not allow all classes to be deserialized
37
- by default. This option allows you to specify classes deemed "safe" in your
38
- application. For example, if your application uses Symbol and Time in
39
- serialized data, you can add Symbol and Time to the allowed list as follows:
40
-
41
- ```
42
- config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
43
- ```
19
+ *Garrett Blehm*
44
20
 
45
- [CVE-2022-32224]
21
+ * Ensure `ActiveRecord::Encryption.config` is always ready before access.
46
22
 
23
+ Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
24
+ was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
25
+ `ActiveRecord::Base` was loaded would give incorrect results.
47
26
 
48
- ## Rails 6.1.6 (May 09, 2022) ##
27
+ `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
28
+ soon as needed.
49
29
 
50
- * No changes.
30
+ When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
31
+ `ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
32
+ before any use of `ActiveRecord::Base`.
51
33
 
34
+ *Maxime Réty*
52
35
 
53
- ## Rails 6.1.5.1 (April 26, 2022) ##
36
+ * Add `TimeZoneConverter#==` method, so objects will be properly compared by
37
+ their type, scale, limit & precision.
54
38
 
55
- * No changes.
39
+ Address #52699.
56
40
 
41
+ *Ruy Rocha*
57
42
 
58
- ## Rails 6.1.5 (March 09, 2022) ##
59
43
 
60
- * Fix `ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate` for Ruby 2.6.
44
+ ## Rails 7.1.4.2 (October 23, 2024) ##
61
45
 
62
- Ruby 2.6 and 2.7 have slightly different implementations of the `String#-@` method.
63
- In Ruby 2.6, the receiver of the `String#-@` method is modified under certain circumstances.
64
- This was later identified as a bug (https://bugs.ruby-lang.org/issues/15926) and only
65
- fixed in Ruby 2.7.
46
+ * No changes.
66
47
 
67
- Before the changes in this commit, the
68
- `ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate` method, which internally
69
- calls the `String#-@` method, could also modify an input string argument in Ruby 2.6 --
70
- changing a tainted, unfrozen string into a tainted, frozen string.
71
48
 
72
- Fixes #43056
49
+ ## Rails 7.1.4.1 (October 15, 2024) ##
73
50
 
74
- *Eric O'Hanlon*
51
+ * No changes.
75
52
 
76
- * Fix migration compatibility to create SQLite references/belongs_to column as integer when
77
- migration version is 6.0.
78
53
 
79
- `reference`/`belongs_to` in migrations with version 6.0 were creating columns as
80
- bigint instead of integer for the SQLite Adapter.
54
+ ## Rails 7.1.4 (August 22, 2024) ##
81
55
 
82
- *Marcelo Lauxen*
56
+ * Allow to eager load nested nil associations.
83
57
 
84
- * Fix dbconsole for 3-tier config.
58
+ *fatkodima*
85
59
 
86
- *Eileen M. Uchitelle*
60
+ * Fix `create_table` with `:auto_increment` option for MySQL adapter.
87
61
 
88
- * Better handle SQL queries with invalid encoding.
62
+ *fatkodima*
89
63
 
90
- ```ruby
91
- Post.create(name: "broken \xC8 UTF-8")
92
- ```
64
+ * Don't load has_one associations during autosave.
93
65
 
94
- Would cause all adapters to fail in a non controlled way in the code
95
- responsible to detect write queries.
66
+ *Eugene Kenny*
96
67
 
97
- The query is now properly passed to the database connection, which might or might
98
- not be able to handle it, but will either succeed or failed in a more correct way.
68
+ * Fix migration ordering for `bin/rails db:prepare` across databases.
99
69
 
100
- *Jean Boussier*
70
+ *fatkodima*
101
71
 
102
- * Ignore persisted in-memory records when merging target lists.
72
+ * Fix `alias_attribute` to ignore methods defined in parent classes.
103
73
 
104
- *Kevin Sjöberg*
74
+ *Jean Boussier*
105
75
 
106
- * Fix regression bug that caused ignoring additional conditions for preloading
107
- `has_many` through relations.
76
+ * Fix a performance regression in attribute methods.
108
77
 
109
- Fixes #43132
78
+ *Jean Boussier*
110
79
 
111
- *Alexander Pauly*
80
+ * Fix Active Record configs variable shadowing.
112
81
 
113
- * Fix `ActiveRecord::InternalMetadata` to not be broken by
114
- `config.active_record.record_timestamps = false`
82
+ *Joel Lubrano*
115
83
 
116
- Since the model always create the timestamp columns, it has to set them, otherwise it breaks
117
- various DB management tasks.
84
+ * Fix running migrations on other databases when `database_tasks: false` on primary.
118
85
 
119
- Fixes #42983
86
+ *fatkodima*
120
87
 
121
- *Jean Boussier*
88
+ * Fix non-partial inserts for models with composite identity primary keys.
122
89
 
123
- * Fix duplicate active record objects on `inverse_of`.
90
+ *fatkodima*
124
91
 
125
- *Justin Carvalho*
92
+ * Fix `ActiveRecord::Relation#touch_all` with custom attribute aliased as attribute for update.
126
93
 
127
- * Fix duplicate objects stored in has many association after save.
94
+ *fatkodima*
128
95
 
129
- Fixes #42549.
96
+ * Fix a crash when an Executor wrapped fork exit.
130
97
 
131
- *Alex Ghiculescu*
98
+ *Joé Dupuis*
132
99
 
133
- * Fix performance regression in `CollectionAssocation#build`.
100
+ * Fix `destroy_async` job for owners with composite primary keys.
134
101
 
135
- *Alex Ghiculescu*
102
+ *fatkodima*
136
103
 
137
- * Fix retrieving default value for text column for MariaDB.
104
+ * Ensure pre-7.1 migrations use legacy index names when using `rename_table`.
138
105
 
139
106
  *fatkodima*
140
107
 
108
+ * Allow `primary_key:` association option to be composite.
141
109
 
142
- ## Rails 6.1.4.7 (March 08, 2022) ##
143
-
144
- * No changes.
110
+ *Nikita Vasilevsky*
145
111
 
112
+ * Do not try to alias on key update when raw SQL is supplied.
146
113
 
147
- ## Rails 6.1.4.6 (February 11, 2022) ##
114
+ *Gabriel Amaral*
148
115
 
149
- * No changes.
116
+ * Memoize `key_provider` from `key` or deterministic `key_provider` if any.
150
117
 
118
+ *Rosa Gutierrez*
151
119
 
152
- ## Rails 6.1.4.5 (February 11, 2022) ##
120
+ * Fix `upsert` warning for MySQL.
153
121
 
154
- * No changes.
122
+ *fatkodima*
155
123
 
124
+ * Fix predicate builder for polymorphic models referencing models with composite primary keys.
156
125
 
157
- ## Rails 6.1.4.4 (December 15, 2021) ##
126
+ *fatkodima*
158
127
 
159
- * No changes.
128
+ * Fix `update_all/delete_all` on CPK model relation with join subquery.
160
129
 
130
+ *Nikita Vasilevsky*
161
131
 
162
- ## Rails 6.1.4.3 (December 14, 2021) ##
132
+ * Remove memoization to accept `key_provider` overridden by `with_encryption_context`.
163
133
 
164
- * No changes.
134
+ *John Hawthorn*
165
135
 
136
+ * Raise error for Trilogy when prepared_statements is true.
166
137
 
167
- ## Rails 6.1.4.2 (December 14, 2021) ##
138
+ Trilogy doesn't currently support prepared statements. The error that
139
+ applications would see is a `StatementInvalid` error. This doesn't quite point
140
+ you to the fact this isn't supported. So raise a more appropriate error
141
+ pointing to what to change.
168
142
 
169
- * No changes.
143
+ *Eileen M. Uchitelle*
170
144
 
145
+ * Fix loading schema cache when all databases have disabled database tasks.
171
146
 
172
- ## Rails 6.1.4.1 (August 19, 2021) ##
147
+ *fatkodima*
173
148
 
174
- * No changes.
149
+ * Always request `primary_key` in `RETURNING` if no other columns requested.
175
150
 
151
+ *Nikita Vasilevsky*
176
152
 
177
- ## Rails 6.1.4 (June 24, 2021) ##
153
+ * Handle records being loaded with Marshal without triggering schema load
178
154
 
179
- * Do not try to rollback transactions that failed due to a `ActiveRecord::TransactionRollbackError`.
155
+ When using the old marshalling format for Active Record and loading
156
+ a serialized instance, it didn't trigger loading the schema and defining
157
+ attribute methods.
180
158
 
181
- *Jamie McCarthy*
159
+ *Jean Boussier*
182
160
 
183
- * Raise an error if `pool_config` is `nil` in `set_pool_config`.
161
+ * Prevent some constant redefinition warnings when defining `inherited` on models.
184
162
 
185
- *Eileen M. Uchitelle*
163
+ *Adrian Hirt*
186
164
 
187
- * Fix compatibility with `psych >= 4`.
165
+ * Fix a memory perfomance regression in attribute methods.
188
166
 
189
- Starting in Psych 4.0.0 `YAML.load` behaves like `YAML.safe_load`. To preserve compatibility
190
- Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
167
+ Attribute methods used much more memory and were slower to define than
168
+ they should have been.
191
169
 
192
170
  *Jean Boussier*
193
171
 
194
- * Support using replicas when using `rails dbconsole`.
172
+ * Fix an issue that could cause database connection leaks.
195
173
 
196
- *Christopher Thornton*
174
+ If Active Record successfully connected to the database, but then failed
175
+ to read the server informations, the connection would be leaked until the
176
+ Ruby garbage collector triggers.
197
177
 
198
- * Restore connection pools after transactional tests.
199
-
200
- *Eugene Kenny*
178
+ *Jean Boussier*
201
179
 
202
- * Change `upsert_all` to fails cleanly for MySQL when `:unique_by` is used.
180
+ * Fix an issue where the IDs reader method did not return expected results
181
+ for preloaded associations in models using composite primary keys.
203
182
 
204
- *Bastian Bartmann*
183
+ *Jay Ang*
205
184
 
206
- * Fix user-defined `self.default_scope` to respect table alias.
185
+ * PostgreSQL `Cidr#change?` detects the address prefix change.
207
186
 
208
- *Ryuta Kamizono*
187
+ *Taketo Takashima*
209
188
 
210
- * Clear `@cache_keys` cache after `update_all`, `delete_all`, `destroy_all`.
189
+ * Fix Active Record serialization to not include instantiated but not loaded associations
211
190
 
212
- *Ryuta Kamizono*
191
+ *Jean Boussier*, *Ben Kyriakou*
213
192
 
214
- * Changed Arel predications `contains` and `overlaps` to use
215
- `quoted_node` so that PostgreSQL arrays are quoted properly.
193
+ * Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`
216
194
 
217
- *Bradley Priest*
195
+ *Mike Dalessio*
218
196
 
219
- * Fix `merge` when the `where` clauses have string contents.
197
+ * Strict loading using `:n_plus_one_only` does not eagerly load child associations.
220
198
 
221
- *Ryuta Kamizono*
199
+ With this change, child associations are no longer eagerly loaded, to
200
+ match intended behavior and to prevent non-deterministic order issues caused
201
+ by calling methods like `first` or `last`. As `first` and `last` don't cause
202
+ an N+1 by themselves, calling child associations will no longer raise.
203
+ Fixes #49473.
222
204
 
223
- * Fix rollback of parent destruction with nested `dependent: :destroy`.
205
+ Before:
224
206
 
225
- *Jacopo Beschi*
207
+ ```ruby
208
+ person = Person.find(1)
209
+ person.strict_loading!(mode: :n_plus_one_only)
210
+ person.posts.first
211
+ # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
212
+ person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
213
+ ```
226
214
 
227
- * Fix binds logging for `"WHERE ... IN ..."` statements.
215
+ After:
228
216
 
229
- *Ricardo Díaz*
217
+ ```ruby
218
+ person = Person.find(1)
219
+ person.strict_loading!(mode: :n_plus_one_only)
220
+ person.posts.first # this is 1+1, not N+1
221
+ # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
222
+ person.posts.first.firm # no longer raises
223
+ ```
230
224
 
231
- * Handle `false` in relation strict loading checks.
225
+ *Reid Lynch*
232
226
 
233
- Previously when a model had strict loading set to true and then had a
234
- relation set `strict_loading` to false the false wasn't considered when
235
- deciding whether to raise/warn about strict loading.
227
+ * Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
228
+ incorrect error message. This has been fixed to raise with a more appropriate error message.
236
229
 
237
- ```
238
- class Dog < ActiveRecord::Base
239
- self.strict_loading_by_default = true
230
+ *Joshua Young*
240
231
 
241
- has_many :treats, strict_loading: false
242
- end
243
- ```
232
+ * Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
244
233
 
245
- In the example, `dog.treats` would still raise even though
246
- `strict_loading` was set to false. This is a bug affecting more than
247
- Active Storage which is why I made this PR superseding #41461. We need
248
- to fix this for all applications since the behavior is a little
249
- surprising. I took the test from #41461 and the code suggestion from #41453
250
- with some additions.
234
+ This behaviour is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
235
+ an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
251
236
 
252
- *Eileen M. Uchitelle*, *Radamés Roriz*
237
+ *Joshua Young*
253
238
 
254
- * Fix numericality validator without precision.
239
+ * Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
240
+ of Active Record models, when an application is eager loaded. As a result, encrypted attributes
241
+ could be misconfigured in some cases.
255
242
 
256
- *Ryuta Kamizono*
243
+ *Maxime Réty*
257
244
 
258
- * Fix aggregate attribute on Enum types.
245
+ * Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`
259
246
 
260
- *Ryuta Kamizono*
247
+ As well as `disconnect!` and `verify!`.
261
248
 
262
- * Fix `CREATE INDEX` statement generation for PostgreSQL.
249
+ This generally isn't a big problem as connections must not be shared between
250
+ threads, but is required when running transactional tests or system tests
251
+ and could lead to a SEGV.
263
252
 
264
- *eltongo*
253
+ *Jean Boussier*
265
254
 
266
- * Fix where clause on enum attribute when providing array of strings.
255
+ * Fix counter caches when the foreign key is composite.
267
256
 
268
- *Ryuta Kamizono*
257
+ If the model holding the counter cache had a composite primary key,
258
+ inserting a dependent record would fail with an `ArgumentError`
259
+ `Expected corresponding value for...`
269
260
 
270
- * Fix `unprepared_statement` to work it when nesting.
261
+ *fatkodima*
271
262
 
272
- *Ryuta Kamizono*
263
+ * Fix loading of schema cache for multiple databases.
273
264
 
265
+ Before this change, if you have multiple databases configured in your
266
+ application, and had schema cache present, Rails would load the same
267
+ cache to all databases.
274
268
 
275
- ## Rails 6.1.3.2 (May 05, 2021) ##
269
+ *Rafael Mendonça França*
276
270
 
277
- * No changes.
271
+ * Fix eager loading of composite primary key associations.
278
272
 
273
+ `relation.eager_load(:other_model)` could load the wrong records if `other_model`
274
+ had a composite primary key.
279
275
 
280
- ## Rails 6.1.3.1 (March 26, 2021) ##
276
+ *Nikita Vasilevsky*
281
277
 
282
- * No changes.
278
+ * Fix async queries returning a doubly wrapped result when hitting the query cache.
283
279
 
280
+ *fatkodima*
284
281
 
285
- ## Rails 6.1.3 (February 17, 2021) ##
282
+ * Fix single quote escapes on default generated MySQL columns
286
283
 
287
- * Fix the MySQL adapter to always set the right collation and charset
288
- to the connection session.
284
+ MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
289
285
 
290
- *Rafael Mendonça França*
286
+ Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
291
287
 
292
- * Fix MySQL adapter handling of time objects when prepared statements
293
- are enabled.
288
+ This would result in issues when importing the schema on a fresh instance of a MySQL database.
294
289
 
295
- *Rafael Mendonça França*
290
+ Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
296
291
 
297
- * Fix scoping in enum fields using conditions that would generate
298
- an `IN` clause.
292
+ *Yash Kapadia*
299
293
 
300
- *Ryuta Kamizono*
294
+ * Fix Migrations with versions older than 7.1 validating options given to
295
+ `t.references`.
301
296
 
302
- * Skip optimised #exist? query when #include? is called on a relation
303
- with a having clause
297
+ *Hartley McGuire*
304
298
 
305
- Relations that have aliased select values AND a having clause that
306
- references an aliased select value would generate an error when
307
- #include? was called, due to an optimisation that would generate
308
- call #exists? on the relation instead, which effectively alters
309
- the select values of the query (and thus removes the aliased select
310
- values), but leaves the having clause intact. Because the having
311
- clause is then referencing an aliased column that is no longer
312
- present in the simplified query, an ActiveRecord::InvalidStatement
313
- error was raised.
314
299
 
315
- An sample query affected by this problem:
300
+ ## Rails 7.1.3.4 (June 04, 2024) ##
316
301
 
317
- ```ruby
318
- Author.select('COUNT(*) as total_posts', 'authors.*')
319
- .joins(:posts)
320
- .group(:id)
321
- .having('total_posts > 2')
322
- .include?(Author.first)
323
- ```
302
+ * No changes.
324
303
 
325
- This change adds an addition check to the condition that skips the
326
- simplified #exists? query, which simply checks for the presence of
327
- a having clause.
328
304
 
329
- Fixes #41417
305
+ ## Rails 7.1.3.3 (May 16, 2024) ##
330
306
 
331
- *Michael Smart*
307
+ * No changes.
332
308
 
333
- * Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
334
- without Rails knowledge (e.g., if app gets kill -9d during long-running query or due to Rack::Timeout), app won't end
335
- up in perpetual crash state for being inconsistent with Postgres.
336
309
 
337
- *wbharding*, *Martin Tepper*
310
+ ## Rails 7.1.3.2 (February 21, 2024) ##
338
311
 
312
+ * No changes.
339
313
 
340
- ## Rails 6.1.2.1 (February 10, 2021) ##
341
314
 
342
- * Fix possible DoS vector in PostgreSQL money type
315
+ ## Rails 7.1.3.1 (February 21, 2024) ##
343
316
 
344
- Carefully crafted input can cause a DoS via the regular expressions used
345
- for validating the money format in the PostgreSQL adapter. This patch
346
- fixes the regexp.
317
+ * No changes.
347
318
 
348
- Thanks to @dee-see from Hackerone for this patch!
349
319
 
350
- [CVE-2021-22880]
320
+ ## Rails 7.1.3 (January 16, 2024) ##
351
321
 
352
- *Aaron Patterson*
322
+ * Fix Migrations with versions older than 7.1 validating options given to
323
+ `add_reference`.
353
324
 
325
+ *Hartley McGuire*
354
326
 
355
- ## Rails 6.1.2 (February 09, 2021) ##
327
+ * Ensure `reload` sets correct owner for each association.
356
328
 
357
- * Fix timestamp type for sqlite3.
329
+ *Dmytro Savochkin*
358
330
 
359
- *Eileen M. Uchitelle*
331
+ * Fix view runtime for controllers with async queries.
360
332
 
361
- * Make destroy async transactional.
333
+ *fatkodima*
362
334
 
363
- An active record rollback could occur while enqueuing a job. In this
364
- case the job would enqueue even though the database deletion
365
- rolledback putting things in a funky state.
335
+ * Fix `load_async` to work with query cache.
366
336
 
367
- Now the jobs are only enqueued until after the db transaction has been committed.
337
+ *fatkodima*
368
338
 
369
- *Cory Gwin*
339
+ * Fix polymorphic `belongs_to` to correctly use parent's `query_constraints`.
370
340
 
371
- * Fix malformed packet error in MySQL statement for connection configuration.
341
+ *fatkodima*
372
342
 
373
- *robinroestenburg*
343
+ * Fix `Preloader` to not generate a query for already loaded association with `query_constraints`.
374
344
 
375
- * Connection specification now passes the "url" key as a configuration for the
376
- adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
377
- urls with the "jdbc" prefix were passed to the Active Record Adapter, others
378
- are assumed to be adapter specification urls.
345
+ *fatkodima*
379
346
 
380
- Fixes #41137.
347
+ * Fix multi-database polymorphic preloading with equivalent table names.
381
348
 
382
- *Jonathan Bracy*
349
+ When preloading polymorphic associations, if two models pointed to two
350
+ tables with the same name but located in different databases, the
351
+ preloader would only load one.
383
352
 
384
- * Fix granular connection swapping when there are multiple abstract classes.
353
+ *Ari Summer*
385
354
 
386
- *Eileen M. Uchitelle*
355
+ * Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
387
356
 
388
- * Fix `find_by` with custom primary key for belongs_to association.
357
+ *Maxime Réty*
389
358
 
390
- *Ryuta Kamizono*
359
+ * Fix `find_by` to work correctly in presence of composite primary keys.
391
360
 
392
- * Add support for `rails console --sandbox` for multiple database applications.
361
+ *fatkodima*
393
362
 
394
- *alpaca-tc*
363
+ * Fix async queries sometimes returning a raw result if they hit the query cache.
395
364
 
396
- * Fix `where` on polymorphic association with empty array.
365
+ `ShipPart.async_count` could return a raw integer rather than a Promise
366
+ if it found the result in the query cache.
397
367
 
398
- *Ryuta Kamizono*
368
+ *fatkodima*
399
369
 
400
- * Fix preventing writes for `ApplicationRecord`.
370
+ * Fix `Relation#transaction` to not apply a default scope.
401
371
 
402
- *Eileen M. Uchitelle*
372
+ The method was incorrectly setting a default scope around its block:
403
373
 
374
+ ```ruby
375
+ Post.where(published: true).transaction do
376
+ Post.count # SELECT COUNT(*) FROM posts WHERE published = FALSE;
377
+ end
378
+ ```
404
379
 
405
- ## Rails 6.1.1 (January 07, 2021) ##
380
+ *Jean Boussier*
406
381
 
407
- * Fix fixtures loading when strict loading is enabled for the association.
382
+ * Fix calling `async_pluck` on a `none` relation.
408
383
 
409
- *Alex Ghiculescu*
384
+ `Model.none.async_pluck(:id)` was returning a naked value
385
+ instead of a promise.
410
386
 
411
- * Fix `where` with custom primary key for belongs_to association.
387
+ *Jean Boussier*
412
388
 
413
- *Ryuta Kamizono*
389
+ * Fix calling `load_async` on a `none` relation.
414
390
 
415
- * Fix `where` with aliased associations.
391
+ `Model.none.load_async` was returning a broken result.
416
392
 
417
- *Ryuta Kamizono*
393
+ *Lucas Mazza*
418
394
 
419
- * Fix `composed_of` with symbol mapping.
395
+ * TrilogyAdapter: ignore `host` if `socket` parameter is set.
420
396
 
421
- *Ryuta Kamizono*
397
+ This allows to configure a connection on a UNIX socket via DATABASE_URL:
422
398
 
423
- * Don't skip money's type cast for pluck and calculations.
399
+ ```
400
+ DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
401
+ ```
424
402
 
425
- *Ryuta Kamizono*
403
+ *Jean Boussier*
426
404
 
427
- * Fix `where` on polymorphic association with non Active Record object.
405
+ * Fix `has_secure_token` calls the setter method on initialize.
428
406
 
429
- *Ryuta Kamizono*
407
+ *Abeid Ahmed*
430
408
 
431
- * Make sure `db:prepare` works even the schema file doesn't exist.
409
+ * Allow using `object_id` as a database column name.
410
+ It was available before rails 7.1 and may be used as a part of polymorphic relationship to `object` where `object` can be any other database record.
432
411
 
433
- *Rafael Mendonça França*
412
+ *Mikhail Doronin*
434
413
 
435
- * Fix complicated `has_many :through` with nested where condition.
414
+ * Fix `rails db:create:all` to not touch databases before they are created.
436
415
 
437
- *Ryuta Kamizono*
416
+ *fatkodima*
438
417
 
439
- * Handle STI models for `has_many dependent: :destroy_async`.
440
418
 
441
- *Muhammad Usman*
419
+ ## Rails 7.1.2 (November 10, 2023) ##
442
420
 
443
- * Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
421
+ * Fix renaming primary key index when renaming a table with a UUID primary key
422
+ in PostgreSQL.
444
423
 
445
- Previously, passing `false` would trigger the option validation logic
446
- to throw an error saying :polymorphic would not be a valid option.
424
+ *fatkodima*
447
425
 
448
- *glaszig*
426
+ * Fix `where(field: values)` queries when `field` is a serialized attribute
427
+ (for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
428
+ column).
449
429
 
450
- * Allow adding nonnamed expression indexes to be revertible.
430
+ *João Alves*
451
431
 
452
- Fixes #40732.
432
+ * Prevent marking broken connections as verified.
453
433
 
454
- Previously, the following code would raise an error, when executed while rolling back,
455
- and the index name should be specified explicitly. Now, the index name is inferred
456
- automatically.
434
+ *Daniel Colson*
457
435
 
458
- ```ruby
459
- add_index(:items, "to_tsvector('english', description)")
460
- ```
436
+ * Don't mark Float::INFINITY as changed when reassigning it
461
437
 
462
- *fatkodima*
438
+ When saving a record with a float infinite value, it shouldn't mark as changed
463
439
 
440
+ *Maicol Bentancor*
464
441
 
465
- ## Rails 6.1.0 (December 09, 2020) ##
442
+ * `ActiveRecord::Base.table_name` now returns `nil` instead of raising
443
+ "undefined method `abstract_class?` for Object:Class".
466
444
 
467
- * Only warn about negative enums if a positive form that would cause conflicts exists.
445
+ *a5-stable*
468
446
 
469
- Fixes #39065.
447
+ * Fix upserting for custom `:on_duplicate` and `:unique_by` consisting of all
448
+ inserts keys.
470
449
 
471
- *Alex Ghiculescu*
450
+ *fatkodima*
472
451
 
473
- * Change `attribute_for_inspect` to take `filter_attributes` in consideration.
452
+ * Fixed an [issue](https://github.com/rails/rails/issues/49809) where saving a
453
+ record could innappropriately `dup` its attributes.
474
454
 
475
- *Rafael Mendonça França*
455
+ *Jonathan Hefner*
476
456
 
477
- * Fix odd behavior of inverse_of with multiple belongs_to to same class.
457
+ * Dump schema only for a specific db for rollback/up/down tasks for multiple dbs.
478
458
 
479
- Fixes #35204.
459
+ *fatkodima*
480
460
 
481
- *Tomoyuki Kai*
461
+ * Fix `NoMethodError` when casting a PostgreSQL `money` value that uses a
462
+ comma as its radix point and has no leading currency symbol. For example,
463
+ when casting `"3,50"`.
482
464
 
483
- * Build predicate conditions with objects that delegate `#id` and primary key:
465
+ *Andreas Reischuck* and *Jonathan Hefner*
484
466
 
485
- ```ruby
486
- class AdminAuthor
487
- delegate_missing_to :@author
467
+ * Re-enable support for using `enum` with non-column-backed attributes.
468
+ Non-column-backed attributes must be previously declared with an explicit
469
+ type. For example:
488
470
 
489
- def initialize(author)
490
- @author = author
471
+ ```ruby
472
+ class Post < ActiveRecord::Base
473
+ attribute :topic, :string
474
+ enum topic: %i[science tech engineering math]
491
475
  end
492
- end
493
-
494
- Post.where(author: AdminAuthor.new(author))
495
- ```
476
+ ```
496
477
 
497
- *Sean Doyle*
478
+ *Jonathan Hefner*
498
479
 
499
- * Add `connected_to_many` API.
480
+ * Raise on `foreign_key:` being passed as an array in associations
500
481
 
501
- This API allows applications to connect to multiple databases at once without switching all of them or implementing a deeply nested stack.
482
+ *Nikita Vasilevsky*
502
483
 
503
- Before:
484
+ * Return back maximum allowed PostgreSQL table name to 63 characters.
504
485
 
505
- AnimalsRecord.connected_to(role: :reading) do
506
- MealsRecord.connected_to(role: :reading) do
507
- Dog.first # read from animals replica
508
- Dinner.first # read from meals replica
509
- Person.first # read from primary writer
510
- end
511
- end
486
+ *fatkodima*
512
487
 
513
- After:
488
+ * Fix detecting `IDENTITY` columns for PostgreSQL < 10.
514
489
 
515
- ActiveRecord::Base.connected_to_many([AnimalsRecord, MealsRecord], role: :reading) do
516
- Dog.first # read from animals replica
517
- Dinner.first # read from meals replica
518
- Person.first # read from primary writer
519
- end
490
+ *fatkodima*
520
491
 
521
- *Eileen M. Uchitelle*, *John Crepezzi*
522
492
 
523
- * Add option to raise or log for `ActiveRecord::StrictLoadingViolationError`.
493
+ ## Rails 7.1.1 (October 11, 2023) ##
524
494
 
525
- Some applications may not want to raise an error in production if using `strict_loading`. This would allow an application to set strict loading to log for the production environment while still raising in development and test environments.
495
+ * Fix auto populating IDENTITY columns for PostgreSQL.
526
496
 
527
- Set `config.active_record.action_on_strict_loading_violation` to `:log` errors instead of raising.
497
+ *fatkodima*
528
498
 
529
- *Eileen M. Uchitelle*
499
+ * Fix "ArgumentError: wrong number of arguments (given 3, expected 2)" when
500
+ down migrating `rename_table` in older migrations.
530
501
 
531
- * Allow the inverse of a `has_one` association that was previously autosaved to be loaded.
502
+ *fatkodima*
532
503
 
533
- Fixes #34255.
504
+ * Do not require the Action Text, Active Storage and Action Mailbox tables
505
+ to be present when running when running test on CI.
534
506
 
535
- *Steven Weber*
507
+ *Rafael Mendonça França*
536
508
 
537
- * Optimise the length of index names for polymorphic references by using the reference name rather than the type and id column names.
538
509
 
539
- Because the default behaviour when adding an index with multiple columns is to use all column names in the index name, this could frequently lead to overly long index names for polymorphic references which would fail the migration if it exceeded the database limit.
510
+ ## Rails 7.1.0 (October 05, 2023) ##
540
511
 
541
- This change reduces the chance of that happening by using the reference name, e.g. `index_my_table_on_my_reference`.
512
+ * No changes.
542
513
 
543
- Fixes #38655.
544
514
 
545
- *Luke Redpath*
515
+ ## Rails 7.1.0.rc2 (October 01, 2023) ##
546
516
 
547
- * MySQL: Uniqueness validator now respects default database collation,
548
- no longer enforce case sensitive comparison by default.
517
+ * Remove -shm and -wal SQLite files when `rails db:drop` is run.
549
518
 
550
- *Ryuta Kamizono*
519
+ *Niklas Häusele*
551
520
 
552
- * Remove deprecated methods from `ActiveRecord::ConnectionAdapters::DatabaseLimits`.
521
+ * Revert the change to raise an `ArgumentError` when `#accepts_nested_attributes_for` is declared more than once for
522
+ an association in the same class.
553
523
 
554
- `column_name_length`
555
- `table_name_length`
556
- `columns_per_table`
557
- `indexes_per_table`
558
- `columns_per_multicolumn_index`
559
- `sql_query_length`
560
- `joins_per_query`
524
+ The reverted behavior broke the case where the `#accepts_nested_attributes_for` was defined in a concern and
525
+ where overridden in the class that included the concern.
561
526
 
562
527
  *Rafael Mendonça França*
563
528
 
564
- * Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_multi_insert?`.
565
529
 
566
- *Rafael Mendonça França*
530
+ ## Rails 7.1.0.rc1 (September 27, 2023) ##
567
531
 
568
- * Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_foreign_keys_in_create?`.
532
+ * Better naming for unique constraints support.
569
533
 
570
- *Rafael Mendonça França*
534
+ Naming unique keys leads to misunderstanding it's a short-hand of unique indexes.
535
+ Just naming it unique constraints is not misleading.
571
536
 
572
- * Remove deprecated `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#supports_ranges?`.
537
+ In Rails 7.1.0.beta1 or before:
573
538
 
574
- *Rafael Mendonça França*
539
+ ```ruby
540
+ add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
541
+ remove_unique_key :sections, name: "unique_section_position"
542
+ ```
575
543
 
576
- * Remove deprecated `ActiveRecord::Base#update_attributes` and `ActiveRecord::Base#update_attributes!`.
544
+ Now:
577
545
 
578
- *Rafael Mendonça França*
546
+ ```ruby
547
+ add_unique_constraint :sections, [:position], deferrable: :deferred, name: "unique_section_position"
548
+ remove_unique_constraint :sections, name: "unique_section_position"
549
+ ```
579
550
 
580
- * Remove deprecated `migrations_path` argument in `ActiveRecord::ConnectionAdapter::SchemaStatements#assume_migrated_upto_version`.
551
+ *Ryuta Kamizono*
581
552
 
582
- *Rafael Mendonça França*
553
+ * Fix duplicate quoting for check constraint expressions in schema dump when using MySQL
583
554
 
584
- * Remove deprecated `config.active_record.sqlite3.represent_boolean_as_integer`.
555
+ A check constraint with an expression, that already contains quotes, lead to an invalid schema
556
+ dump with the mysql2 adapter.
585
557
 
586
- *Rafael Mendonça França*
558
+ Fixes #42424.
587
559
 
588
- * `relation.create` does no longer leak scope to class level querying methods
589
- in initialization block and callbacks.
560
+ *Felix Tscheulin*
590
561
 
591
- Before:
562
+ * Performance tune the SQLite3 adapter connection configuration
592
563
 
593
- User.where(name: "John").create do |john|
594
- User.find_by(name: "David") # => nil
595
- end
564
+ For Rails applications, the Write-Ahead-Log in normal syncing mode with a capped journal size, a healthy shared memory buffer and a shared cache will perform, on average, 2× better.
596
565
 
597
- After:
566
+ *Stephen Margheim*
598
567
 
599
- User.where(name: "John").create do |john|
600
- User.find_by(name: "David") # => #<User name: "David", ...>
601
- end
568
+ * Allow SQLite3 `busy_handler` to be configured with simple max number of `retries`
602
569
 
603
- *Ryuta Kamizono*
570
+ Retrying busy connections without delay is a preferred practice for performance-sensitive applications. Add support for a `database.yml` `retries` integer, which is used in a simple `busy_handler` function to retry busy connections without exponential backoff up to the max number of `retries`.
604
571
 
605
- * Named scope chain does no longer leak scope to class level querying methods.
572
+ *Stephen Margheim*
606
573
 
607
- class User < ActiveRecord::Base
608
- scope :david, -> { User.where(name: "David") }
609
- end
574
+ * The SQLite3 adapter now supports `supports_insert_returning?`
610
575
 
611
- Before:
576
+ Implementing the full `supports_insert_returning?` contract means the SQLite3 adapter supports auto-populated columns (#48241) as well as custom primary keys.
612
577
 
613
- User.where(name: "John").david
614
- # SELECT * FROM users WHERE name = 'John' AND name = 'David'
578
+ *Stephen Margheim*
615
579
 
616
- After:
580
+ * Ensure the SQLite3 adapter handles default functions with the `||` concatenation operator
617
581
 
618
- User.where(name: "John").david
619
- # SELECT * FROM users WHERE name = 'David'
582
+ Previously, this default function would produce the static string `"'Ruby ' || 'on ' || 'Rails'"`.
583
+ Now, the adapter will appropriately receive and use `"Ruby on Rails"`.
620
584
 
621
- *Ryuta Kamizono*
585
+ ```ruby
586
+ change_column_default "test_models", "ruby_on_rails", -> { "('Ruby ' || 'on ' || 'Rails')" }
587
+ ```
622
588
 
623
- * Remove deprecated methods from `ActiveRecord::DatabaseConfigurations`.
589
+ *Stephen Margheim*
624
590
 
625
- `fetch`
626
- `each`
627
- `first`
628
- `values`
629
- `[]=`
591
+ * Dump PostgreSQL schemas as part of the schema dump.
630
592
 
631
- *Rafael Mendonça França*
593
+ *Lachlan Sylvester*
632
594
 
633
- * `where.not` now generates NAND predicates instead of NOR.
634
595
 
635
- Before:
596
+ ## Rails 7.1.0.beta1 (September 13, 2023) ##
636
597
 
637
- User.where.not(name: "Jon", role: "admin")
638
- # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
598
+ * Encryption now supports `support_unencrypted_data` being set per-attribute.
639
599
 
640
- After:
600
+ You can now opt out of `support_unencrypted_data` on a specific encrypted attribute.
601
+ This only has an effect if `ActiveRecord::Encryption.config.support_unencrypted_data == true`.
641
602
 
642
- User.where.not(name: "Jon", role: "admin")
643
- # SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
603
+ ```ruby
604
+ class User < ActiveRecord::Base
605
+ encrypts :name, deterministic: true, support_unencrypted_data: false
606
+ encrypts :email, deterministic: true
607
+ end
608
+ ```
644
609
 
645
- *Rafael Mendonça França*
610
+ *Alex Ghiculescu*
646
611
 
647
- * Remove deprecated `ActiveRecord::Result#to_hash` method.
612
+ * Add instrumentation for Active Record transactions
648
613
 
649
- *Rafael Mendonça França*
614
+ Allows subscribing to transaction events for tracking/instrumentation. The event payload contains the connection and the outcome (commit, rollback, restart, incomplete), as well as timing details.
650
615
 
651
- * Deprecate `ActiveRecord::Base.allow_unsafe_raw_sql`.
616
+ ```ruby
617
+ ActiveSupport::Notifications.subscribe("transaction.active_record") do |event|
618
+ puts "Transaction event occurred!"
619
+ connection = event.payload[:connection]
620
+ puts "Connection: #{connection.inspect}"
621
+ end
622
+ ```
652
623
 
653
- *Rafael Mendonça França*
624
+ *Daniel Colson*, *Ian Candy*
654
625
 
655
- * Remove deprecated support for using unsafe raw SQL in `ActiveRecord::Relation` methods.
626
+ * Support composite foreign keys via migration helpers.
656
627
 
657
- *Rafael Mendonça França*
628
+ ```ruby
629
+ # Assuming "carts" table has "(shop_id, user_id)" as a primary key.
658
630
 
659
- * Allow users to silence the "Rails couldn't infer whether you are using multiple databases..."
660
- message using `config.active_record.suppress_multiple_database_warning`.
631
+ add_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
661
632
 
662
- *Omri Gabay*
633
+ remove_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
634
+ foreign_key_exists?(:orders, :carts, primary_key: [:shop_id, :user_id])
635
+ ```
663
636
 
664
- * Connections can be granularly switched for abstract classes when `connected_to` is called.
637
+ *fatkodima*
665
638
 
666
- This change allows `connected_to` to switch a `role` and/or `shard` for a single abstract class instead of all classes globally. Applications that want to use the new feature need to set `config.active_record.legacy_connection_handling` to `false` in their application configuration.
639
+ * Adds support for `if_not_exists` when adding a check constraint.
667
640
 
668
- Example usage:
641
+ ```ruby
642
+ add_check_constraint :posts, "post_type IN ('blog', 'comment', 'share')", if_not_exists: true
643
+ ```
669
644
 
670
- Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`.
645
+ *Cody Cutrer*
671
646
 
672
- ```ruby
673
- ActiveRecord::Base.connected_to(role: :reading) do
674
- User.first # reads from default replica
675
- Dog.first # reads from default replica
647
+ * Raise an `ArgumentError` when `#accepts_nested_attributes_for` is declared more than once for an association in
648
+ the same class. Previously, the last declaration would silently override the previous one. Overriding in a subclass
649
+ is still allowed.
676
650
 
677
- AnimalsRecord.connected_to(role: :writing, shard: :one) do
678
- User.first # reads from default replica
679
- Dog.first # reads from shard one primary
680
- end
651
+ *Joshua Young*
681
652
 
682
- User.first # reads from default replica
683
- Dog.first # reads from default replica
653
+ * Deprecate `rewhere` argument on `#merge`.
684
654
 
685
- ApplicationRecord.connected_to(role: :writing, shard: :two) do
686
- User.first # reads from shard two primary
687
- Dog.first # reads from default replica
688
- end
689
- end
690
- ```
655
+ The `rewhere` argument on `#merge`is deprecated without replacement and
656
+ will be removed in Rails 7.2.
691
657
 
692
- *Eileen M. Uchitelle*, *John Crepezzi*
658
+ *Adam Hess*
693
659
 
694
- * Allow double-dash comment syntax when querying read-only databases
660
+ * Deprecate aliasing non-attributes with `alias_attribute`.
695
661
 
696
- *James Adam*
662
+ *Ian Candy*
697
663
 
698
- * Add `values_at` method.
664
+ * Fix unscope is not working in specific case
665
+
666
+ Before:
667
+ ```ruby
668
+ Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
699
669
 
700
- Returns an array containing the values associated with the given methods.
670
+ ```
701
671
 
672
+ After:
702
673
  ```ruby
703
- topic = Topic.first
704
- topic.values_at(:title, :author_name)
705
- # => ["Budget", "Jason"]
674
+ Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
706
675
  ```
707
676
 
708
- Similar to `Hash#values_at` but on an Active Record instance.
677
+ Fixes #48094.
709
678
 
710
- *Guillaume Briday*
679
+ *Kazuya Hatanaka*
711
680
 
712
- * Fix `read_attribute_before_type_cast` to consider attribute aliases.
681
+ * Change `has_secure_token` default to `on: :initialize`
713
682
 
714
- *Marcelo Lauxen*
683
+ Change the new default value from `on: :create` to `on: :initialize`
715
684
 
716
- * Support passing record to uniqueness validator `:conditions` callable:
685
+ Can be controlled by the `config.active_record.generate_secure_token_on`
686
+ configuration:
717
687
 
718
688
  ```ruby
719
- class Article < ApplicationRecord
720
- validates_uniqueness_of :title, conditions: ->(article) {
721
- published_at = article.published_at
722
- where(published_at: published_at.beginning_of_year..published_at.end_of_year)
723
- }
724
- end
689
+ config.active_record.generate_secure_token_on = :create
725
690
  ```
726
691
 
727
- *Eliot Sykes*
692
+ *Sean Doyle*
728
693
 
729
- * `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
730
- total number of rows affected, just like their non-batched counterparts.
694
+ * Fix `change_column` not setting `precision: 6` on `datetime` columns when
695
+ using 7.0+ Migrations and SQLite.
731
696
 
732
- ```ruby
733
- Person.in_batches.update_all("first_name = 'Eugene'") # => 42
734
- Person.in_batches.delete_all # => 42
735
- ```
697
+ *Hartley McGuire*
736
698
 
737
- Fixes #40287.
699
+ * Support composite identifiers in `to_key`
738
700
 
739
- *Eugene Kenny*
701
+ `to_key` avoids wrapping `#id` value into an `Array` if `#id` already an array
740
702
 
741
- * Add support for PostgreSQL `interval` data type with conversion to
742
- `ActiveSupport::Duration` when loading records from database and
743
- serialization to ISO 8601 formatted duration string on save.
744
- Add support to define a column in migrations and get it in a schema dump.
745
- Optional column precision is supported.
703
+ *Nikita Vasilevsky*
746
704
 
747
- To use this in 6.1, you need to place the next string to your model file:
705
+ * Add validation option for `enum`
748
706
 
749
- attribute :duration, :interval
707
+ ```ruby
708
+ class Contract < ApplicationRecord
709
+ enum :status, %w[in_progress completed], validate: true
710
+ end
711
+ Contract.new(status: "unknown").valid? # => false
712
+ Contract.new(status: nil).valid? # => false
713
+ Contract.new(status: "completed").valid? # => true
750
714
 
751
- To keep old behavior until 7.0 is released:
715
+ class Contract < ApplicationRecord
716
+ enum :status, %w[in_progress completed], validate: { allow_nil: true }
717
+ end
718
+ Contract.new(status: "unknown").valid? # => false
719
+ Contract.new(status: nil).valid? # => true
720
+ Contract.new(status: "completed").valid? # => true
721
+ ```
752
722
 
753
- attribute :duration, :string
723
+ *Edem Topuzov*, *Ryuta Kamizono*
754
724
 
755
- Example:
725
+ * Allow batching methods to use already loaded relation if available
756
726
 
757
- create_table :events do |t|
758
- t.string :name
759
- t.interval :duration
760
- end
727
+ Calling batch methods on already loaded relations will use the records previously loaded instead of retrieving
728
+ them from the database again.
761
729
 
762
- class Event < ApplicationRecord
763
- attribute :duration, :interval
764
- end
730
+ *Adam Hess*
765
731
 
766
- Event.create!(name: 'Rock Fest', duration: 2.days)
767
- Event.last.duration # => 2 days
768
- Event.last.duration.iso8601 # => "P2D"
769
- Event.new(duration: 'P1DT12H3S').duration # => 1 day, 12 hours, and 3 seconds
770
- Event.new(duration: '1 day') # Unknown value will be ignored and NULL will be written to database
732
+ * Deprecate `read_attribute(:id)` returning the primary key if the primary key is not `:id`.
771
733
 
772
- *Andrey Novikov*
734
+ Starting in Rails 7.2, `read_attribute(:id)` will return the value of the id column, regardless of the model's
735
+ primary key. To retrieve the value of the primary key, use `#id` instead. `read_attribute(:id)` for composite
736
+ primary key models will now return the value of the id column.
773
737
 
774
- * Allow associations supporting the `dependent:` key to take `dependent: :destroy_async`.
738
+ *Adrianna Chang*
775
739
 
776
- ```ruby
777
- class Account < ActiveRecord::Base
778
- belongs_to :supplier, dependent: :destroy_async
779
- end
780
- ```
740
+ * Fix `change_table` setting datetime precision for 6.1 Migrations
781
741
 
782
- `:destroy_async` will enqueue a job to destroy associated records in the background.
742
+ *Hartley McGuire*
783
743
 
784
- *DHH*, *George Claghorn*, *Cory Gwin*, *Rafael Mendonça França*, *Adrianna Chang*
744
+ * Fix change_column setting datetime precision for 6.1 Migrations
785
745
 
786
- * Add `SKIP_TEST_DATABASE` environment variable to disable modifying the test database when `rails db:create` and `rails db:drop` are called.
746
+ *Hartley McGuire*
787
747
 
788
- *Jason Schweier*
748
+ * Add `ActiveRecord::Base#id_value` alias to access the raw value of a record's id column.
789
749
 
790
- * `connects_to` can only be called on `ActiveRecord::Base` or abstract classes.
750
+ This alias is only provided for models that declare an `:id` column.
791
751
 
792
- Ensure that `connects_to` can only be called from `ActiveRecord::Base` or abstract classes. This protects the application from opening duplicate or too many connections.
752
+ *Adrianna Chang*
793
753
 
794
- *Eileen M. Uchitelle*, *John Crepezzi*
754
+ * Fix previous change tracking for `ActiveRecord::Store` when using a column with JSON structured database type
795
755
 
796
- * All connection adapters `execute` now raises `ActiveRecord::ConnectionNotEstablished` rather than
797
- `ActiveRecord::StatementInvalid` when they encounter a connection error.
756
+ Before, the methods to access the changes made during the last save `#saved_change_to_key?`, `#saved_change_to_key`, and `#key_before_last_save` did not work if the store was defined as a `store_accessor` on a column with a JSON structured database type
798
757
 
799
- *Jean Boussier*
758
+ *Robert DiMartino*
800
759
 
801
- * `Mysql2Adapter#quote_string` now raises `ActiveRecord::ConnectionNotEstablished` rather than
802
- `ActiveRecord::StatementInvalid` when it can't connect to the MySQL server.
760
+ * Fully support `NULLS [NOT] DISTINCT` for PostgreSQL 15+ indexes.
803
761
 
804
- *Jean Boussier*
762
+ Previous work was done to allow the index to be created in a migration, but it was not
763
+ supported in schema.rb. Additionally, the matching for `NULLS [NOT] DISTINCT` was not
764
+ in the correct order, which could have resulted in inconsistent schema detection.
805
765
 
806
- * Add support for check constraints that are `NOT VALID` via `validate: false` (PostgreSQL-only).
766
+ *Gregory Jones*
807
767
 
808
- *Alex Robbin*
768
+ * Allow escaping of literal colon characters in `sanitize_sql_*` methods when named bind variables are used
809
769
 
810
- * Ensure the default configuration is considered primary or first for an environment
770
+ *Justin Bull*
811
771
 
812
- If a multiple database application provides a configuration named primary, that will be treated as default. In applications that do not have a primary entry, the default database configuration will be the first configuration for an environment.
772
+ * Fix `#previously_new_record?` to return true for destroyed records.
813
773
 
814
- *Eileen M. Uchitelle*
774
+ Before, if a record was created and then destroyed, `#previously_new_record?` would return true.
775
+ Now, any UPDATE or DELETE to a record is considered a change, and will result in `#previously_new_record?`
776
+ returning false.
777
+
778
+ *Adrianna Chang*
815
779
 
816
- * Allow `where` references association names as joined table name aliases.
780
+ * Specify callback in `has_secure_token`
817
781
 
818
782
  ```ruby
819
- class Comment < ActiveRecord::Base
820
- enum label: [:default, :child]
821
- has_many :children, class_name: "Comment", foreign_key: :parent_id
783
+ class User < ApplicationRecord
784
+ has_secure_token on: :initialize
822
785
  end
823
786
 
824
- # ... FROM comments LEFT OUTER JOIN comments children ON ... WHERE children.label = 1
825
- Comment.includes(:children).where("children.label": "child")
787
+ User.new.token # => "abc123...."
826
788
  ```
827
789
 
828
- *Ryuta Kamizono*
829
-
830
- * Support storing demodulized class name for polymorphic type.
831
-
832
- Before Rails 6.1, storing demodulized class name is supported only for STI type
833
- by `store_full_sti_class` class attribute.
790
+ *Sean Doyle*
834
791
 
835
- Now `store_full_class_name` class attribute can handle both STI and polymorphic types.
792
+ * Fix incrementation of in memory counter caches when associations overlap
836
793
 
837
- *Ryuta Kamizono*
794
+ When two associations had a similarly named counter cache column, Active Record
795
+ could sometime increment the wrong one.
838
796
 
839
- * Deprecate `rails db:structure:{load, dump}` tasks and extend
840
- `rails db:schema:{load, dump}` tasks to work with either `:ruby` or `:sql` format,
841
- depending on `config.active_record.schema_format` configuration value.
797
+ *Jacopo Beschi*, *Jean Boussier*
842
798
 
843
- *fatkodima*
799
+ * Don't show secrets for Active Record's `Cipher::Aes256Gcm#inspect`.
844
800
 
845
- * Respect the `select` values for eager loading.
801
+ Before:
846
802
 
847
803
  ```ruby
848
- post = Post.select("UPPER(title) AS title").first
849
- post.title # => "WELCOME TO THE WEBLOG"
850
- post.body # => ActiveModel::MissingAttributeError
804
+ ActiveRecord::Encryption::Cipher::Aes256Gcm.new(secret).inspect
805
+ "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
806
+ ```
851
807
 
852
- # Rails 6.0 (ignore the `select` values)
853
- post = Post.select("UPPER(title) AS title").eager_load(:comments).first
854
- post.title # => "Welcome to the weblog"
855
- post.body # => "Such a lovely day"
808
+ After:
856
809
 
857
- # Rails 6.1 (respect the `select` values)
858
- post = Post.select("UPPER(title) AS title").eager_load(:comments).first
859
- post.title # => "WELCOME TO THE WEBLOG"
860
- post.body # => ActiveModel::MissingAttributeError
810
+ ```ruby
811
+ ActiveRecord::Encryption::Cipher::Aes256Gcm(secret).inspect
812
+ "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038>"
861
813
  ```
862
814
 
863
- *Ryuta Kamizono*
815
+ *Petrik de Heus*
864
816
 
865
- * Allow attribute's default to be configured but keeping its own type.
817
+ * Bring back the historical behavior of committing transaction on non-local return.
866
818
 
867
819
  ```ruby
868
- class Post < ActiveRecord::Base
869
- attribute :written_at, default: -> { Time.now.utc }
820
+ Model.transaction do
821
+ model.save
822
+ return
823
+ other_model.save # not executed
870
824
  end
825
+ ```
871
826
 
872
- # Rails 6.0
873
- Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
827
+ Historically only raised errors would trigger a rollback, but in Ruby `2.3`, the `timeout` library
828
+ started using `throw` to interrupt execution which had the adverse effect of committing open transactions.
874
829
 
875
- # Rails 6.1
876
- Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
877
- ```
830
+ To solve this, in Active Record 6.1 the behavior was changed to instead rollback the transaction as it was safer
831
+ than to potentially commit an incomplete transaction.
878
832
 
879
- *Ryuta Kamizono*
833
+ Using `return`, `break` or `throw` inside a `transaction` block was essentially deprecated from Rails 6.1 onwards.
880
834
 
881
- * Allow default to be configured for Enum.
835
+ However with the release of `timeout 0.4.0`, `Timeout.timeout` now raises an error again, and Active Record is able
836
+ to return to its original, less surprising, behavior.
882
837
 
883
- ```ruby
884
- class Book < ActiveRecord::Base
885
- enum status: [:proposed, :written, :published], _default: :published
886
- end
838
+ This historical behavior can now be opt-ed in via:
887
839
 
888
- Book.new.status # => "published"
840
+ ```
841
+ Rails.application.config.active_record.commit_transaction_on_non_local_return = true
889
842
  ```
890
843
 
891
- *Ryuta Kamizono*
844
+ And is the default for new applications created in Rails 7.1.
892
845
 
893
- * Deprecate YAML loading from legacy format older than Rails 5.0.
846
+ *Jean Boussier*
894
847
 
895
- *Ryuta Kamizono*
848
+ * Deprecate `name` argument on `#remove_connection`.
896
849
 
897
- * Added the setting `ActiveRecord::Base.immutable_strings_by_default`, which
898
- allows you to specify that all string columns should be frozen unless
899
- otherwise specified. This will reduce memory pressure for applications which
900
- do not generally mutate string properties of Active Record objects.
850
+ The `name` argument is deprecated on `#remove_connection` without replacement. `#remove_connection` should be called directly on the class that established the connection.
901
851
 
902
- *Sean Griffin*, *Ryuta Kamizono*
852
+ *Eileen M. Uchitelle*
903
853
 
904
- * Deprecate `map!` and `collect!` on `ActiveRecord::Result`.
854
+ * Fix has_one through singular building with inverse.
905
855
 
906
- *Ryuta Kamizono*
856
+ Allows building of records from an association with a has_one through a
857
+ singular association with inverse. For belongs_to through associations,
858
+ linking the foreign key to the primary key model isn't needed.
859
+ For has_one, we cannot build records due to the association not being mutable.
907
860
 
908
- * Support `relation.and` for intersection as Set theory.
861
+ *Gannon McGibbon*
909
862
 
910
- ```ruby
911
- david_and_mary = Author.where(id: [david, mary])
912
- mary_and_bob = Author.where(id: [mary, bob])
863
+ * Disable database prepared statements when query logs are enabled
913
864
 
914
- david_and_mary.merge(mary_and_bob) # => [mary, bob]
865
+ Prepared Statements and Query Logs are incompatible features due to query logs making every query unique.
915
866
 
916
- david_and_mary.and(mary_and_bob) # => [mary]
917
- david_and_mary.or(mary_and_bob) # => [david, mary, bob]
918
- ```
867
+ *zzak, Jean Boussier*
919
868
 
920
- *Ryuta Kamizono*
869
+ * Support decrypting data encrypted non-deterministically with a SHA1 hash digest.
921
870
 
922
- * Merging conditions on the same column no longer maintain both conditions,
923
- and will be consistently replaced by the latter condition in Rails 7.0.
924
- To migrate to Rails 7.0's behavior, use `relation.merge(other, rewhere: true)`.
871
+ This adds a new Active Record encryption option to support decrypting data encrypted
872
+ non-deterministically with a SHA1 hash digest:
925
873
 
926
- ```ruby
927
- # Rails 6.1 (IN clause is replaced by merger side equality condition)
928
- Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
874
+ ```
875
+ Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
876
+ ```
929
877
 
930
- # Rails 6.1 (both conflict conditions exists, deprecated)
931
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
878
+ The new option addresses a problem when upgrading from 7.0 to 7.1. Due to a bug in how Active Record
879
+ Encryption was getting initialized, the key provider used for non-deterministic encryption were using
880
+ SHA-1 as its digest class, instead of the one configured globally by Rails via
881
+ `Rails.application.config.active_support.key_generator_hash_digest_class`.
932
882
 
933
- # Rails 6.1 with rewhere to migrate to Rails 7.0's behavior
934
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
883
+ *Cadu Ribeiro and Jorge Manrubia*
935
884
 
936
- # Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
937
- Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
938
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
939
- ```
885
+ * Added PostgreSQL migration commands for enum rename, add value, and rename value.
940
886
 
941
- *Ryuta Kamizono*
887
+ `rename_enum` and `rename_enum_value` are reversible. Due to Postgres
888
+ limitation, `add_enum_value` is not reversible since you cannot delete enum
889
+ values. As an alternative you should drop and recreate the enum entirely.
890
+
891
+ ```ruby
892
+ rename_enum :article_status, to: :article_state
893
+ ```
942
894
 
943
- * Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case.
895
+ ```ruby
896
+ add_enum_value :article_state, "archived" # will be at the end of existing values
897
+ add_enum_value :article_state, "in review", before: "published"
898
+ add_enum_value :article_state, "approved", after: "in review"
899
+ ```
944
900
 
945
- *Peter Fry*
901
+ ```ruby
902
+ rename_enum_value :article_state, from: "archived", to: "deleted"
903
+ ```
946
904
 
947
- * Resolve issue with insert_all unique_by option when used with expression index.
905
+ *Ray Faddis*
948
906
 
949
- When the `:unique_by` option of `ActiveRecord::Persistence.insert_all` and
950
- `ActiveRecord::Persistence.upsert_all` was used with the name of an expression index, an error
951
- was raised. Adding a guard around the formatting behavior for the `:unique_by` corrects this.
907
+ * Allow composite primary key to be derived from schema
952
908
 
953
- Usage:
909
+ Booting an application with a schema that contains composite primary keys
910
+ will not issue warning and won't `nil`ify the `ActiveRecord::Base#primary_key` value anymore.
954
911
 
912
+ Given a `travel_routes` table definition and a `TravelRoute` model like:
955
913
  ```ruby
956
- create_table :books, id: :integer, force: true do |t|
957
- t.column :name, :string
958
- t.index "lower(name)", unique: true
914
+ create_table :travel_routes, primary_key: [:origin, :destination], force: true do |t|
915
+ t.string :origin
916
+ t.string :destination
959
917
  end
960
918
 
961
- Book.insert_all [{ name: "MyTest" }], unique_by: :index_books_on_lower_name
919
+ class TravelRoute < ActiveRecord::Base; end
962
920
  ```
921
+ The `TravelRoute.primary_key` value will be automatically derived to `["origin", "destination"]`
963
922
 
964
- Fixes #39516.
923
+ *Nikita Vasilevsky*
965
924
 
966
- *Austen Madden*
925
+ * Include the `connection_pool` with exceptions raised from an adapter.
967
926
 
968
- * Add basic support for CHECK constraints to database migrations.
927
+ The `connection_pool` provides added context such as the connection used
928
+ that led to the exception as well as which role and shard.
969
929
 
970
- Usage:
930
+ *Luan Vieira*
931
+
932
+ * Support multiple column ordering for `find_each`, `find_in_batches` and `in_batches`.
933
+
934
+ When find_each/find_in_batches/in_batches are performed on a table with composite primary keys, ascending or descending order can be selected for each key.
971
935
 
972
936
  ```ruby
973
- add_check_constraint :products, "price > 0", name: "price_check"
974
- remove_check_constraint :products, name: "price_check"
937
+ Person.find_each(order: [:desc, :asc]) do |person|
938
+ person.party_all_night!
939
+ end
975
940
  ```
976
941
 
977
- *fatkodima*
942
+ *Takuya Kurimoto*
978
943
 
979
- * Add `ActiveRecord::Base.strict_loading_by_default` and `ActiveRecord::Base.strict_loading_by_default=`
980
- to enable/disable strict_loading mode by default for a model. The configuration's value is
981
- inheritable by subclasses, but they can override that value and it will not impact parent class.
944
+ * Fix where on association with has_one/has_many polymorphic relations.
982
945
 
983
- Usage:
946
+ Before:
947
+ ```ruby
948
+ Treasure.where(price_estimates: PriceEstimate.all)
949
+ #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
950
+ ```
984
951
 
952
+ Later:
985
953
  ```ruby
986
- class Developer < ApplicationRecord
987
- self.strict_loading_by_default = true
954
+ Treasure.where(price_estimates: PriceEstimate.all)
955
+ #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
956
+ ```
988
957
 
989
- has_many :projects
990
- end
958
+ *Lázaro Nixon*
991
959
 
992
- dev = Developer.first
993
- dev.projects.first
994
- # => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
995
- ```
960
+ * Assign auto populated columns on Active Record record creation.
996
961
 
997
- *bogdanvlviv*
962
+ Changes record creation logic to allow for the `auto_increment` column to be assigned
963
+ immediately after creation regardless of it's relation to the model's primary key.
998
964
 
999
- * Deprecate passing an Active Record object to `quote`/`type_cast` directly.
965
+ The PostgreSQL adapter benefits the most from the change allowing for any number of auto-populated
966
+ columns to be assigned on the object immediately after row insertion utilizing the `RETURNING` statement.
1000
967
 
1001
- *Ryuta Kamizono*
968
+ *Nikita Vasilevsky*
1002
969
 
1003
- * Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic.
970
+ * Use the first key in the `shards` hash from `connected_to` for the `default_shard`.
1004
971
 
1005
- Before:
972
+ Some applications may not want to use `:default` as a shard name in their connection model. Unfortunately Active Record expects there to be a `:default` shard because it must assume a shard to get the right connection from the pool manager. Rather than force applications to manually set this, `connects_to` can infer the default shard name from the hash of shards and will now assume that the first shard is your default.
973
+
974
+ For example if your model looked like this:
1006
975
 
1007
976
  ```ruby
1008
- create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
1009
- end
977
+ class ShardRecord < ApplicationRecord
978
+ self.abstract_class = true
979
+
980
+ connects_to shards: {
981
+ shard_one: { writing: :shard_one },
982
+ shard_two: { writing: :shard_two }
983
+ }
1010
984
  ```
1011
985
 
1012
- After:
986
+ Then the `default_shard` for this class would be set to `shard_one`.
1013
987
 
1014
- ```ruby
1015
- create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
1016
- end
1017
- ```
988
+ Fixes: #45390
1018
989
 
1019
- *Ryuta Kamizono*
990
+ *Eileen M. Uchitelle*
1020
991
 
1021
- * Added delegated type as an alternative to single-table inheritance for representing class hierarchies.
1022
- See ActiveRecord::DelegatedType for the full description.
992
+ * Fix mutation detection for serialized attributes backed by binary columns.
1023
993
 
1024
- *DHH*
994
+ *Jean Boussier*
1025
995
 
1026
- * Deprecate aggregations with group by duplicated fields.
996
+ * Add `ActiveRecord.disconnect_all!` method to immediately close all connections from all pools.
1027
997
 
1028
- To migrate to Rails 7.0's behavior, use `uniq!(:group)` to deduplicate group fields.
998
+ *Jean Boussier*
1029
999
 
1030
- ```ruby
1031
- accounts = Account.group(:firm_id)
1000
+ * Discard connections which may have been left in a transaction.
1032
1001
 
1033
- # duplicated group fields, deprecated.
1034
- accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
1035
- # => {
1036
- # [1, 1] => 50,
1037
- # [2, 2] => 60
1038
- # }
1002
+ There are cases where, due to an error, `within_new_transaction` may unexpectedly leave a connection in an open transaction. In these cases the connection may be reused, and the following may occur:
1003
+ - Writes appear to fail when they actually succeed.
1004
+ - Writes appear to succeed when they actually fail.
1005
+ - Reads return stale or uncommitted data.
1039
1006
 
1040
- # use `uniq!(:group)` to deduplicate group fields.
1041
- accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
1042
- # => {
1043
- # 1 => 50,
1044
- # 2 => 60
1045
- # }
1046
- ```
1007
+ Previously, the following case was detected:
1008
+ - An error is encountered during the transaction, then another error is encountered while attempting to roll it back.
1047
1009
 
1048
- *Ryuta Kamizono*
1010
+ Now, the following additional cases are detected:
1011
+ - An error is encountered just after successfully beginning a transaction.
1012
+ - An error is encountered while committing a transaction, then another error is encountered while attempting to roll it back.
1013
+ - An error is encountered while rolling back a transaction.
1049
1014
 
1050
- * Deprecate duplicated query annotations.
1015
+ *Nick Dower*
1051
1016
 
1052
- To migrate to Rails 7.0's behavior, use `uniq!(:annotate)` to deduplicate query annotations.
1017
+ * Active Record query cache now evicts least recently used entries
1053
1018
 
1054
- ```ruby
1055
- accounts = Account.where(id: [1, 2]).annotate("david and mary")
1019
+ By default it only keeps the `100` most recently used queries.
1056
1020
 
1057
- # duplicated annotations, deprecated.
1058
- accounts.merge(accounts.rewhere(id: 3))
1059
- # SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */ /* david and mary */
1021
+ The cache size can be configured via `database.yml`
1060
1022
 
1061
- # use `uniq!(:annotate)` to deduplicate annotations.
1062
- accounts.merge(accounts.rewhere(id: 3)).uniq!(:annotate)
1063
- # SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */
1023
+ ```yaml
1024
+ development:
1025
+ adapter: mysql2
1026
+ query_cache: 200
1064
1027
  ```
1065
1028
 
1066
- *Ryuta Kamizono*
1029
+ It can also be entirely disabled:
1030
+
1031
+ ```yaml
1032
+ development:
1033
+ adapter: mysql2
1034
+ query_cache: false
1035
+ ```
1067
1036
 
1068
- * Resolve conflict between counter cache and optimistic locking.
1037
+ *Jean Boussier*
1069
1038
 
1070
- Bump an Active Record instance's lock version after updating its counter
1071
- cache. This avoids raising an unnecessary `ActiveRecord::StaleObjectError`
1072
- upon subsequent transactions by maintaining parity with the corresponding
1073
- database record's `lock_version` column.
1039
+ * Deprecate `check_pending!` in favor of `check_all_pending!`.
1074
1040
 
1075
- Fixes #16449.
1041
+ `check_pending!` will only check for pending migrations on the current database connection or the one passed in. This has been deprecated in favor of `check_all_pending!` which will find all pending migrations for the database configurations in a given environment.
1076
1042
 
1077
- *Aaron Lipman*
1043
+ *Eileen M. Uchitelle*
1078
1044
 
1079
- * Support merging option `:rewhere` to allow mergee side condition to be replaced exactly.
1045
+ * Make `increment_counter`/`decrement_counter` accept an amount argument
1080
1046
 
1081
1047
  ```ruby
1082
- david_and_mary = Author.where(id: david.id..mary.id)
1048
+ Post.increment_counter(:comments_count, 5, by: 3)
1049
+ ```
1083
1050
 
1084
- # both conflict conditions exists
1085
- david_and_mary.merge(Author.where(id: bob)) # => []
1051
+ *fatkodima*
1086
1052
 
1087
- # mergee side condition is replaced by rewhere
1088
- david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
1053
+ * Add support for `Array#intersect?` to `ActiveRecord::Relation`.
1089
1054
 
1090
- # mergee side condition is replaced by rewhere option
1091
- david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
1092
- ```
1055
+ `Array#intersect?` is only available on Ruby 3.1 or later.
1093
1056
 
1094
- *Ryuta Kamizono*
1057
+ This allows the Rubocop `Style/ArrayIntersect` cop to work with `ActiveRecord::Relation` objects.
1095
1058
 
1096
- * Add support for finding records based on signed ids, which are tamper-proof, verified ids that can be
1097
- set to expire and scoped with a purpose. This is particularly useful for things like password reset
1098
- or email verification, where you want the bearer of the signed id to be able to interact with the
1099
- underlying record, but usually only within a certain time period.
1059
+ *John Harry Kelly*
1100
1060
 
1101
- ```ruby
1102
- signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
1061
+ * The deferrable foreign key can be passed to `t.references`.
1103
1062
 
1104
- User.find_signed signed_id # => nil, since the purpose does not match
1063
+ *Hiroyuki Ishii*
1064
+
1065
+ * Deprecate `deferrable: true` option of `add_foreign_key`.
1066
+
1067
+ `deferrable: true` is deprecated in favor of `deferrable: :immediate`, and
1068
+ will be removed in Rails 7.2.
1069
+
1070
+ Because `deferrable: true` and `deferrable: :deferred` are hard to understand.
1071
+ Both true and :deferred are truthy values.
1072
+ This behavior is the same as the deferrable option of the add_unique_key method, added in #46192.
1073
+
1074
+ *Hiroyuki Ishii*
1075
+
1076
+ * `AbstractAdapter#execute` and `#exec_query` now clear the query cache
1077
+
1078
+ If you need to perform a read only SQL query without clearing the query
1079
+ cache, use `AbstractAdapter#select_all`.
1105
1080
 
1106
- travel 16.minutes
1107
- User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
1081
+ *Jean Boussier*
1082
+
1083
+ * Make `.joins` / `.left_outer_joins` work with CTEs.
1108
1084
 
1109
- travel_back
1110
- User.find_signed signed_id, purpose: :password_reset # => User.first
1085
+ For example:
1111
1086
 
1112
- User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
1087
+ ```ruby
1088
+ Post
1089
+ .with(commented_posts: Comment.select(:post_id).distinct)
1090
+ .joins(:commented_posts)
1091
+ #=> WITH (...) SELECT ... INNER JOIN commented_posts on posts.id = commented_posts.post_id
1113
1092
  ```
1114
1093
 
1115
- *DHH*
1094
+ *Vladimir Dementyev*
1116
1095
 
1117
- * Support `ALGORITHM = INSTANT` DDL option for index operations on MySQL.
1096
+ * Add a load hook for `ActiveRecord::ConnectionAdapters::Mysql2Adapter`
1097
+ (named `active_record_mysql2adapter`) to allow for overriding aspects of the
1098
+ `ActiveRecord::ConnectionAdapters::Mysql2Adapter` class. This makes `Mysql2Adapter`
1099
+ consistent with `PostgreSQLAdapter` and `SQLite3Adapter` that already have load hooks.
1118
1100
 
1119
- *Ryuta Kamizono*
1101
+ *fatkodima*
1120
1102
 
1121
- * Fix index creation to preserve index comment in bulk change table on MySQL.
1103
+ * Introduce adapter for Trilogy database client
1122
1104
 
1123
- *Ryuta Kamizono*
1105
+ Trilogy is a MySQL-compatible database client. Rails applications can use Trilogy
1106
+ by configuring their `config/database.yml`:
1124
1107
 
1125
- * Allow `unscope` to be aware of table name qualified values.
1108
+ ```yaml
1109
+ development:
1110
+ adapter: trilogy
1111
+ database: blog_development
1112
+ pool: 5
1113
+ ```
1126
1114
 
1127
- It is possible to unscope only the column in the specified table.
1115
+ Or by using the `DATABASE_URL` environment variable:
1128
1116
 
1129
1117
  ```ruby
1130
- posts = Post.joins(:comments).group(:"posts.hidden")
1131
- posts = posts.where("posts.hidden": false, "comments.hidden": false)
1118
+ ENV['DATABASE_URL'] # => "trilogy://localhost/blog_development?pool=5"
1119
+ ```
1120
+
1121
+ *Adrianna Chang*
1132
1122
 
1133
- posts.count
1134
- # => { false => 10 }
1123
+ * `after_commit` callbacks defined on models now execute in the correct order.
1124
+
1125
+ ```ruby
1126
+ class User < ActiveRecord::Base
1127
+ after_commit { puts("this gets called first") }
1128
+ after_commit { puts("this gets called second") }
1129
+ end
1130
+ ```
1135
1131
 
1136
- # unscope both hidden columns
1137
- posts.unscope(where: :hidden).count
1138
- # => { false => 11, true => 1 }
1132
+ Previously, the callbacks executed in the reverse order. To opt in to the new behaviour:
1139
1133
 
1140
- # unscope only comments.hidden column
1141
- posts.unscope(where: :"comments.hidden").count
1142
- # => { false => 11 }
1134
+ ```ruby
1135
+ config.active_record.run_after_transaction_callbacks_in_order_defined = true
1143
1136
  ```
1144
1137
 
1145
- *Ryuta Kamizono*, *Slava Korolev*
1138
+ This is the default for new apps.
1139
+
1140
+ *Alex Ghiculescu*
1146
1141
 
1147
- * Fix `rewhere` to truly overwrite collided where clause by new where clause.
1142
+ * Infer `foreign_key` when `inverse_of` is present on `has_one` and `has_many` associations.
1148
1143
 
1149
1144
  ```ruby
1150
- steve = Person.find_by(name: "Steve")
1151
- david = Author.find_by(name: "David")
1145
+ has_many :citations, foreign_key: "book1_id", inverse_of: :book
1146
+ ```
1152
1147
 
1153
- relation = Essay.where(writer: steve)
1148
+ can be simplified to
1154
1149
 
1155
- # Before
1156
- relation.rewhere(writer: david).to_a # => []
1150
+ ```ruby
1151
+ has_many :citations, inverse_of: :book
1152
+ ```
1157
1153
 
1158
- # After
1159
- relation.rewhere(writer: david).to_a # => [david]
1154
+ and the foreign_key will be read from the corresponding `belongs_to` association.
1155
+
1156
+ *Daniel Whitney*
1157
+
1158
+ * Limit max length of auto generated index names
1159
+
1160
+ Auto generated index names are now limited to 62 bytes, which fits within
1161
+ the default index name length limits for MySQL, Postgres and SQLite.
1162
+
1163
+ Any index name over the limit will fallback to the new short format.
1164
+
1165
+ Before (too long):
1166
+ ```
1167
+ index_testings_on_foo_and_bar_and_first_name_and_last_name_and_administrator
1160
1168
  ```
1161
1169
 
1162
- *Ryuta Kamizono*
1170
+ After (short format):
1171
+ ```
1172
+ idx_on_foo_bar_first_name_last_name_administrator_5939248142
1173
+ ```
1174
+
1175
+ The short format includes a hash to ensure the name is unique database-wide.
1176
+
1177
+ *Mike Coutermarsh*
1178
+
1179
+ * Introduce a more stable and optimized Marshal serializer for Active Record models.
1180
+
1181
+ Can be enabled with `config.active_record.marshalling_format_version = 7.1`.
1182
+
1183
+ *Jean Boussier*
1184
+
1185
+ * Allow specifying where clauses with column-tuple syntax.
1163
1186
 
1164
- * Inspect time attributes with subsec and time zone offset.
1187
+ Querying through `#where` now accepts a new tuple-syntax which accepts, as
1188
+ a key, an array of columns and, as a value, an array of corresponding tuples.
1189
+ The key specifies a list of columns, while the value is an array of
1190
+ ordered-tuples that conform to the column list.
1191
+
1192
+ For instance:
1165
1193
 
1166
1194
  ```ruby
1167
- p Knot.create
1168
- => #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000 +0000">
1195
+ # Cpk::Book => Cpk::Book(author_id: integer, number: integer, title: string, revision: integer)
1196
+ # Cpk::Book.primary_key => ["author_id", "number"]
1197
+
1198
+ book = Cpk::Book.create!(author_id: 1, number: 1)
1199
+ Cpk::Book.where(Cpk::Book.primary_key => [[1, 2]]) # => [book]
1200
+
1201
+ # Topic => Topic(id: integer, title: string, author_name: string...)
1202
+
1203
+ Topic.where([:title, :author_name] => [["The Alchemist", "Paulo Coelho"], ["Harry Potter", "J.K Rowling"]])
1169
1204
  ```
1170
1205
 
1171
- *akinomaeni*, *Jonathan Hefner*
1206
+ *Paarth Madan*
1172
1207
 
1173
- * Deprecate passing a column to `type_cast`.
1208
+ * Allow warning codes to be ignore when reporting SQL warnings.
1174
1209
 
1175
- *Ryuta Kamizono*
1210
+ Active Record config that can ignore warning codes
1176
1211
 
1177
- * Deprecate `in_clause_length` and `allowed_index_name_length` in `DatabaseLimits`.
1212
+ ```ruby
1213
+ # Configure allowlist of warnings that should always be ignored
1214
+ config.active_record.db_warnings_ignore = [
1215
+ "1062", # MySQL Error 1062: Duplicate entry
1216
+ ]
1217
+ ```
1178
1218
 
1179
- *Ryuta Kamizono*
1219
+ This is supported for the MySQL and PostgreSQL adapters.
1180
1220
 
1181
- * Support bulk insert/upsert on relation to preserve scope values.
1221
+ *Nick Borromeo*
1182
1222
 
1183
- *Josef Šimánek*, *Ryuta Kamizono*
1223
+ * Introduce `:active_record_fixtures` lazy load hook.
1184
1224
 
1185
- * Preserve column comment value on changing column name on MySQL.
1225
+ Hooks defined with this name will be run whenever `TestFixtures` is included
1226
+ in a class.
1186
1227
 
1187
- *Islam Taha*
1228
+ ```ruby
1229
+ ActiveSupport.on_load(:active_record_fixtures) do
1230
+ self.fixture_paths << "test/fixtures"
1231
+ end
1188
1232
 
1189
- * Add support for `if_exists` option for removing an index.
1233
+ klass = Class.new
1234
+ klass.include(ActiveRecord::TestFixtures)
1190
1235
 
1191
- The `remove_index` method can take an `if_exists` option. If this is set to true an error won't be raised if the index doesn't exist.
1236
+ klass.fixture_paths # => ["test/fixtures"]
1237
+ ```
1192
1238
 
1193
- *Eileen M. Uchitelle*
1239
+ *Andrew Novoselac*
1194
1240
 
1195
- * Remove ibm_db, informix, mssql, oracle, and oracle12 Arel visitors which are not used in the code base.
1241
+ * Introduce `TestFixtures#fixture_paths`.
1196
1242
 
1197
- *Ryuta Kamizono*
1243
+ Multiple fixture paths can now be specified using the `#fixture_paths` accessor.
1244
+ Apps will continue to have `test/fixtures` as their one fixture path by default,
1245
+ but additional fixture paths can be specified.
1198
1246
 
1199
- * Prevent `build_association` from `touching` a parent record if the record isn't persisted for `has_one` associations.
1247
+ ```ruby
1248
+ ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
1249
+ ActiveSupport::TestCase.fixture_paths << "component2/test/fixtures"
1250
+ ```
1200
1251
 
1201
- Fixes #38219.
1252
+ `TestFixtures#fixture_path` is now deprecated.
1202
1253
 
1203
- *Josh Brody*
1254
+ *Andrew Novoselac*
1204
1255
 
1205
- * Add support for `if_not_exists` option for adding index.
1256
+ * Adds support for deferrable exclude constraints in PostgreSQL.
1206
1257
 
1207
- The `add_index` method respects `if_not_exists` option. If it is set to true
1208
- index won't be added.
1258
+ By default, exclude constraints in PostgreSQL are checked after each statement.
1259
+ This works for most use cases, but becomes a major limitation when replacing
1260
+ records with overlapping ranges by using multiple statements.
1209
1261
 
1210
- Usage:
1262
+ ```ruby
1263
+ exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :immediate
1264
+ ```
1265
+
1266
+ Passing `deferrable: :immediate` checks constraint after each statement,
1267
+ but allows manually deferring the check using `SET CONSTRAINTS ALL DEFERRED`
1268
+ within a transaction. This will cause the excludes to be checked after the transaction.
1269
+
1270
+ It's also possible to change the default behavior from an immediate check
1271
+ (after the statement), to a deferred check (after the transaction):
1211
1272
 
1212
1273
  ```ruby
1213
- add_index :users, :account_id, if_not_exists: true
1274
+ exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :deferred
1214
1275
  ```
1215
1276
 
1216
- The `if_not_exists` option passed to `create_table` also gets propagated to indexes
1217
- created within that migration so that if table and its indexes exist then there is no
1218
- attempt to create them again.
1277
+ *Hiroyuki Ishii*
1278
+
1279
+ * Respect `foreign_type` option to `delegated_type` for `{role}_class` method.
1219
1280
 
1220
- *Prathamesh Sonpatki*
1281
+ Usage of `delegated_type` with non-conventional `{role}_type` column names can now be specified with `foreign_type` option.
1282
+ This option is the same as `foreign_type` as forwarded to the underlying `belongs_to` association that `delegated_type` wraps.
1221
1283
 
1222
- * Add `ActiveRecord::Base#previously_new_record?` to show if a record was new before the last save.
1284
+ *Jason Karns*
1223
1285
 
1224
- *Tom Ward*
1286
+ * Add support for unique constraints (PostgreSQL-only).
1225
1287
 
1226
- * Support descending order for `find_each`, `find_in_batches`, and `in_batches`.
1288
+ ```ruby
1289
+ add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
1290
+ remove_unique_key :sections, name: "unique_section_position"
1291
+ ```
1227
1292
 
1228
- Batch processing methods allow you to work with the records in batches, greatly reducing memory consumption, but records are always batched from oldest id to newest.
1293
+ See PostgreSQL's [Unique Constraints](https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS) documentation for more on unique constraints.
1229
1294
 
1230
- This change allows reversing the order, batching from newest to oldest. This is useful when you need to process newer batches of records first.
1295
+ By default, unique constraints in PostgreSQL are checked after each statement.
1296
+ This works for most use cases, but becomes a major limitation when replacing
1297
+ records with unique column by using multiple statements.
1231
1298
 
1232
- Pass `order: :desc` to yield batches in descending order. The default remains `order: :asc`.
1299
+ An example of swapping unique columns between records.
1233
1300
 
1234
1301
  ```ruby
1235
- Person.find_each(order: :desc) do |person|
1236
- person.party_all_night!
1302
+ # position is unique column
1303
+ old_item = Item.create!(position: 1)
1304
+ new_item = Item.create!(position: 2)
1305
+
1306
+ Item.transaction do
1307
+ old_item.update!(position: 2)
1308
+ new_item.update!(position: 1)
1237
1309
  end
1238
1310
  ```
1239
1311
 
1240
- *Alexey Vasiliev*
1312
+ Using the default behavior, the transaction would fail when executing the
1313
+ first `UPDATE` statement.
1241
1314
 
1242
- * Fix `insert_all` with enum values.
1315
+ By passing the `:deferrable` option to the `add_unique_key` statement in
1316
+ migrations, it's possible to defer this check.
1243
1317
 
1244
- Fixes #38716.
1245
-
1246
- *Joel Blum*
1318
+ ```ruby
1319
+ add_unique_key :items, [:position], deferrable: :immediate
1320
+ ```
1247
1321
 
1248
- * Add support for `db:rollback:name` for multiple database applications.
1322
+ Passing `deferrable: :immediate` does not change the behaviour of the previous example,
1323
+ but allows manually deferring the check using `SET CONSTRAINTS ALL DEFERRED` within a transaction.
1324
+ This will cause the unique constraints to be checked after the transaction.
1249
1325
 
1250
- Multiple database applications will now raise if `db:rollback` is call and recommend using the `db:rollback:[NAME]` to rollback migrations.
1326
+ It's also possible to adjust the default behavior from an immediate
1327
+ check (after the statement), to a deferred check (after the transaction):
1251
1328
 
1252
- *Eileen M. Uchitelle*
1329
+ ```ruby
1330
+ add_unique_key :items, [:position], deferrable: :deferred
1331
+ ```
1253
1332
 
1254
- * `Relation#pick` now uses already loaded results instead of making another query.
1333
+ If you want to change an existing unique index to deferrable, you can use :using_index
1334
+ to create deferrable unique constraints.
1255
1335
 
1256
- *Eugene Kenny*
1336
+ ```ruby
1337
+ add_unique_key :items, deferrable: :deferred, using_index: "index_items_on_position"
1338
+ ```
1257
1339
 
1258
- * Deprecate using `return`, `break` or `throw` to exit a transaction block after writes.
1340
+ *Hiroyuki Ishii*
1259
1341
 
1260
- *Dylan Thacker-Smith*
1342
+ * Remove deprecated `Tasks::DatabaseTasks.schema_file_type`.
1261
1343
 
1262
- * Dump the schema or structure of a database when calling `db:migrate:name`.
1344
+ *Rafael Mendonça França*
1263
1345
 
1264
- In previous versions of Rails, `rails db:migrate` would dump the schema of the database. In Rails 6, that holds true (`rails db:migrate` dumps all databases' schemas), but `rails db:migrate:name` does not share that behavior.
1346
+ * Remove deprecated `config.active_record.partial_writes`.
1265
1347
 
1266
- Going forward, calls to `rails db:migrate:name` will dump the schema (or structure) of the database being migrated.
1348
+ *Rafael Mendonça França*
1267
1349
 
1268
- *Kyle Thompson*
1350
+ * Remove deprecated `ActiveRecord::Base` config accessors.
1269
1351
 
1270
- * Reset the `ActiveRecord::Base` connection after `rails db:migrate:name`.
1352
+ *Rafael Mendonça França*
1271
1353
 
1272
- When `rails db:migrate` has finished, it ensures the `ActiveRecord::Base` connection is reset to its original configuration. Going forward, `rails db:migrate:name` will have the same behavior.
1354
+ * Remove the `:include_replicas` argument from `configs_for`. Use `:include_hidden` argument instead.
1273
1355
 
1274
- *Kyle Thompson*
1356
+ *Eileen M. Uchitelle*
1275
1357
 
1276
- * Disallow calling `connected_to` on subclasses of `ActiveRecord::Base`.
1358
+ * Allow applications to lookup a config via a custom hash key.
1277
1359
 
1278
- Behavior has not changed here but the previous API could be misleading to people who thought it would switch connections for only that class. `connected_to` switches the context from which we are getting connections, not the connections themselves.
1360
+ If you have registered a custom config or want to find configs where the hash matches a specific key, now you can pass `config_key` to `configs_for`. For example if you have a `db_config` with the key `vitess` you can look up a database configuration hash by matching that key.
1279
1361
 
1280
- *Eileen M. Uchitelle*, *John Crepezzi*
1362
+ ```ruby
1363
+ ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary", config_key: :vitess)
1364
+ ActiveRecord::Base.configurations.configs_for(env_name: "development", config_key: :vitess)
1365
+ ```
1281
1366
 
1282
- * Add support for horizontal sharding to `connects_to` and `connected_to`.
1367
+ *Eileen M. Uchitelle*
1283
1368
 
1284
- Applications can now connect to multiple shards and switch between their shards in an application. Note that the shard swapping is still a manual process as this change does not include an API for automatic shard swapping.
1369
+ * Allow applications to register a custom database configuration handler.
1285
1370
 
1286
- Usage:
1371
+ Adds a mechanism for registering a custom handler for cases where you want database configurations to respond to custom methods. This is useful for non-Rails database adapters or tools like Vitess that you may want to configure differently from a standard `HashConfig` or `UrlConfig`.
1287
1372
 
1288
- Given the following configuration:
1373
+ Given the following database YAML we want the `animals` db to create a `CustomConfig` object instead while the `primary` database will be a `UrlConfig`:
1289
1374
 
1290
1375
  ```yaml
1291
- # config/database.yml
1292
- production:
1376
+ development:
1293
1377
  primary:
1294
- database: my_database
1295
- primary_shard_one:
1296
- database: my_database_shard_one
1378
+ url: postgres://localhost/primary
1379
+ animals:
1380
+ url: postgres://localhost/animals
1381
+ custom_config:
1382
+ sharded: 1
1297
1383
  ```
1298
1384
 
1299
- Connect to multiple shards:
1385
+ To register a custom handler first make a class that has your custom methods:
1300
1386
 
1301
1387
  ```ruby
1302
- class ApplicationRecord < ActiveRecord::Base
1303
- self.abstract_class = true
1388
+ class CustomConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
1389
+ def sharded?
1390
+ custom_config.fetch("sharded", false)
1391
+ end
1304
1392
 
1305
- connects_to shards: {
1306
- default: { writing: :primary },
1307
- shard_one: { writing: :primary_shard_one }
1308
- }
1393
+ private
1394
+ def custom_config
1395
+ configuration_hash.fetch(:custom_config)
1396
+ end
1397
+ end
1309
1398
  ```
1310
1399
 
1311
- Swap between shards in your controller / model code:
1400
+ Then register the config in an initializer:
1312
1401
 
1313
1402
  ```ruby
1314
- ActiveRecord::Base.connected_to(shard: :shard_one) do
1315
- # Read from shard one
1403
+ ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
1404
+ next unless config.key?(:custom_config)
1405
+ CustomConfig.new(env_name, name, url, config)
1316
1406
  end
1317
1407
  ```
1318
1408
 
1319
- The horizontal sharding API also supports read replicas. See guides for more details.
1409
+ When the application is booted, configuration hashes with the `:custom_config` key will be `CustomConfig` objects and respond to `sharded?`. Applications must handle the condition in which Active Record should use their custom handler.
1410
+
1411
+ *Eileen M. Uchitelle and John Crepezzi*
1412
+
1413
+ * `ActiveRecord::Base.serialize` no longer uses YAML by default.
1414
+
1415
+ YAML isn't particularly performant and can lead to security issues
1416
+ if not used carefully.
1417
+
1418
+ Unfortunately there isn't really any good serializers in Ruby's stdlib
1419
+ to replace it.
1420
+
1421
+ The obvious choice would be JSON, which is a fine format for this use case,
1422
+ however the JSON serializer in Ruby's stdlib isn't strict enough, as it fallback
1423
+ to casting unknown types to strings, which could lead to corrupted data.
1320
1424
 
1321
- *Eileen M. Uchitelle*, *John Crepezzi*
1425
+ Some third party JSON libraries like `Oj` have a suitable strict mode.
1322
1426
 
1323
- * Deprecate `spec_name` in favor of `name` on database configurations.
1427
+ So it's preferable that users choose a serializer based on their own constraints.
1324
1428
 
1325
- The accessors for `spec_name` on `configs_for` and `DatabaseConfig` are deprecated. Please use `name` instead.
1429
+ The original default can be restored by setting `config.active_record.default_column_serializer = YAML`.
1326
1430
 
1327
- Deprecated behavior:
1431
+ *Jean Boussier*
1432
+
1433
+ * `ActiveRecord::Base.serialize` signature changed.
1434
+
1435
+ Rather than a single positional argument that accepts two possible
1436
+ types of values, `serialize` now accepts two distinct keyword arguments.
1437
+
1438
+ Before:
1328
1439
 
1329
1440
  ```ruby
1330
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
1331
- db_config.spec_name
1441
+ serialize :content, JSON
1442
+ serialize :backtrace, Array
1332
1443
  ```
1333
1444
 
1334
- New behavior:
1445
+ After:
1335
1446
 
1336
1447
  ```ruby
1337
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary")
1338
- db_config.name
1448
+ serialize :content, coder: JSON
1449
+ serialize :backtrace, type: Array
1339
1450
  ```
1340
1451
 
1341
- *Eileen M. Uchitelle*
1452
+ *Jean Boussier*
1342
1453
 
1343
- * Add additional database-specific rake tasks for multi-database users.
1454
+ * YAML columns use `YAML.safe_dump` if available.
1344
1455
 
1345
- Previously, `rails db:create`, `rails db:drop`, and `rails db:migrate` were the only rails tasks that could operate on a single
1346
- database. For example:
1456
+ As of `psych 5.1.0`, `YAML.safe_dump` can now apply the same permitted
1457
+ types restrictions than `YAML.safe_load`.
1347
1458
 
1459
+ It's preferable to ensure the payload only use allowed types when we first
1460
+ try to serialize it, otherwise you may end up with invalid records in the
1461
+ database.
1462
+
1463
+ *Jean Boussier*
1464
+
1465
+ * `ActiveRecord::QueryLogs` better handle broken encoding.
1466
+
1467
+ It's not uncommon when building queries with BLOB fields to contain
1468
+ binary data. Unless the call carefully encode the string in ASCII-8BIT
1469
+ it generally end up being encoded in `UTF-8`, and `QueryLogs` would
1470
+ end up failing on it.
1471
+
1472
+ `ActiveRecord::QueryLogs` no longer depend on the query to be properly encoded.
1473
+
1474
+ *Jean Boussier*
1475
+
1476
+ * Fix a bug where `ActiveRecord::Generators::ModelGenerator` would not respect create_table_migration template overrides.
1477
+
1478
+ ```
1479
+ rails g model create_books title:string content:text
1348
1480
  ```
1349
- rails db:create
1350
- rails db:create:primary
1351
- rails db:create:animals
1352
- rails db:drop
1353
- rails db:drop:primary
1354
- rails db:drop:animals
1355
- rails db:migrate
1356
- rails db:migrate:primary
1357
- rails db:migrate:animals
1481
+ will now read from the create_table_migration.rb.tt template in the following locations in order:
1482
+ ```
1483
+ lib/templates/active_record/model/create_table_migration.rb
1484
+ lib/templates/active_record/migration/create_table_migration.rb
1358
1485
  ```
1359
1486
 
1360
- With these changes, `rails db:schema:dump`, `rails db:schema:load`, `rails db:structure:dump`, `rails db:structure:load` and
1361
- `rails db:test:prepare` can additionally operate on a single database. For example:
1487
+ *Spencer Neste*
1362
1488
 
1363
- ```
1364
- rails db:schema:dump
1365
- rails db:schema:dump:primary
1366
- rails db:schema:dump:animals
1367
- rails db:schema:load
1368
- rails db:schema:load:primary
1369
- rails db:schema:load:animals
1370
- rails db:structure:dump
1371
- rails db:structure:dump:primary
1372
- rails db:structure:dump:animals
1373
- rails db:structure:load
1374
- rails db:structure:load:primary
1375
- rails db:structure:load:animals
1376
- rails db:test:prepare
1377
- rails db:test:prepare:primary
1378
- rails db:test:prepare:animals
1489
+ * `ActiveRecord::Relation#explain` now accepts options.
1490
+
1491
+ For databases and adapters which support them (currently PostgreSQL
1492
+ and MySQL), options can be passed to `explain` to provide more
1493
+ detailed query plan analysis:
1494
+
1495
+ ```ruby
1496
+ Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)
1379
1497
  ```
1380
1498
 
1381
- *Kyle Thompson*
1499
+ *Reid Lynch*
1382
1500
 
1383
- * Add support for `strict_loading` mode on association declarations.
1501
+ * Multiple `Arel::Nodes::SqlLiteral` nodes can now be added together to
1502
+ form `Arel::Nodes::Fragments` nodes. This allows joining several pieces
1503
+ of SQL.
1384
1504
 
1385
- Raise an error if attempting to load a record from an association that has been marked as `strict_loading` unless it was explicitly eager loaded.
1505
+ *Matthew Draper*, *Ole Friis*
1386
1506
 
1387
- Usage:
1507
+ * `ActiveRecord::Base#signed_id` raises if called on a new record.
1388
1508
 
1389
- ```ruby
1390
- class Developer < ApplicationRecord
1391
- has_many :projects, strict_loading: true
1392
- end
1509
+ Previously it would return an ID that was not usable, since it was based on `id = nil`.
1510
+
1511
+ *Alex Ghiculescu*
1393
1512
 
1394
- dev = Developer.first
1395
- dev.projects.first
1396
- # => ActiveRecord::StrictLoadingViolationError: The projects association is marked as strict_loading and cannot be lazily loaded.
1513
+ * Allow SQL warnings to be reported.
1514
+
1515
+ Active Record configs can be set to enable SQL warning reporting.
1516
+
1517
+ ```ruby
1518
+ # Configure action to take when SQL query produces warning
1519
+ config.active_record.db_warnings_action = :raise
1520
+
1521
+ # Configure allowlist of warnings that should always be ignored
1522
+ config.active_record.db_warnings_ignore = [
1523
+ /Invalid utf8mb4 character string/,
1524
+ "An exact warning message",
1525
+ ]
1397
1526
  ```
1398
1527
 
1399
- *Kevin Deisz*
1528
+ This is supported for the MySQL and PostgreSQL adapters.
1400
1529
 
1401
- * Add support for `strict_loading` mode to prevent lazy loading of records.
1530
+ *Adrianna Chang*, *Paarth Madan*
1402
1531
 
1403
- Raise an error if a parent record is marked as `strict_loading` and attempts to lazily load its associations. This is useful for finding places you may want to preload an association and avoid additional queries.
1532
+ * Add `#regroup` query method as a short-hand for `.unscope(:group).group(fields)`
1404
1533
 
1405
- Usage:
1534
+ Example:
1406
1535
 
1407
1536
  ```ruby
1408
- dev = Developer.strict_loading.first
1409
- dev.audit_logs.to_a
1410
- # => ActiveRecord::StrictLoadingViolationError: Developer is marked as strict_loading and AuditLog cannot be lazily loaded.
1537
+ Post.group(:title).regroup(:author)
1538
+ # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
1411
1539
  ```
1412
1540
 
1413
- *Eileen M. Uchitelle*, *Aaron Patterson*
1541
+ *Danielius Visockas*
1414
1542
 
1415
- * Add support for PostgreSQL 11+ partitioned indexes when using `upsert_all`.
1543
+ * PostgreSQL adapter method `enable_extension` now allows parameter to be `[schema_name.]<extension_name>`
1544
+ if the extension must be installed on another schema.
1416
1545
 
1417
- *Sebastián Palma*
1546
+ Example: `enable_extension('heroku_ext.hstore')`
1418
1547
 
1419
- * Adds support for `if_not_exists` to `add_column` and `if_exists` to `remove_column`.
1548
+ *Leonardo Luarte*
1420
1549
 
1421
- Applications can set their migrations to ignore exceptions raised when adding a column that already exists or when removing a column that does not exist.
1550
+ * Add `:include` option to `add_index`.
1422
1551
 
1423
- Example Usage:
1552
+ Add support for including non-key columns in indexes for PostgreSQL
1553
+ with the `INCLUDE` parameter.
1424
1554
 
1425
1555
  ```ruby
1426
- class AddColumnTitle < ActiveRecord::Migration[6.1]
1427
- def change
1428
- add_column :posts, :title, :string, if_not_exists: true
1429
- end
1430
- end
1556
+ add_index(:users, :email, include: [:id, :created_at])
1431
1557
  ```
1432
1558
 
1433
- ```ruby
1434
- class RemoveColumnTitle < ActiveRecord::Migration[6.1]
1435
- def change
1436
- remove_column :posts, :title, if_exists: true
1437
- end
1438
- end
1559
+ will result in:
1560
+
1561
+ ```sql
1562
+ CREATE INDEX index_users_on_email USING btree (email) INCLUDE (id, created_at)
1439
1563
  ```
1440
1564
 
1441
- *Eileen M. Uchitelle*
1565
+ *Steve Abrams*
1442
1566
 
1443
- * Regexp-escape table name for MS SQL Server.
1567
+ * `ActiveRecord::Relation`’s `#any?`, `#none?`, and `#one?` methods take an optional pattern
1568
+ argument, more closely matching their `Enumerable` equivalents.
1444
1569
 
1445
- Add `Regexp.escape` to one method in ActiveRecord, so that table names with regular expression characters in them work as expected. Since MS SQL Server uses "[" and "]" to quote table and column names, and those characters are regular expression characters, methods like `pluck` and `select` fail in certain cases when used with the MS SQL Server adapter.
1570
+ *George Claghorn*
1446
1571
 
1447
- *Larry Reid*
1572
+ * Add `ActiveRecord::Base.normalizes` for declaring attribute normalizations.
1448
1573
 
1449
- * Store advisory locks on their own named connection.
1574
+ An attribute normalization is applied when the attribute is assigned or
1575
+ updated, and the normalized value will be persisted to the database. The
1576
+ normalization is also applied to the corresponding keyword argument of query
1577
+ methods, allowing records to be queried using unnormalized values.
1450
1578
 
1451
- Previously advisory locks were taken out against a connection when a migration started. This works fine in single database applications but doesn't work well when migrations need to open new connections which results in the lock getting dropped.
1579
+ For example:
1452
1580
 
1453
- In order to fix this we are storing the advisory lock on a new connection with the connection specification name `AdvisoryLockBase`. The caveat is that we need to maintain at least 2 connections to a database while migrations are running in order to do this.
1581
+ ```ruby
1582
+ class User < ActiveRecord::Base
1583
+ normalizes :email, with: -> email { email.strip.downcase }
1584
+ normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
1585
+ end
1454
1586
 
1455
- *Eileen M. Uchitelle*, *John Crepezzi*
1587
+ user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
1588
+ user.email # => "cruise-control@example.com"
1456
1589
 
1457
- * Allow schema cache path to be defined in the database configuration file.
1590
+ user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
1591
+ user.email # => "cruise-control@example.com"
1592
+ user.email_before_type_cast # => "cruise-control@example.com"
1458
1593
 
1459
- For example:
1594
+ User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count # => 1
1595
+ User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
1460
1596
 
1461
- ```yaml
1462
- development:
1463
- adapter: postgresql
1464
- database: blog_development
1465
- pool: 5
1466
- schema_cache_path: tmp/schema/main.yml
1467
- ```
1597
+ User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ") # => true
1598
+ User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
1468
1599
 
1469
- *Katrina Owen*
1600
+ User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"
1601
+ ```
1470
1602
 
1471
- * Deprecate `#remove_connection` in favor of `#remove_connection_pool` when called on the handler.
1603
+ *Jonathan Hefner*
1472
1604
 
1473
- `#remove_connection` is deprecated in order to support returning a `DatabaseConfig` object instead of a `Hash`. Use `#remove_connection_pool`, `#remove_connection` will be removed in Rails 7.0.
1605
+ * Hide changes to before_committed! callback behaviour behind flag.
1474
1606
 
1475
- *Eileen M. Uchitelle*, *John Crepezzi*
1607
+ In #46525, behavior around before_committed! callbacks was changed so that callbacks
1608
+ would run on every enrolled record in a transaction, not just the first copy of a record.
1609
+ This change in behavior is now controlled by a configuration option,
1610
+ `config.active_record.before_committed_on_all_records`. It will be enabled by default on Rails 7.1.
1476
1611
 
1477
- * Deprecate `#default_hash` and it's alias `#[]` on database configurations.
1612
+ *Adrianna Chang*
1478
1613
 
1479
- Applications should use `configs_for`. `#default_hash` and `#[]` will be removed in Rails 7.0.
1614
+ * The `namespaced_controller` Query Log tag now matches the `controller` format
1480
1615
 
1481
- *Eileen M. Uchitelle*, *John Crepezzi*
1616
+ For example, a request processed by `NameSpaced::UsersController` will now log as:
1482
1617
 
1483
- * Add scale support to `ActiveRecord::Validations::NumericalityValidator`.
1618
+ ```
1619
+ :controller # "users"
1620
+ :namespaced_controller # "name_spaced/users"
1621
+ ```
1484
1622
 
1485
- *Gannon McGibbon*
1623
+ *Alex Ghiculescu*
1486
1624
 
1487
- * Find orphans by looking for missing relations through chaining `where.missing`:
1625
+ * Return only unique ids from ActiveRecord::Calculations#ids
1488
1626
 
1489
- Before:
1627
+ Updated ActiveRecord::Calculations#ids to only return the unique ids of the base model
1628
+ when using eager_load, preload and includes.
1490
1629
 
1491
1630
  ```ruby
1492
- Post.left_joins(:author).where(authors: { id: nil })
1631
+ Post.find_by(id: 1).comments.count
1632
+ # => 5
1633
+ Post.includes(:comments).where(id: 1).pluck(:id)
1634
+ # => [1, 1, 1, 1, 1]
1635
+ Post.includes(:comments).where(id: 1).ids
1636
+ # => [1]
1493
1637
  ```
1494
1638
 
1495
- After:
1639
+ *Joshua Young*
1496
1640
 
1497
- ```ruby
1498
- Post.where.missing(:author)
1499
- ```
1641
+ * Stop using `LOWER()` for case-insensitive queries on `citext` columns
1500
1642
 
1501
- *Tom Rossi*
1643
+ Previously, `LOWER()` was added for e.g. uniqueness validations with
1644
+ `case_sensitive: false`.
1645
+ It wasn't mentioned in the documentation that the index without `LOWER()`
1646
+ wouldn't be used in this case.
1502
1647
 
1503
- * Ensure `:reading` connections always raise if a write is attempted.
1648
+ *Phil Pirozhkov*
1504
1649
 
1505
- Now Rails will raise an `ActiveRecord::ReadOnlyError` if any connection on the reading handler attempts to make a write. If your reading role needs to write you should name the role something other than `:reading`.
1650
+ * Extract `#sync_timezone_changes` method in AbstractMysqlAdapter to enable subclasses
1651
+ to sync database timezone changes without overriding `#raw_execute`.
1506
1652
 
1507
- *Eileen M. Uchitelle*
1653
+ *Adrianna Chang*, *Paarth Madan*
1508
1654
 
1509
- * Deprecate `"primary"` as the `connection_specification_name` for `ActiveRecord::Base`.
1655
+ * Do not write additional new lines when dumping sql migration versions
1510
1656
 
1511
- `"primary"` has been deprecated as the `connection_specification_name` for `ActiveRecord::Base` in favor of using `"ActiveRecord::Base"`. This change affects calls to `ActiveRecord::Base.connection_handler.retrieve_connection` and `ActiveRecord::Base.connection_handler.remove_connection`. If you're calling these methods with `"primary"`, please switch to `"ActiveRecord::Base"`.
1657
+ This change updates the `insert_versions_sql` function so that the database insert string containing the current database migration versions does not end with two additional new lines.
1512
1658
 
1513
- *Eileen M. Uchitelle*, *John Crepezzi*
1659
+ *Misha Schwartz*
1514
1660
 
1515
- * Add `ActiveRecord::Validations::NumericalityValidator` with
1516
- support for casting floats using a database columns' precision value.
1661
+ * Fix `composed_of` value freezing and duplication.
1517
1662
 
1518
- *Gannon McGibbon*
1663
+ Previously composite values exhibited two confusing behaviors:
1519
1664
 
1520
- * Enforce fresh ETag header after a collection's contents change by adding
1521
- ActiveRecord::Relation#cache_key_with_version. This method will be used by
1522
- ActionController::ConditionalGet to ensure that when collection cache versioning
1523
- is enabled, requests using ConditionalGet don't return the same ETag header
1524
- after a collection is modified.
1665
+ - When reading a compositve value it'd _NOT_ be frozen, allowing it to get out of sync with its underlying database
1666
+ columns.
1667
+ - When writing a compositve value the argument would be frozen, potentially confusing the caller.
1525
1668
 
1526
- Fixes #38078.
1669
+ Currently, composite values instantiated based on database columns are frozen (addressing the first issue) and
1670
+ assigned compositve values are duplicated and the duplicate is frozen (addressing the second issue).
1527
1671
 
1528
- *Aaron Lipman*
1672
+ *Greg Navis*
1529
1673
 
1530
- * Skip test database when running `db:create` or `db:drop` in development
1531
- with `DATABASE_URL` set.
1674
+ * Fix redundant updates to the column insensitivity cache
1532
1675
 
1533
- *Brian Buchalter*
1676
+ Fixed redundant queries checking column capability for insensitive
1677
+ comparison.
1534
1678
 
1535
- * Don't allow mutations on the database configurations hash.
1679
+ *Phil Pirozhkov*
1536
1680
 
1537
- Freeze the configurations hash to disallow directly changing it. If applications need to change the hash, for example to create databases for parallelization, they should use the `DatabaseConfig` object directly.
1681
+ * Allow disabling methods generated by `ActiveRecord.enum`.
1538
1682
 
1539
- Before:
1683
+ *Alfred Dominic*
1540
1684
 
1541
- ```ruby
1542
- @db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
1543
- @db_config.configuration_hash.merge!(idle_timeout: "0.02")
1544
- ```
1685
+ * Avoid validating `belongs_to` association if it has not changed.
1545
1686
 
1546
- After:
1687
+ Previously, when updating a record, Active Record will perform an extra query to check for the presence of
1688
+ `belongs_to` associations (if the presence is configured to be mandatory), even if that attribute hasn't changed.
1689
+
1690
+ Currently, only `belongs_to`-related columns are checked for presence. It is possible to have orphaned records with
1691
+ this approach. To avoid this problem, you need to use a foreign key.
1692
+
1693
+ This behavior can be controlled by configuration:
1547
1694
 
1548
1695
  ```ruby
1549
- @db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
1550
- config = @db_config.configuration_hash.merge(idle_timeout: "0.02")
1551
- db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.spec_name, config)
1696
+ config.active_record.belongs_to_required_validates_foreign_key = false
1552
1697
  ```
1553
1698
 
1554
- *Eileen M. Uchitelle*, *John Crepezzi*
1699
+ and will be disabled by default with `config.load_defaults 7.1`.
1700
+
1701
+ *fatkodima*
1555
1702
 
1556
- * Remove `:connection_id` from the `sql.active_record` notification.
1703
+ * `has_one` and `belongs_to` associations now define a `reset_association` method
1704
+ on the owner model (where `association` is the name of the association). This
1705
+ method unloads the cached associate record, if any, and causes the next access
1706
+ to query it from the database.
1557
1707
 
1558
- *Aaron Patterson*, *Rafael Mendonça França*
1708
+ *George Claghorn*
1559
1709
 
1560
- * The `:name` key will no longer be returned as part of `DatabaseConfig#configuration_hash`. Please use `DatabaseConfig#owner_name` instead.
1710
+ * Allow per attribute setting of YAML permitted classes (safe load) and unsafe load.
1561
1711
 
1562
- *Eileen M. Uchitelle*, *John Crepezzi*
1712
+ *Carlos Palhares*
1563
1713
 
1564
- * ActiveRecord's `belongs_to_required_by_default` flag can now be set per model.
1714
+ * Add a build persistence method
1565
1715
 
1566
- You can now opt-out/opt-in specific models from having their associations required
1567
- by default.
1716
+ Provides a wrapper for `new`, to provide feature parity with `create`s
1717
+ ability to create multiple records from an array of hashes, using the
1718
+ same notation as the `build` method on associations.
1568
1719
 
1569
- This change is meant to ease the process of migrating all your models to have
1570
- their association required.
1720
+ *Sean Denny*
1571
1721
 
1572
- *Edouard Chin*
1722
+ * Raise on assignment to readonly attributes
1573
1723
 
1574
- * The `connection_config` method has been deprecated, please use `connection_db_config` instead which will return a `DatabaseConfigurations::DatabaseConfig` instead of a `Hash`.
1724
+ ```ruby
1725
+ class Post < ActiveRecord::Base
1726
+ attr_readonly :content
1727
+ end
1728
+ Post.create!(content: "cannot be updated")
1729
+ post.content # "cannot be updated"
1730
+ post.content = "something else" # => ActiveRecord::ReadonlyAttributeError
1731
+ ```
1575
1732
 
1576
- *Eileen M. Uchitelle*, *John Crepezzi*
1733
+ Previously, assignment would succeed but silently not write to the database.
1577
1734
 
1578
- * Retain explicit selections on the base model after applying `includes` and `joins`.
1735
+ This behavior can be controlled by configuration:
1579
1736
 
1580
- Resolves #34889.
1737
+ ```ruby
1738
+ config.active_record.raise_on_assign_to_attr_readonly = true
1739
+ ```
1581
1740
 
1582
- *Patrick Rebsch*
1741
+ and will be enabled by default with `config.load_defaults 7.1`.
1583
1742
 
1584
- * The `database` kwarg is deprecated without replacement because it can't be used for sharding and creates an issue if it's used during a request. Applications that need to create new connections should use `connects_to` instead.
1743
+ *Alex Ghiculescu*, *Hartley McGuire*
1585
1744
 
1586
- *Eileen M. Uchitelle*, *John Crepezzi*
1745
+ * Allow unscoping of preload and eager_load associations
1587
1746
 
1588
- * Allow attributes to be fetched from Arel node groupings.
1747
+ Added the ability to unscope preload and eager_load associations just like
1748
+ includes, joins, etc. See ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES
1749
+ for the full list of supported unscopable scopes.
1589
1750
 
1590
- *Jeff Emminger*, *Gannon McGibbon*
1751
+ ```ruby
1752
+ query.unscope(:eager_load, :preload).group(:id).select(:id)
1753
+ ```
1591
1754
 
1592
- * A database URL can now contain a querystring value that contains an equal sign. This is needed to support passing PostgreSQL `options`.
1755
+ *David Morehouse*
1593
1756
 
1594
- *Joshua Flanagan*
1757
+ * Add automatic filtering of encrypted attributes on inspect
1595
1758
 
1596
- * Calling methods like `establish_connection` with a `Hash` which is invalid (eg: no `adapter`) will now raise an error the same way as connections defined in `config/database.yml`.
1759
+ This feature is enabled by default but can be disabled with
1597
1760
 
1598
- *John Crepezzi*
1761
+ ```ruby
1762
+ config.active_record.encryption.add_to_filter_parameters = false
1763
+ ```
1599
1764
 
1600
- * Specifying `implicit_order_column` now subsorts the records by primary key if available to ensure deterministic results.
1765
+ *Hartley McGuire*
1601
1766
 
1602
- *Paweł Urbanek*
1767
+ * Clear locking column on #dup
1603
1768
 
1604
- * `where(attr => [])` now loads an empty result without making a query.
1769
+ This change fixes not to duplicate locking_column like id and timestamps.
1605
1770
 
1606
- *John Hawthorn*
1771
+ ```
1772
+ car = Car.create!
1773
+ car.touch
1774
+ car.lock_version #=> 1
1775
+ car.dup.lock_version #=> 0
1776
+ ```
1607
1777
 
1608
- * Fixed the performance regression for `primary_keys` introduced MySQL 8.0.
1778
+ *Shouichi Kamiya*, *Seonggi Yang*, *Ryohei UEDA*
1609
1779
 
1610
- *Hiroyuki Ishii*
1780
+ * Invalidate transaction as early as possible
1611
1781
 
1612
- * Add support for `belongs_to` to `has_many` inversing.
1782
+ After rescuing a `TransactionRollbackError` exception Rails invalidates transactions earlier in the flow
1783
+ allowing the framework to skip issuing the `ROLLBACK` statement in more cases.
1784
+ Only affects adapters that have `savepoint_errors_invalidate_transactions?` configured as `true`,
1785
+ which at this point is only applicable to the `mysql2` adapter.
1613
1786
 
1614
- *Gannon McGibbon*
1787
+ *Nikita Vasilevsky*
1615
1788
 
1616
- * Allow length configuration for `has_secure_token` method. The minimum length
1617
- is set at 24 characters.
1789
+ * Allow configuring columns list to be used in SQL queries issued by an `ActiveRecord::Base` object
1618
1790
 
1619
- Before:
1791
+ It is now possible to configure columns list that will be used to build an SQL query clauses when
1792
+ updating, deleting or reloading an `ActiveRecord::Base` object
1620
1793
 
1621
1794
  ```ruby
1622
- has_secure_token :auth_token
1795
+ class Developer < ActiveRecord::Base
1796
+ query_constraints :company_id, :id
1797
+ end
1798
+ developer = Developer.first.update(name: "Bob")
1799
+ # => UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
1623
1800
  ```
1624
1801
 
1625
- After:
1802
+ *Nikita Vasilevsky*
1626
1803
 
1627
- ```ruby
1628
- has_secure_token :default_token # 24 characters
1629
- has_secure_token :auth_token, length: 36 # 36 characters
1630
- has_secure_token :invalid_token, length: 12 # => ActiveRecord::SecureToken::MinimumLengthError
1631
- ```
1804
+ * Adds `validate` to foreign keys and check constraints in schema.rb
1632
1805
 
1633
- *Bernardo de Araujo*
1806
+ Previously, `schema.rb` would not record if `validate: false` had been used when adding a foreign key or check
1807
+ constraint, so restoring a database from the schema could result in foreign keys or check constraints being
1808
+ incorrectly validated.
1634
1809
 
1635
- * Deprecate `DatabaseConfigurations#to_h`. These connection hashes are still available via `ActiveRecord::Base.configurations.configs_for`.
1810
+ *Tommy Graves*
1636
1811
 
1637
- *Eileen Uchitelle*, *John Crepezzi*
1812
+ * Adapter `#execute` methods now accept an `allow_retry` option. When set to `true`, the SQL statement will be
1813
+ retried, up to the database's configured `connection_retries` value, upon encountering connection-related errors.
1638
1814
 
1639
- * Add `DatabaseConfig#configuration_hash` to return database configuration hashes with symbol keys, and use all symbol-key configuration hashes internally. Deprecate `DatabaseConfig#config` which returns a String-keyed `Hash` with the same values.
1815
+ *Adrianna Chang*
1640
1816
 
1641
- *John Crepezzi*, *Eileen Uchitelle*
1817
+ * Only trigger `after_commit :destroy` callbacks when a database row is deleted.
1642
1818
 
1643
- * Allow column names to be passed to `remove_index` positionally along with other options.
1819
+ This prevents `after_commit :destroy` callbacks from being triggered again
1820
+ when `destroy` is called multiple times on the same record.
1644
1821
 
1645
- Passing other options can be necessary to make `remove_index` correctly reversible.
1822
+ *Ben Sheldon*
1646
1823
 
1647
- Before:
1824
+ * Fix `ciphertext_for` for yet-to-be-encrypted values.
1648
1825
 
1649
- add_index :reports, :report_id # => works
1650
- add_index :reports, :report_id, unique: true # => works
1651
- remove_index :reports, :report_id # => works
1652
- remove_index :reports, :report_id, unique: true # => ArgumentError
1826
+ Previously, `ciphertext_for` returned the cleartext of values that had not
1827
+ yet been encrypted, such as with an unpersisted record:
1653
1828
 
1654
- After:
1829
+ ```ruby
1830
+ Post.encrypts :body
1655
1831
 
1656
- remove_index :reports, :report_id, unique: true # => works
1832
+ post = Post.create!(body: "Hello")
1833
+ post.ciphertext_for(:body)
1834
+ # => "{\"p\":\"abc..."
1657
1835
 
1658
- *Eugene Kenny*
1836
+ post.body = "World"
1837
+ post.ciphertext_for(:body)
1838
+ # => "World"
1839
+ ```
1659
1840
 
1660
- * Allow bulk `ALTER` statements to drop and recreate indexes with the same name.
1841
+ Now, `ciphertext_for` will always return the ciphertext of encrypted
1842
+ attributes:
1661
1843
 
1662
- *Eugene Kenny*
1844
+ ```ruby
1845
+ Post.encrypts :body
1663
1846
 
1664
- * `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
1847
+ post = Post.create!(body: "Hello")
1848
+ post.ciphertext_for(:body)
1849
+ # => "{\"p\":\"abc..."
1665
1850
 
1666
- *Eugene Kenny*
1851
+ post.body = "World"
1852
+ post.ciphertext_for(:body)
1853
+ # => "{\"p\":\"xyz..."
1854
+ ```
1667
1855
 
1668
- * Call `while_preventing_writes` directly from `connected_to`.
1856
+ *Jonathan Hefner*
1669
1857
 
1670
- In some cases application authors want to use the database switching middleware and make explicit calls with `connected_to`. It's possible for an app to turn off writes and not turn them back on by the time we call `connected_to(role: :writing)`.
1858
+ * Fix a bug where using groups and counts with long table names would return incorrect results.
1671
1859
 
1672
- This change allows apps to fix this by assuming if a role is writing we want to allow writes, except in the case it's explicitly turned off.
1860
+ *Shota Toguchi*, *Yusaku Ono*
1673
1861
 
1674
- *Eileen M. Uchitelle*
1862
+ * Fix encryption of column default values.
1675
1863
 
1676
- * Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter in the edge case when the query is terminated during filesort.
1864
+ Previously, encrypted attributes that used column default values appeared to
1865
+ be encrypted on create, but were not:
1677
1866
 
1678
- *Kir Shatrov*
1867
+ ```ruby
1868
+ Book.encrypts :name
1679
1869
 
1680
- * Stop trying to read yaml file fixtures when loading Active Record fixtures.
1870
+ book = Book.create!
1871
+ book.name
1872
+ # => "<untitled>"
1873
+ book.name_before_type_cast
1874
+ # => "{\"p\":\"abc..."
1875
+ book.reload.name_before_type_cast
1876
+ # => "<untitled>"
1877
+ ```
1681
1878
 
1682
- *Gannon McGibbon*
1879
+ Now, attributes with column default values are encrypted:
1683
1880
 
1684
- * Deprecate `.reorder(nil)` with `.first` / `.first!` taking non-deterministic result.
1881
+ ```ruby
1882
+ Book.encrypts :name
1685
1883
 
1686
- To continue taking non-deterministic result, use `.take` / `.take!` instead.
1884
+ book = Book.create!
1885
+ book.name
1886
+ # => "<untitled>"
1887
+ book.name_before_type_cast
1888
+ # => "{\"p\":\"abc..."
1889
+ book.reload.name_before_type_cast
1890
+ # => "{\"p\":\"abc..."
1891
+ ```
1687
1892
 
1688
- *Ryuta Kamizono*
1893
+ *Jonathan Hefner*
1689
1894
 
1690
- * Preserve user supplied joins order as much as possible.
1895
+ * Deprecate delegation from `Base` to `connection_handler`.
1691
1896
 
1692
- Fixes #36761, #34328, #24281, #12953.
1897
+ Calling `Base.clear_all_connections!`, `Base.clear_active_connections!`, `Base.clear_reloadable_connections!` and `Base.flush_idle_connections!` is deprecated. Please call these methods on the connection handler directly. In future Rails versions, the delegation from `Base` to the `connection_handler` will be removed.
1693
1898
 
1694
- *Ryuta Kamizono*
1899
+ *Eileen M. Uchitelle*
1695
1900
 
1696
- * Allow `matches_regex` and `does_not_match_regexp` on the MySQL Arel visitor.
1901
+ * Allow ActiveRecord::QueryMethods#reselect to receive hash values, similar to ActiveRecord::QueryMethods#select
1697
1902
 
1698
- *James Pearson*
1903
+ *Sampat Badhe*
1699
1904
 
1700
- * Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section.
1905
+ * Validate options when managing columns and tables in migrations.
1701
1906
 
1702
- *Tongfei Gao*
1907
+ If an invalid option is passed to a migration method like `create_table` and `add_column`, an error will be raised
1908
+ instead of the option being silently ignored. Validation of the options will only be applied for new migrations
1909
+ that are created.
1703
1910
 
1704
- * Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
1911
+ *Guo Xiang Tan*, *George Wambold*
1705
1912
 
1706
- *John Crepezzi*, *Eileen Uchitelle*
1913
+ * Update query log tags to use the [SQLCommenter](https://open-telemetry.github.io/opentelemetry-sqlcommenter/) format by default. See [#46179](https://github.com/rails/rails/issues/46179)
1707
1914
 
1708
- * Add a warning for enum elements with 'not_' prefix.
1915
+ To opt out of SQLCommenter-formatted query log tags, set `config.active_record.query_log_tags_format = :legacy`. By default, this is set to `:sqlcommenter`.
1709
1916
 
1710
- class Foo
1711
- enum status: [:sent, :not_sent]
1712
- end
1917
+ *Modulitos* and *Iheanyi*
1713
1918
 
1714
- *Edu Depetris*
1919
+ * Allow any ERB in the database.yml when creating rake tasks.
1715
1920
 
1716
- * Make currency symbols optional for money column type in PostgreSQL.
1921
+ Any ERB can be used in `database.yml` even if it accesses environment
1922
+ configurations.
1717
1923
 
1718
- *Joel Schneider*
1924
+ Deprecates `config.active_record.suppress_multiple_database_warning`.
1719
1925
 
1720
- * Add support for beginless ranges, introduced in Ruby 2.7.
1926
+ *Eike Send*
1721
1927
 
1722
- *Josh Goodall*
1928
+ * Add table to error for duplicate column definitions.
1723
1929
 
1724
- * Add `database_exists?` method to connection adapters to check if a database exists.
1930
+ If a migration defines duplicate columns for a table, the error message
1931
+ shows which table it concerns.
1725
1932
 
1726
- *Guilherme Mansur*
1933
+ *Petrik de Heus*
1727
1934
 
1728
- * Loading the schema for a model that has no `table_name` raises a `TableNotSpecified` error.
1935
+ * Fix erroneous nil default precision on virtual datetime columns.
1729
1936
 
1730
- *Guilherme Mansur*, *Eugene Kenny*
1937
+ Prior to this change, virtual datetime columns did not have the same
1938
+ default precision as regular datetime columns, resulting in the following
1939
+ being erroneously equivalent:
1731
1940
 
1732
- * PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
1941
+ t.virtual :name, type: datetime, as: "expression"
1942
+ t.virtual :name, type: datetime, precision: nil, as: "expression"
1733
1943
 
1734
- Fixes #36022.
1944
+ This change fixes the default precision lookup, so virtual and regular
1945
+ datetime column default precisions match.
1735
1946
 
1736
- *Ryuta Kamizono*
1947
+ *Sam Bostock*
1948
+
1949
+ * Use connection from `#with_raw_connection` in `#quote_string`.
1950
+
1951
+ This ensures that the string quoting is wrapped in the reconnect and retry logic
1952
+ that `#with_raw_connection` offers.
1737
1953
 
1738
- * Make ActiveRecord `ConnectionPool.connections` method thread-safe.
1954
+ *Adrianna Chang*
1739
1955
 
1740
- Fixes #36465.
1956
+ * Add `expires_at` option to `signed_id`.
1741
1957
 
1742
- *Jeff Doering*
1958
+ *Shouichi Kamiya*
1743
1959
 
1744
- * Add support for multiple databases to `rails db:abort_if_pending_migrations`.
1960
+ * Allow applications to set retry deadline for query retries.
1745
1961
 
1746
- *Mark Lee*
1962
+ Building on the work done in #44576 and #44591, we extend the logic that automatically
1963
+ reconnects database connections to take into account a timeout limit. We won't retry
1964
+ a query if a given amount of time has elapsed since the query was first attempted. This
1965
+ value defaults to nil, meaning that all retryable queries are retried regardless of time elapsed,
1966
+ but this can be changed via the `retry_deadline` option in the database config.
1747
1967
 
1748
- * Fix sqlite3 collation parsing when using decimal columns.
1968
+ *Adrianna Chang*
1749
1969
 
1750
- *Martin R. Schuster*
1970
+ * Fix a case where the query cache can return wrong values. See #46044
1751
1971
 
1752
- * Fix invalid schema when primary key column has a comment.
1972
+ *Aaron Patterson*
1973
+
1974
+ * Support MySQL's ssl-mode option for MySQLDatabaseTasks.
1753
1975
 
1754
- Fixes #29966.
1976
+ Verifying the identity of the database server requires setting the ssl-mode
1977
+ option to VERIFY_CA or VERIFY_IDENTITY. This option was previously ignored
1978
+ for MySQL database tasks like creating a database and dumping the structure.
1755
1979
 
1756
- *Guilherme Goettems Schneider*
1980
+ *Petrik de Heus*
1757
1981
 
1758
- * Fix table comment also being applied to the primary key column.
1982
+ * Move `ActiveRecord::InternalMetadata` to an independent object.
1759
1983
 
1760
- *Guilherme Goettems Schneider*
1984
+ `ActiveRecord::InternalMetadata` no longer inherits from `ActiveRecord::Base` and is now an independent object that should be instantiated with a `connection`. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: `ActiveRecord::Base.connection.schema_migration`.
1985
+
1986
+ *Eileen M. Uchitelle*
1761
1987
 
1762
- * Allow generated `create_table` migrations to include or skip timestamps.
1988
+ * Deprecate quoting `ActiveSupport::Duration` as an integer
1989
+
1990
+ Using ActiveSupport::Duration as an interpolated bind parameter in a SQL
1991
+ string template is deprecated. To avoid this warning, you should explicitly
1992
+ convert the duration to a more specific database type. For example, if you
1993
+ want to use a duration as an integer number of seconds:
1994
+ ```
1995
+ Record.where("duration = ?", 1.hour.to_i)
1996
+ ```
1997
+ If you want to use a duration as an ISO 8601 string:
1998
+ ```
1999
+ Record.where("duration = ?", 1.hour.iso8601)
2000
+ ```
2001
+
2002
+ *Aram Greenman*
2003
+
2004
+ * Allow `QueryMethods#in_order_of` to order by a string column name.
2005
+
2006
+ ```ruby
2007
+ Post.in_order_of("id", [4,2,3,1]).to_a
2008
+ Post.joins(:author).in_order_of("authors.name", ["Bob", "Anna", "John"]).to_a
2009
+ ```
2010
+
2011
+ *Igor Kasyanchuk*
2012
+
2013
+ * Move `ActiveRecord::SchemaMigration` to an independent object.
2014
+
2015
+ `ActiveRecord::SchemaMigration` no longer inherits from `ActiveRecord::Base` and is now an independent object that should be instantiated with a `connection`. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: `ActiveRecord::Base.connection.schema_migration`.
2016
+
2017
+ *Eileen M. Uchitelle*
2018
+
2019
+ * Deprecate `all_connection_pools` and make `connection_pool_list` more explicit.
2020
+
2021
+ Following on #45924 `all_connection_pools` is now deprecated. `connection_pool_list` will either take an explicit role or applications can opt into the new behavior by passing `:all`.
2022
+
2023
+ *Eileen M. Uchitelle*
2024
+
2025
+ * Fix connection handler methods to operate on all pools.
2026
+
2027
+ `active_connections?`, `clear_active_connections!`, `clear_reloadable_connections!`, `clear_all_connections!`, and `flush_idle_connections!` now operate on all pools by default. Previously they would default to using the `current_role` or `:writing` role unless specified.
2028
+
2029
+ *Eileen M. Uchitelle*
2030
+
2031
+
2032
+ * Allow ActiveRecord::QueryMethods#select to receive hash values.
2033
+
2034
+ Currently, `select` might receive only raw sql and symbols to define columns and aliases to select.
2035
+
2036
+ With this change we can provide `hash` as argument, for example:
2037
+
2038
+ ```ruby
2039
+ Post.joins(:comments).select(posts: [:id, :title, :created_at], comments: [:id, :body, :author_id])
2040
+ #=> "SELECT \"posts\".\"id\", \"posts\".\"title\", \"posts\".\"created_at\", \"comments\".\"id\", \"comments\".\"body\", \"comments\".\"author_id\"
2041
+ # FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
2042
+
2043
+ Post.joins(:comments).select(posts: { id: :post_id, title: :post_title }, comments: { id: :comment_id, body: :comment_body })
2044
+ #=> "SELECT posts.id as post_id, posts.title as post_title, comments.id as comment_id, comments.body as comment_body
2045
+ # FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
2046
+ ```
2047
+ *Oleksandr Holubenko*, *Josef Šimánek*, *Jean Boussier*
2048
+
2049
+ * Adapts virtual attributes on `ActiveRecord::Persistence#becomes`.
2050
+
2051
+ When source and target classes have a different set of attributes adapts
2052
+ attributes such that the extra attributes from target are added.
2053
+
2054
+ ```ruby
2055
+ class Person < ApplicationRecord
2056
+ end
2057
+
2058
+ class WebUser < Person
2059
+ attribute :is_admin, :boolean
2060
+ after_initialize :set_admin
2061
+
2062
+ def set_admin
2063
+ write_attribute(:is_admin, email =~ /@ourcompany\.com$/)
2064
+ end
2065
+ end
2066
+
2067
+ person = Person.find_by(email: "email@ourcompany.com")
2068
+ person.respond_to? :is_admin
2069
+ # => false
2070
+ person.becomes(WebUser).is_admin?
2071
+ # => true
2072
+ ```
2073
+
2074
+ *Jacopo Beschi*, *Sampson Crowley*
2075
+
2076
+ * Fix `ActiveRecord::QueryMethods#in_order_of` to include `nil`s, to match the
2077
+ behavior of `Enumerable#in_order_of`.
2078
+
2079
+ For example, `Post.in_order_of(:title, [nil, "foo"])` will now include posts
2080
+ with `nil` titles, the same as `Post.all.to_a.in_order_of(:title, [nil, "foo"])`.
2081
+
2082
+ *fatkodima*
2083
+
2084
+ * Optimize `add_timestamps` to use a single SQL statement.
2085
+
2086
+ ```ruby
2087
+ add_timestamps :my_table
2088
+ ```
2089
+
2090
+ Now results in the following SQL:
2091
+
2092
+ ```sql
2093
+ ALTER TABLE "my_table" ADD COLUMN "created_at" datetime(6) NOT NULL, ADD COLUMN "updated_at" datetime(6) NOT NULL
2094
+ ```
2095
+
2096
+ *Iliana Hadzhiatanasova*
2097
+
2098
+ * Add `drop_enum` migration command for PostgreSQL
2099
+
2100
+ This does the inverse of `create_enum`. Before dropping an enum, ensure you have
2101
+ dropped columns that depend on it.
2102
+
2103
+ *Alex Ghiculescu*
2104
+
2105
+ * Adds support for `if_exists` option when removing a check constraint.
2106
+
2107
+ The `remove_check_constraint` method now accepts an `if_exists` option. If set
2108
+ to true an error won't be raised if the check constraint doesn't exist.
2109
+
2110
+ *Margaret Parsa* and *Aditya Bhutani*
2111
+
2112
+ * `find_or_create_by` now try to find a second time if it hits a unicity constraint.
2113
+
2114
+ `find_or_create_by` always has been inherently racy, either creating multiple
2115
+ duplicate records or failing with `ActiveRecord::RecordNotUnique` depending on
2116
+ whether a proper unicity constraint was set.
2117
+
2118
+ `create_or_find_by` was introduced for this use case, however it's quite wasteful
2119
+ when the record is expected to exist most of the time, as INSERT require to send
2120
+ more data than SELECT and require more work from the database. Also on some
2121
+ databases it can actually consume a primary key increment which is undesirable.
2122
+
2123
+ So for case where most of the time the record is expected to exist, `find_or_create_by`
2124
+ can be made race-condition free by re-trying the `find` if the `create` failed
2125
+ with `ActiveRecord::RecordNotUnique`. This assumes that the table has the proper
2126
+ unicity constraints, if not, `find_or_create_by` will still lead to duplicated records.
2127
+
2128
+ *Jean Boussier*, *Alex Kitchens*
2129
+
2130
+ * Introduce a simpler constructor API for ActiveRecord database adapters.
2131
+
2132
+ Previously the adapter had to know how to build a new raw connection to
2133
+ support reconnect, but also expected to be passed an initial already-
2134
+ established connection.
2135
+
2136
+ When manually creating an adapter instance, it will now accept a single
2137
+ config hash, and only establish the real connection on demand.
2138
+
2139
+ *Matthew Draper*
2140
+
2141
+ * Avoid redundant `SELECT 1` connection-validation query during DB pool
2142
+ checkout when possible.
2143
+
2144
+ If the first query run during a request is known to be idempotent, it can be
2145
+ used directly to validate the connection, saving a network round-trip.
2146
+
2147
+ *Matthew Draper*
2148
+
2149
+ * Automatically reconnect broken database connections when safe, even
2150
+ mid-request.
2151
+
2152
+ When an error occurs while attempting to run a known-idempotent query, and
2153
+ not inside a transaction, it is safe to immediately reconnect to the
2154
+ database server and try again, so this is now the default behavior.
2155
+
2156
+ This new default should always be safe -- to support that, it's consciously
2157
+ conservative about which queries are considered idempotent -- but if
2158
+ necessary it can be disabled by setting the `connection_retries` connection
2159
+ option to `0`.
2160
+
2161
+ *Matthew Draper*
2162
+
2163
+ * Avoid removing a PostgreSQL extension when there are dependent objects.
2164
+
2165
+ Previously, removing an extension also implicitly removed dependent objects. Now, this will raise an error.
2166
+
2167
+ You can force removing the extension:
2168
+
2169
+ ```ruby
2170
+ disable_extension :citext, force: :cascade
2171
+ ```
2172
+
2173
+ Fixes #29091.
2174
+
2175
+ *fatkodima*
2176
+
2177
+ * Allow nested functions as safe SQL string
2178
+
2179
+ *Michael Siegfried*
2180
+
2181
+ * Allow `destroy_association_async_job=` to be configured with a class string instead of a constant.
2182
+
2183
+ Defers an autoloading dependency between `ActiveRecord::Base` and `ActiveJob::Base`
2184
+ and moves the configuration of `ActiveRecord::DestroyAssociationAsyncJob`
2185
+ from ActiveJob to ActiveRecord.
2186
+
2187
+ Deprecates `ActiveRecord::ActiveJobRequiredError` and now raises a `NameError`
2188
+ if the job class is unloadable or an `ActiveRecord::ConfigurationError` if
2189
+ `dependent: :destroy_async` is declared on an association but there is no job
2190
+ class configured.
2191
+
2192
+ *Ben Sheldon*
2193
+
2194
+ * Fix `ActiveRecord::Store` to serialize as a regular Hash
2195
+
2196
+ Previously it would serialize as an `ActiveSupport::HashWithIndifferentAccess`
2197
+ which is wasteful and cause problem with YAML safe_load.
2198
+
2199
+ *Jean Boussier*
2200
+
2201
+ * Add `timestamptz` as a time zone aware type for PostgreSQL
2202
+
2203
+ This is required for correctly parsing `timestamp with time zone` values in your database.
2204
+
2205
+ If you don't want this, you can opt out by adding this initializer:
2206
+
2207
+ ```ruby
2208
+ ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
2209
+ ```
2210
+
2211
+ *Alex Ghiculescu*
2212
+
2213
+ * Add new `ActiveRecord::Base.generates_token_for` API.
2214
+
2215
+ Currently, `signed_id` fulfills the role of generating tokens for e.g.
2216
+ resetting a password. However, signed IDs cannot reflect record state, so
2217
+ if a token is intended to be single-use, it must be tracked in a database at
2218
+ least until it expires.
2219
+
2220
+ With `generates_token_for`, a token can embed data from a record. When
2221
+ using the token to fetch the record, the data from the token and the current
2222
+ data from the record will be compared. If the two do not match, the token
2223
+ will be treated as invalid, the same as if it had expired. For example:
2224
+
2225
+ ```ruby
2226
+ class User < ActiveRecord::Base
2227
+ has_secure_password
2228
+
2229
+ generates_token_for :password_reset, expires_in: 15.minutes do
2230
+ # A password's BCrypt salt changes when the password is updated.
2231
+ # By embedding (part of) the salt in a token, the token will
2232
+ # expire when the password is updated.
2233
+ BCrypt::Password.new(password_digest).salt[-10..]
2234
+ end
2235
+ end
2236
+
2237
+ user = User.first
2238
+ token = user.generate_token_for(:password_reset)
2239
+
2240
+ User.find_by_token_for(:password_reset, token) # => user
2241
+
2242
+ user.update!(password: "new password")
2243
+ User.find_by_token_for(:password_reset, token) # => nil
2244
+ ```
2245
+
2246
+ *Jonathan Hefner*
2247
+
2248
+ * Optimize Active Record batching for whole table iterations.
2249
+
2250
+ Previously, `in_batches` got all the ids and constructed an `IN`-based query for each batch.
2251
+ When iterating over the whole tables, this approach is not optimal as it loads unneeded ids and
2252
+ `IN` queries with lots of items are slow.
2253
+
2254
+ Now, whole table iterations use range iteration (`id >= x AND id <= y`) by default which can make iteration
2255
+ several times faster. E.g., tested on a PostgreSQL table with 10 million records: querying (`253s` vs `30s`),
2256
+ updating (`288s` vs `124s`), deleting (`268s` vs `83s`).
2257
+
2258
+ Only whole table iterations use this style of iteration by default. You can disable this behavior by passing `use_ranges: false`.
2259
+ If you iterate over the table and the only condition is, e.g., `archived_at: nil` (and only a tiny fraction
2260
+ of the records are archived), it makes sense to opt in to this approach:
2261
+
2262
+ ```ruby
2263
+ Project.where(archived_at: nil).in_batches(use_ranges: true) do |relation|
2264
+ # do something
2265
+ end
2266
+ ```
2267
+
2268
+ See #45414 for more details.
2269
+
2270
+ *fatkodima*
2271
+
2272
+ * `.with` query method added. Construct common table expressions with ease and get `ActiveRecord::Relation` back.
2273
+
2274
+ ```ruby
2275
+ Post.with(posts_with_comments: Post.where("comments_count > ?", 0))
2276
+ # => ActiveRecord::Relation
2277
+ # WITH posts_with_comments AS (SELECT * FROM posts WHERE (comments_count > 0)) SELECT * FROM posts
2278
+ ```
2279
+
2280
+ *Vlado Cingel*
2281
+
2282
+ * Don't establish a new connection if an identical pool exists already.
2283
+
2284
+ Previously, if `establish_connection` was called on a class that already had an established connection, the existing connection would be removed regardless of whether it was the same config. Now if a pool is found with the same values as the new connection, the existing connection will be returned instead of creating a new one.
2285
+
2286
+ This has a slight change in behavior if application code is depending on a new connection being established regardless of whether it's identical to an existing connection. If the old behavior is desirable, applications should call `ActiveRecord::Base#remove_connection` before establishing a new one. Calling `establish_connection` with a different config works the same way as it did previously.
2287
+
2288
+ *Eileen M. Uchitelle*
2289
+
2290
+ * Update `db:prepare` task to load schema when an uninitialized database exists, and dump schema after migrations.
2291
+
2292
+ *Ben Sheldon*
2293
+
2294
+ * Fix supporting timezone awareness for `tsrange` and `tstzrange` array columns.
2295
+
2296
+ ```ruby
2297
+ # In database migrations
2298
+ add_column :shops, :open_hours, :tsrange, array: true
2299
+ # In app config
2300
+ ActiveRecord::Base.time_zone_aware_types += [:tsrange]
2301
+ # In the code times are properly converted to app time zone
2302
+ Shop.create!(open_hours: [Time.current..8.hour.from_now])
2303
+ ```
2304
+
2305
+ *Wojciech Wnętrzak*
2306
+
2307
+ * Introduce strategy pattern for executing migrations.
2308
+
2309
+ By default, migrations will use a strategy object that delegates the method
2310
+ to the connection adapter. Consumers can implement custom strategy objects
2311
+ to change how their migrations run.
2312
+
2313
+ *Adrianna Chang*
2314
+
2315
+ * Add adapter option disallowing foreign keys
2316
+
2317
+ This adds a new option to be added to `database.yml` which enables skipping
2318
+ foreign key constraints usage even if the underlying database supports them.
2319
+
2320
+ Usage:
2321
+ ```yaml
2322
+ development:
2323
+ <<: *default
2324
+ database: storage/development.sqlite3
2325
+ foreign_keys: false
2326
+ ```
2327
+
2328
+ *Paulo Barros*
2329
+
2330
+ * Add configurable deprecation warning for singular associations
2331
+
2332
+ This adds a deprecation warning when using the plural name of a singular associations in `where`.
2333
+ It is possible to opt into the new more performant behavior with `config.active_record.allow_deprecated_singular_associations_name = false`
2334
+
2335
+ *Adam Hess*
2336
+
2337
+ * Run transactional callbacks on the freshest instance to save a given
2338
+ record within a transaction.
2339
+
2340
+ When multiple Active Record instances change the same record within a
2341
+ transaction, Rails runs `after_commit` or `after_rollback` callbacks for
2342
+ only one of them. `config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction`
2343
+ was added to specify how Rails chooses which instance receives the
2344
+ callbacks. The framework defaults were changed to use the new logic.
2345
+
2346
+ When `config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction`
2347
+ is `true`, transactional callbacks are run on the first instance to save,
2348
+ even though its instance state may be stale.
2349
+
2350
+ When it is `false`, which is the new framework default starting with version
2351
+ 7.1, transactional callbacks are run on the instances with the freshest
2352
+ instance state. Those instances are chosen as follows:
2353
+
2354
+ - In general, run transactional callbacks on the last instance to save a
2355
+ given record within the transaction.
2356
+ - There are two exceptions:
2357
+ - If the record is created within the transaction, then updated by
2358
+ another instance, `after_create_commit` callbacks will be run on the
2359
+ second instance. This is instead of the `after_update_commit`
2360
+ callbacks that would naively be run based on that instance’s state.
2361
+ - If the record is destroyed within the transaction, then
2362
+ `after_destroy_commit` callbacks will be fired on the last destroyed
2363
+ instance, even if a stale instance subsequently performed an update
2364
+ (which will have affected 0 rows).
2365
+
2366
+ *Cameron Bothner and Mitch Vollebregt*
2367
+
2368
+ * Enable strict strings mode for `SQLite3Adapter`.
2369
+
2370
+ Configures SQLite with a strict strings mode, which disables double-quoted string literals.
2371
+
2372
+ SQLite has some quirks around double-quoted string literals.
2373
+ It first tries to consider double-quoted strings as identifier names, but if they don't exist
2374
+ it then considers them as string literals. Because of this, typos can silently go unnoticed.
2375
+ For example, it is possible to create an index for a non existing column.
2376
+ See [SQLite documentation](https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted) for more details.
2377
+
2378
+ If you don't want this behavior, you can disable it via:
2379
+
2380
+ ```ruby
2381
+ # config/application.rb
2382
+ config.active_record.sqlite3_adapter_strict_strings_by_default = false
2383
+ ```
2384
+
2385
+ Fixes #27782.
2386
+
2387
+ *fatkodima*, *Jean Boussier*
2388
+
2389
+ * Resolve issue where a relation cache_version could be left stale.
2390
+
2391
+ Previously, when `reset` was called on a relation object it did not reset the cache_versions
2392
+ ivar. This led to a confusing situation where despite having the correct data the relation
2393
+ still reported a stale cache_version.
2394
+
2395
+ Usage:
2396
+
2397
+ ```ruby
2398
+ developers = Developer.all
2399
+ developers.cache_version
2400
+
2401
+ Developer.update_all(updated_at: Time.now.utc + 1.second)
2402
+
2403
+ developers.cache_version # Stale cache_version
2404
+ developers.reset
2405
+ developers.cache_version # Returns the current correct cache_version
2406
+ ```
2407
+
2408
+ Fixes #45341.
2409
+
2410
+ *Austen Madden*
2411
+
2412
+ * Add support for exclusion constraints (PostgreSQL-only).
2413
+
2414
+ ```ruby
2415
+ add_exclusion_constraint :invoices, "daterange(start_date, end_date) WITH &&", using: :gist, name: "invoices_date_overlap"
2416
+ remove_exclusion_constraint :invoices, name: "invoices_date_overlap"
2417
+ ```
2418
+
2419
+ See PostgreSQL's [`CREATE TABLE ... EXCLUDE ...`](https://www.postgresql.org/docs/12/sql-createtable.html#SQL-CREATETABLE-EXCLUDE) documentation for more on exclusion constraints.
2420
+
2421
+ *Alex Robbin*
2422
+
2423
+ * `change_column_null` raises if a non-boolean argument is provided
2424
+
2425
+ Previously if you provided a non-boolean argument, `change_column_null` would
2426
+ treat it as truthy and make your column nullable. This could be surprising, so now
2427
+ the input must be either `true` or `false`.
2428
+
2429
+ ```ruby
2430
+ change_column_null :table, :column, true # good
2431
+ change_column_null :table, :column, false # good
2432
+ change_column_null :table, :column, from: true, to: false # raises (previously this made the column nullable)
2433
+ ```
2434
+
2435
+ *Alex Ghiculescu*
2436
+
2437
+ * Enforce limit on table names length.
2438
+
2439
+ Fixes #45130.
2440
+
2441
+ *fatkodima*
2442
+
2443
+ * Adjust the minimum MariaDB version for check constraints support.
2444
+
2445
+ *Eddie Lebow*
2446
+
2447
+ * Fix Hstore deserialize regression.
2448
+
2449
+ *edsharp*
2450
+
2451
+ * Add validity for PostgreSQL indexes.
2452
+
2453
+ ```ruby
2454
+ connection.index_exists?(:users, :email, valid: true)
2455
+ connection.indexes(:users).select(&:valid?)
2456
+ ```
2457
+
2458
+ *fatkodima*
2459
+
2460
+ * Fix eager loading for models without primary keys.
2461
+
2462
+ *Anmol Chopra*, *Matt Lawrence*, and *Jonathan Hefner*
2463
+
2464
+ * Avoid validating a unique field if it has not changed and is backed by a unique index.
2465
+
2466
+ Previously, when saving a record, Active Record will perform an extra query to check for the
2467
+ uniqueness of each attribute having a `uniqueness` validation, even if that attribute hasn't changed.
2468
+ If the database has the corresponding unique index, then this validation can never fail for persisted
2469
+ records, and we could safely skip it.
2470
+
2471
+ *fatkodima*
2472
+
2473
+ * Stop setting `sql_auto_is_null`
2474
+
2475
+ Since version 5.5 the default has been off, we no longer have to manually turn it off.
2476
+
2477
+ *Adam Hess*
2478
+
2479
+ * Fix `touch` to raise an error for readonly columns.
2480
+
2481
+ *fatkodima*
2482
+
2483
+ * Add ability to ignore tables by regexp for SQL schema dumps.
2484
+
2485
+ ```ruby
2486
+ ActiveRecord::SchemaDumper.ignore_tables = [/^_/]
2487
+ ```
2488
+
2489
+ *fatkodima*
2490
+
2491
+ * Avoid queries when performing calculations on contradictory relations.
2492
+
2493
+ Previously calculations would make a query even when passed a
2494
+ contradiction, such as `User.where(id: []).count`. We no longer perform a
2495
+ query in that scenario.
2496
+
2497
+ This applies to the following calculations: `count`, `sum`, `average`,
2498
+ `minimum` and `maximum`
2499
+
2500
+ *Luan Vieira, John Hawthorn and Daniel Colson*
2501
+
2502
+ * Allow using aliased attributes with `insert_all`/`upsert_all`.
2503
+
2504
+ ```ruby
2505
+ class Book < ApplicationRecord
2506
+ alias_attribute :title, :name
2507
+ end
2508
+
2509
+ Book.insert_all [{ title: "Remote", author_id: 1 }], returning: :title
2510
+ ```
2511
+
2512
+ *fatkodima*
2513
+
2514
+ * Support encrypted attributes on columns with default db values.
2515
+
2516
+ This adds support for encrypted attributes defined on columns with default values.
2517
+ It will encrypt those values at creation time. Before, it would raise an
2518
+ error unless `config.active_record.encryption.support_unencrypted_data` was true.
2519
+
2520
+ *Jorge Manrubia* and *Dima Fatko*
2521
+
2522
+ * Allow overriding `reading_request?` in `DatabaseSelector::Resolver`
2523
+
2524
+ The default implementation checks if a request is a `get?` or `head?`,
2525
+ but you can now change it to anything you like. If the method returns true,
2526
+ `Resolver#read` gets called meaning the request could be served by the
2527
+ replica database.
2528
+
2529
+ *Alex Ghiculescu*
2530
+
2531
+ * Remove `ActiveRecord.legacy_connection_handling`.
2532
+
2533
+ *Eileen M. Uchitelle*
2534
+
2535
+ * `rails db:schema:{dump,load}` now checks `ENV["SCHEMA_FORMAT"]` before config
2536
+
2537
+ Since `rails db:structure:{dump,load}` was deprecated there wasn't a simple
2538
+ way to dump a schema to both SQL and Ruby formats. You can now do this with
2539
+ an environment variable. For example:
2540
+
2541
+ ```
2542
+ SCHEMA_FORMAT=sql rake db:schema:dump
2543
+ ```
2544
+
2545
+ *Alex Ghiculescu*
2546
+
2547
+ * Fixed MariaDB default function support.
2548
+
2549
+ Defaults would be written wrong in "db/schema.rb" and not work correctly
2550
+ if using `db:schema:load`. Further more the function name would be
2551
+ added as string content when saving new records.
2552
+
2553
+ *kaspernj*
2554
+
2555
+ * Add `active_record.destroy_association_async_batch_size` configuration
2556
+
2557
+ This allows applications to specify the maximum number of records that will
2558
+ be destroyed in a single background job by the `dependent: :destroy_async`
2559
+ association option. By default, the current behavior will remain the same:
2560
+ when a parent record is destroyed, all dependent records will be destroyed
2561
+ in a single background job. If the number of dependent records is greater
2562
+ than this configuration, the records will be destroyed in multiple
2563
+ background jobs.
2564
+
2565
+ *Nick Holden*
2566
+
2567
+ * Fix `remove_foreign_key` with `:if_exists` option when foreign key actually exists.
2568
+
2569
+ *fatkodima*
2570
+
2571
+ * Remove `--no-comments` flag in structure dumps for PostgreSQL
2572
+
2573
+ This broke some apps that used custom schema comments. If you don't want
2574
+ comments in your structure dump, you can use:
2575
+
2576
+ ```ruby
2577
+ ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
2578
+ ```
2579
+
2580
+ *Alex Ghiculescu*
2581
+
2582
+ * Reduce the memory footprint of fixtures accessors.
2583
+
2584
+ Until now fixtures accessors were eagerly defined using `define_method`.
2585
+ So the memory usage was directly dependent of the number of fixtures and
2586
+ test suites.
2587
+
2588
+ Instead fixtures accessors are now implemented with `method_missing`,
2589
+ so they incur much less memory and CPU overhead.
2590
+
2591
+ *Jean Boussier*
2592
+
2593
+ * Fix `config.active_record.destroy_association_async_job` configuration
2594
+
2595
+ `config.active_record.destroy_association_async_job` should allow
2596
+ applications to specify the job that will be used to destroy associated
2597
+ records in the background for `has_many` associations with the
2598
+ `dependent: :destroy_async` option. Previously, that was ignored, which
2599
+ meant the default `ActiveRecord::DestroyAssociationAsyncJob` always
2600
+ destroyed records in the background.
2601
+
2602
+ *Nick Holden*
2603
+
2604
+ * Fix `change_column_comment` to preserve column's AUTO_INCREMENT in the MySQL adapter
2605
+
2606
+ *fatkodima*
2607
+
2608
+ * Fix quoting of `ActiveSupport::Duration` and `Rational` numbers in the MySQL adapter.
2609
+
2610
+ *Kevin McPhillips*
2611
+
2612
+ * Allow column name with COLLATE (e.g., title COLLATE "C") as safe SQL string
2613
+
2614
+ *Shugo Maeda*
2615
+
2616
+ * Permit underscores in the VERSION argument to database rake tasks.
2617
+
2618
+ *Eddie Lebow*
2619
+
2620
+ * Reversed the order of `INSERT` statements in `structure.sql` dumps
2621
+
2622
+ This should decrease the likelihood of merge conflicts. New migrations
2623
+ will now be added at the top of the list.
2624
+
2625
+ For existing apps, there will be a large diff the next time `structure.sql`
2626
+ is generated.
2627
+
2628
+ *Alex Ghiculescu*, *Matt Larraz*
2629
+
2630
+ * Fix PG.connect keyword arguments deprecation warning on ruby 2.7
2631
+
2632
+ Fixes #44307.
2633
+
2634
+ *Nikita Vasilevsky*
2635
+
2636
+ * Fix dropping DB connections after serialization failures and deadlocks.
2637
+
2638
+ Prior to 6.1.4, serialization failures and deadlocks caused rollbacks to be
2639
+ issued for both real transactions and savepoints. This breaks MySQL which
2640
+ disallows rollbacks of savepoints following a deadlock.
2641
+
2642
+ 6.1.4 removed these rollbacks, for both transactions and savepoints, causing
2643
+ the DB connection to be left in an unknown state and thus discarded.
2644
+
2645
+ These rollbacks are now restored, except for savepoints on MySQL.
2646
+
2647
+ *Thomas Morgan*
2648
+
2649
+ * Make `ActiveRecord::ConnectionPool` Fiber-safe
2650
+
2651
+ When `ActiveSupport::IsolatedExecutionState.isolation_level` is set to `:fiber`,
2652
+ the connection pool now supports multiple Fibers from the same Thread checking
2653
+ out connections from the pool.
2654
+
2655
+ *Alex Matchneer*
2656
+
2657
+ * Add `update_attribute!` to `ActiveRecord::Persistence`
2658
+
2659
+ Similar to `update_attribute`, but raises `ActiveRecord::RecordNotSaved` when a `before_*` callback throws `:abort`.
2660
+
2661
+ ```ruby
2662
+ class Topic < ActiveRecord::Base
2663
+ before_save :check_title
2664
+
2665
+ def check_title
2666
+ throw(:abort) if title == "abort"
2667
+ end
2668
+ end
2669
+
2670
+ topic = Topic.create(title: "Test Title")
2671
+ # #=> #<Topic title: "Test Title">
2672
+ topic.update_attribute!(:title, "Another Title")
2673
+ # #=> #<Topic title: "Another Title">
2674
+ topic.update_attribute!(:title, "abort")
2675
+ # raises ActiveRecord::RecordNotSaved
2676
+ ```
2677
+
2678
+ *Drew Tempelmeyer*
2679
+
2680
+ * Avoid loading every record in `ActiveRecord::Relation#pretty_print`
2681
+
2682
+ ```ruby
2683
+ # Before
2684
+ pp Foo.all # Loads the whole table.
2685
+
2686
+ # After
2687
+ pp Foo.all # Shows 10 items and an ellipsis.
2688
+ ```
2689
+
2690
+ *Ulysse Buonomo*
2691
+
2692
+ * Change `QueryMethods#in_order_of` to drop records not listed in values.
2693
+
2694
+ `in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version.
2695
+
2696
+ *Kevin Newton*
2697
+
2698
+ * Allow named expression indexes to be revertible.
2699
+
2700
+ Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.
2701
+
2702
+ ```ruby
2703
+ add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
2704
+ ```
2705
+
2706
+ Fixes #43331.
2707
+
2708
+ *Oliver Günther*
2709
+
2710
+ * Fix incorrect argument in PostgreSQL structure dump tasks.
2711
+
2712
+ Updating the `--no-comment` argument added in Rails 7 to the correct `--no-comments` argument.
2713
+
2714
+ *Alex Dent*
2715
+
2716
+ * Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.
2717
+
2718
+ Reference/belongs_to in migrations with version 6.0 were creating columns as
2719
+ bigint instead of integer for the SQLite Adapter.
2720
+
2721
+ *Marcelo Lauxen*
2722
+
2723
+ * Fix `QueryMethods#in_order_of` to handle empty order list.
2724
+
2725
+ ```ruby
2726
+ Post.in_order_of(:id, []).to_a
2727
+ ```
2728
+
2729
+ Also more explicitly set the column as secondary order, so that any other
2730
+ value is still ordered.
2731
+
2732
+ *Jean Boussier*
2733
+
2734
+ * Fix quoting of column aliases generated by calculation methods.
2735
+
2736
+ Since the alias is derived from the table name, we can't assume the result
2737
+ is a valid identifier.
2738
+
2739
+ ```ruby
2740
+ class Test < ActiveRecord::Base
2741
+ self.table_name = '1abc'
2742
+ end
2743
+ Test.group(:id).count
2744
+ # syntax error at or near "1" (ActiveRecord::StatementInvalid)
2745
+ # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
2746
+ ```
2747
+
2748
+ *Jean Boussier*
2749
+
2750
+ * Add `authenticate_by` when using `has_secure_password`.
2751
+
2752
+ `authenticate_by` is intended to replace code like the following, which
2753
+ returns early when a user with a matching email is not found:
2754
+
2755
+ ```ruby
2756
+ User.find_by(email: "...")&.authenticate("...")
2757
+ ```
2758
+
2759
+ Such code is vulnerable to timing-based enumeration attacks, wherein an
2760
+ attacker can determine if a user account with a given email exists. After
2761
+ confirming that an account exists, the attacker can try passwords associated
2762
+ with that email address from other leaked databases, in case the user
2763
+ re-used a password across multiple sites (a common practice). Additionally,
2764
+ knowing an account email address allows the attacker to attempt a targeted
2765
+ phishing ("spear phishing") attack.
2766
+
2767
+ `authenticate_by` addresses the vulnerability by taking the same amount of
2768
+ time regardless of whether a user with a matching email is found:
2769
+
2770
+ ```ruby
2771
+ User.authenticate_by(email: "...", password: "...")
2772
+ ```
1763
2773
 
1764
- *Michael Duchemin*
2774
+ *Jonathan Hefner*
1765
2775
 
1766
2776
 
1767
- Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
2777
+ Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activerecord/CHANGELOG.md) for previous changes.