activerecord 7.0.8.7 → 7.1.5.1

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