activerecord 7.0.8.7 → 7.1.5.2

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