activerecord 7.0.4.3 → 7.1.3.4

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