activerecord 7.2.2.1 → 8.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +523 -677
  3. data/README.rdoc +2 -2
  4. data/lib/active_record/association_relation.rb +1 -0
  5. data/lib/active_record/associations/alias_tracker.rb +6 -4
  6. data/lib/active_record/associations/association.rb +34 -10
  7. data/lib/active_record/associations/belongs_to_association.rb +18 -2
  8. data/lib/active_record/associations/builder/association.rb +7 -6
  9. data/lib/active_record/associations/collection_association.rb +10 -8
  10. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  11. data/lib/active_record/associations/has_many_through_association.rb +3 -2
  12. data/lib/active_record/associations/join_dependency/join_association.rb +25 -27
  13. data/lib/active_record/associations/join_dependency.rb +2 -2
  14. data/lib/active_record/associations/preloader/association.rb +2 -2
  15. data/lib/active_record/associations/preloader/batch.rb +7 -1
  16. data/lib/active_record/associations/singular_association.rb +8 -3
  17. data/lib/active_record/associations.rb +34 -4
  18. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  19. data/lib/active_record/attribute_methods/primary_key.rb +4 -8
  20. data/lib/active_record/attribute_methods/query.rb +34 -0
  21. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  22. data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
  23. data/lib/active_record/attribute_methods.rb +24 -19
  24. data/lib/active_record/attributes.rb +37 -26
  25. data/lib/active_record/autosave_association.rb +91 -39
  26. data/lib/active_record/base.rb +2 -2
  27. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +34 -25
  28. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
  29. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
  30. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +55 -47
  31. data/lib/active_record/connection_adapters/abstract/database_statements.rb +91 -44
  32. data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -8
  33. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  34. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
  35. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +12 -3
  36. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +40 -10
  37. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
  38. data/lib/active_record/connection_adapters/abstract_adapter.rb +92 -70
  39. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +35 -46
  40. data/lib/active_record/connection_adapters/mysql/quoting.rb +7 -9
  41. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
  42. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +50 -45
  43. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +84 -94
  44. data/lib/active_record/connection_adapters/mysql2_adapter.rb +9 -9
  45. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  46. data/lib/active_record/connection_adapters/postgresql/column.rb +4 -2
  47. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -43
  48. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  49. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  50. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  51. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
  52. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -24
  53. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
  54. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +60 -17
  55. data/lib/active_record/connection_adapters/postgresql_adapter.rb +61 -99
  56. data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
  57. data/lib/active_record/connection_adapters/sqlite3/column.rb +8 -2
  58. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +80 -100
  59. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +13 -0
  60. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
  61. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +27 -2
  62. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +10 -1
  63. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +63 -17
  64. data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
  65. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
  66. data/lib/active_record/connection_adapters/trilogy_adapter.rb +1 -18
  67. data/lib/active_record/connection_adapters.rb +0 -56
  68. data/lib/active_record/connection_handling.rb +35 -9
  69. data/lib/active_record/core.rb +57 -22
  70. data/lib/active_record/counter_cache.rb +1 -1
  71. data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -1
  72. data/lib/active_record/database_configurations/database_config.rb +4 -0
  73. data/lib/active_record/database_configurations/hash_config.rb +16 -2
  74. data/lib/active_record/delegated_type.rb +18 -18
  75. data/lib/active_record/encryption/config.rb +3 -1
  76. data/lib/active_record/encryption/encryptable_record.rb +5 -5
  77. data/lib/active_record/encryption/encrypted_attribute_type.rb +11 -2
  78. data/lib/active_record/encryption/encryptor.rb +37 -28
  79. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  80. data/lib/active_record/encryption/scheme.rb +8 -1
  81. data/lib/active_record/enum.rb +22 -34
  82. data/lib/active_record/errors.rb +16 -8
  83. data/lib/active_record/fixture_set/table_row.rb +19 -2
  84. data/lib/active_record/fixtures.rb +0 -2
  85. data/lib/active_record/future_result.rb +15 -9
  86. data/lib/active_record/gem_version.rb +4 -4
  87. data/lib/active_record/insert_all.rb +3 -3
  88. data/lib/active_record/locking/optimistic.rb +1 -1
  89. data/lib/active_record/log_subscriber.rb +5 -11
  90. data/lib/active_record/migration/command_recorder.rb +32 -12
  91. data/lib/active_record/migration/compatibility.rb +5 -2
  92. data/lib/active_record/migration.rb +40 -43
  93. data/lib/active_record/model_schema.rb +3 -4
  94. data/lib/active_record/nested_attributes.rb +4 -6
  95. data/lib/active_record/persistence.rb +128 -130
  96. data/lib/active_record/query_logs.rb +106 -50
  97. data/lib/active_record/query_logs_formatter.rb +17 -28
  98. data/lib/active_record/querying.rb +12 -12
  99. data/lib/active_record/railtie.rb +4 -28
  100. data/lib/active_record/railties/databases.rake +11 -34
  101. data/lib/active_record/reflection.rb +18 -21
  102. data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
  103. data/lib/active_record/relation/batches.rb +132 -72
  104. data/lib/active_record/relation/calculations.rb +71 -65
  105. data/lib/active_record/relation/delegation.rb +25 -14
  106. data/lib/active_record/relation/finder_methods.rb +32 -31
  107. data/lib/active_record/relation/merger.rb +8 -8
  108. data/lib/active_record/relation/predicate_builder/array_handler.rb +3 -1
  109. data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -0
  110. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
  111. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  112. data/lib/active_record/relation/predicate_builder.rb +13 -0
  113. data/lib/active_record/relation/query_attribute.rb +1 -1
  114. data/lib/active_record/relation/query_methods.rb +121 -70
  115. data/lib/active_record/relation/spawn_methods.rb +7 -7
  116. data/lib/active_record/relation/where_clause.rb +9 -3
  117. data/lib/active_record/relation.rb +95 -67
  118. data/lib/active_record/result.rb +66 -4
  119. data/lib/active_record/sanitization.rb +7 -6
  120. data/lib/active_record/schema_dumper.rb +34 -11
  121. data/lib/active_record/schema_migration.rb +2 -1
  122. data/lib/active_record/scoping/named.rb +5 -2
  123. data/lib/active_record/secure_token.rb +3 -3
  124. data/lib/active_record/signed_id.rb +7 -6
  125. data/lib/active_record/statement_cache.rb +14 -14
  126. data/lib/active_record/store.rb +7 -3
  127. data/lib/active_record/table_metadata.rb +1 -3
  128. data/lib/active_record/tasks/database_tasks.rb +69 -60
  129. data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
  130. data/lib/active_record/tasks/postgresql_database_tasks.rb +9 -1
  131. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
  132. data/lib/active_record/test_databases.rb +1 -1
  133. data/lib/active_record/test_fixtures.rb +12 -0
  134. data/lib/active_record/token_for.rb +1 -1
  135. data/lib/active_record/transactions.rb +8 -7
  136. data/lib/active_record/type/serialized.rb +5 -0
  137. data/lib/active_record/validations/uniqueness.rb +8 -8
  138. data/lib/active_record.rb +22 -49
  139. data/lib/arel/collectors/bind.rb +2 -2
  140. data/lib/arel/collectors/sql_string.rb +1 -1
  141. data/lib/arel/collectors/substitute_binds.rb +2 -2
  142. data/lib/arel/crud.rb +2 -0
  143. data/lib/arel/delete_manager.rb +5 -0
  144. data/lib/arel/nodes/binary.rb +1 -1
  145. data/lib/arel/nodes/delete_statement.rb +4 -2
  146. data/lib/arel/nodes/node.rb +1 -1
  147. data/lib/arel/nodes/sql_literal.rb +1 -1
  148. data/lib/arel/nodes/update_statement.rb +4 -2
  149. data/lib/arel/predications.rb +1 -3
  150. data/lib/arel/select_manager.rb +6 -2
  151. data/lib/arel/table.rb +3 -7
  152. data/lib/arel/update_manager.rb +5 -0
  153. data/lib/arel/visitors/dot.rb +2 -0
  154. data/lib/arel/visitors/to_sql.rb +3 -1
  155. metadata +11 -15
  156. data/lib/active_record/relation/record_fetch_warning.rb +0 -52
data/CHANGELOG.md CHANGED
@@ -1,1098 +1,944 @@
1
- ## Rails 7.2.2.1 (December 10, 2024) ##
1
+ ## Rails 8.0.5 (March 24, 2026) ##
2
2
 
3
- * No changes.
3
+ * Fix `insert_all` and `upsert_all` log message when called on anonymous classes.
4
4
 
5
+ *Gabriel Sobrinho*
5
6
 
6
- ## Rails 7.2.2 (October 30, 2024) ##
7
+ * Respect `ActiveRecord::SchemaDumper.ignore_tables` when dumping SQLite virtual tables.
7
8
 
8
- * Fix support for `query_cache: false` in `database.yml`.
9
+ *Hans Schnedlitz*
9
10
 
10
- `query_cache: false` would no longer entirely disable the Active Record query cache.
11
+ * Restore previous instrumenter after `execute_or_skip`
11
12
 
12
- *zzak*
13
+ `FutureResult#execute_or_skip` replaces the thread's instrumenter with an
14
+ `EventBuffer` to collect events published during async query execution.
15
+ If the global async executor is saturated and the `caller_runs` fallback
16
+ executes the task on the calling thread, we need to make sure the previous
17
+ instrumenter is restored or the stale `EventBuffer` would stay in place and
18
+ permanently swallow all subsequent `sql.active_record` notifications on
19
+ that thread.
13
20
 
14
- * Set `.attributes_for_inspect` to `:all` by default.
21
+ *Rosa Gutierrez*
15
22
 
16
- For new applications it is set to `[:id]` in config/environment/production.rb.
23
+ * Fix Ruby 4.0 delegator warning when calling inspect on ActiveRecord::Type::Serialized.
17
24
 
18
- In the console all the attributes are always shown.
25
+ *Hammad Khan*
19
26
 
20
- *Andrew Novoselac*
27
+ * Fix support for table names containing hyphens.
21
28
 
22
- * `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
29
+ *Evgeniy Demin*
23
30
 
24
- *Kazuma Watanabe*
31
+ * Fix column deduplication for SQLite3 and PostgreSQL virtual (generated) columns.
25
32
 
26
- * Fix marshalling of unsaved associated records in 7.1 format.
33
+ `Column#==` and `Column#hash` now account for `virtual?` so that the
34
+ `Deduplicable` registry does not treat a generated column and a regular
35
+ column with the same name and type as identical. Previously, if a
36
+ generated column was registered first, a regular column on a different
37
+ table could be deduplicated to the generated instance, silently
38
+ excluding it from INSERT/UPDATE statements.
27
39
 
28
- The 7.1 format would only marshal associated records if the association was loaded.
29
- But associations that would only contain unsaved records would be skipped.
40
+ *Jay Huber*
30
41
 
31
- *Jean Boussier*
42
+ * Fix merging relations with arel equality predicates with null relations.
32
43
 
33
- * Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
44
+ *fatkodima*
34
45
 
35
- *David Stosik*
46
+ * Fix SQLite3 schema dump for non-autoincrement integer primary keys.
36
47
 
37
- * Allow to save records with polymorphic join tables that have `inverse_of`
38
- specified.
48
+ Previously, `schema.rb` should incorrectly restore that table with an auto incrementing
49
+ primary key.
39
50
 
40
- *Markus Doits*
51
+ *Chris Hasiński*
41
52
 
42
- * Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
53
+ * Fix PostgreSQL `schema_search_path` not being reapplied after `reset!` or `reconnect!`.
43
54
 
44
- *Joshua Young*
55
+ The `schema_search_path` configured in `database.yml` is now correctly
56
+ reapplied instead of falling back to PostgreSQL defaults.
45
57
 
46
- * Fix `dependent: :destroy` for bi-directional has one through association.
58
+ *Tobias Egli*
47
59
 
48
- Fixes #50948.
60
+ * Ensure batched preloaded associations accounts for klass when grouping to avoid issues with STI.
49
61
 
50
- ```ruby
51
- class Left < ActiveRecord::Base
52
- has_one :middle, dependent: :destroy
53
- has_one :right, through: :middle
54
- end
62
+ *zzak*, *Stjepan Hadjic*
55
63
 
56
- class Middle < ActiveRecord::Base
57
- belongs_to :left, dependent: :destroy
58
- belongs_to :right, dependent: :destroy
59
- end
64
+ * Fix `ActiveRecord::SoleRecordExceeded#record` to return the relation.
60
65
 
61
- class Right < ActiveRecord::Base
62
- has_one :middle, dependent: :destroy
63
- has_one :left, through: :middle
64
- end
65
- ```
66
- In the above example `left.destroy` wouldn't destroy its associated `Right`
67
- record.
66
+ This was the case until Rails 7.2, but starting from 8.0 it
67
+ started mistakenly returning the model class.
68
68
 
69
- *Andy Stewart*
69
+ *Jean Boussier*
70
70
 
71
- * Properly handle lazily pinned connection pools.
71
+ * Improve PostgreSQLAdapter resilience to Timeout.timeout.
72
72
 
73
- Fixes #53147.
73
+ Better handle asynchronous exceptions being thrown inside
74
+ the `reconnect!` method.
74
75
 
75
- When using transactional fixtures with system tests to similar tools
76
- such as capybara, it could happen that a connection end up pinned by the
77
- server thread rather than the test thread, causing
78
- `"Cannot expire connection, it is owned by a different thread"` errors.
76
+ This may fixes some deep errors such as:
77
+
78
+ ```
79
+ undefined method `key?' for nil:NilClass (NoMethodError)
80
+ if !type_map.key?(oid)
81
+ ```
79
82
 
80
83
  *Jean Boussier*
81
84
 
82
- * Fix `ActiveRecord::Base.with` to accept more than two sub queries.
85
+ * Fix `eager_load` when loading `has_many` assocations with composite primary keys.
83
86
 
84
- Fixes #53110.
87
+ This would result in some records being loaded multiple times.
85
88
 
86
- ```ruby
87
- User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
88
- undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
89
- ```
89
+ *Martin-Alexander*
90
90
 
91
- The above now works as expected.
92
91
 
93
- *fatkodima*
92
+ ## Rails 8.0.4.1 (March 23, 2026) ##
94
93
 
95
- * Properly release pinned connections with non joinable connections.
94
+ * No changes.
96
95
 
97
- Fixes #52973
98
96
 
99
- When running system tests with transactional fixtures on, it could happen that
100
- the connection leased by the Puma thread wouldn't be properly released back to the pool,
101
- causing "Cannot expire connection, it is owned by a different thread" errors in later tests.
97
+ ## Rails 8.0.4 (October 28, 2025) ##
102
98
 
103
- *Jean Boussier*
99
+ * Fix SQLite3 data loss during table alterations with CASCADE foreign keys.
104
100
 
105
- * Make Float distinguish between `float4` and `float8` in PostgreSQL.
101
+ When altering a table in SQLite3 that is referenced by child tables with
102
+ `ON DELETE CASCADE` foreign keys, ActiveRecord would silently delete all
103
+ data from the child tables. This occurred because SQLite requires table
104
+ recreation for schema changes, and during this process the original table
105
+ is temporarily dropped, triggering CASCADE deletes on child tables.
106
106
 
107
- Fixes #52742
107
+ The root cause was incorrect ordering of operations. The original code
108
+ wrapped `disable_referential_integrity` inside a transaction, but
109
+ `PRAGMA foreign_keys` cannot be modified inside a transaction in SQLite -
110
+ attempting to do so simply has no effect. This meant foreign keys remained
111
+ enabled during table recreation, causing CASCADE deletes to fire.
108
112
 
109
- *Ryota Kitazawa*, *Takayuki Nagatomi*
113
+ The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
114
+ procedure: `disable_referential_integrity` now wraps the transaction instead
115
+ of being wrapped by it. This ensures foreign keys are properly disabled
116
+ before the transaction starts and re-enabled after it commits, preventing
117
+ CASCADE deletes while maintaining data integrity through atomic transactions.
110
118
 
111
- * Fix an issue where `.left_outer_joins` used with multiple associations that have
112
- the same child association but different parents does not join all parents.
119
+ *Ruy Rocha*
113
120
 
114
- Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
121
+ * Add support for bound SQL literals in CTEs.
115
122
 
116
- Now it will correctly join both parents.
123
+ *Nicolas Bachschmidt*
117
124
 
118
- Fixes #41498.
125
+ * Fix `belongs_to` associations not to clear the entire composite primary key.
119
126
 
120
- *Garrett Blehm*
127
+ When clearing a `belongs_to` association that references a model with composite primary key,
128
+ only the optional part of the key should be cleared.
121
129
 
122
- * Ensure `ActiveRecord::Encryption.config` is always ready before access.
130
+ *zzak*
123
131
 
124
- Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
125
- was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
126
- `ActiveRecord::Base` was loaded would give incorrect results.
132
+ * Fix invalid records being autosaved when distantly associated records are marked for deletion.
127
133
 
128
- `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
129
- soon as needed.
134
+ *Ian Terrell*, *axlekb AB*
130
135
 
131
- When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
132
- `ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
133
- before any use of `ActiveRecord::Base`.
134
136
 
135
- *Maxime Réty*
137
+ ## Rails 8.0.3 (September 22, 2025) ##
136
138
 
137
- * Add `TimeZoneConverter#==` method, so objects will be properly compared by
138
- their type, scale, limit & precision.
139
+ * Fix query cache for pinned connections in multi threaded transactional tests
139
140
 
140
- Address #52699.
141
+ When a pinned connection is used across separate threads, they now use a separate cache store
142
+ for each thread.
141
143
 
142
- *Ruy Rocha*
144
+ This improve accuracy of system tests, and any test using multiple threads.
143
145
 
146
+ *Heinrich Lee Yu*, *Jean Boussier*
144
147
 
145
- ## Rails 7.2.1.2 (October 23, 2024) ##
148
+ * Don't add `id_value` attribute alias when attribute/column with that name already exists.
146
149
 
147
- * No changes.
150
+ *Rob Lewis*
148
151
 
152
+ * Fix false positive change detection involving STI and polymorphic has one relationships.
149
153
 
150
- ## Rails 7.2.1.1 (October 15, 2024) ##
154
+ Polymorphic `has_one` relationships would always be considered changed when defined in a STI child
155
+ class, causing nedless extra autosaves.
151
156
 
152
- * No changes.
157
+ *David Fritsch*
153
158
 
159
+ * Skip calling `PG::Connection#cancel` in `cancel_any_running_query`
160
+ when using libpq >= 18 with pg < 1.6.0, due to incompatibility.
161
+ Rollback still runs, but may take longer.
154
162
 
155
- ## Rails 7.2.1 (August 22, 2024) ##
163
+ *Yasuo Honda*, *Lars Kanis*
156
164
 
157
- * Fix detection for `enum` columns with parallelized tests and PostgreSQL.
165
+ * Fix stale association detection for polymorphic `belongs_to`.
158
166
 
159
- *Rafael Mendonça França*
167
+ *Florent Beaurain*, *Thomas Crambert*
160
168
 
161
- * Allow to eager load nested nil associations.
169
+ * Fix removal of PostgreSQL version comments in `structure.sql` for latest PostgreSQL versions which include `\restrict`
162
170
 
163
- *fatkodima*
171
+ *Brendan Weibrecht*
164
172
 
165
- * Fix swallowing ignore order warning when batching using `BatchEnumerator`.
173
+ * Allow setting `schema_format` in database configuration.
166
174
 
167
- *fatkodima*
175
+ ```
176
+ primary:
177
+ schema_format: ruby
178
+ ```
168
179
 
169
- * Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
180
+ Useful in multi-database setups to have different formats per-database.
170
181
 
171
- *Jean Boussier*
182
+ *T S Vallender*
172
183
 
173
- * Restore inferred association class with the same modularized name.
184
+ * Use ntuples to populate row_count instead of count for Postgres
174
185
 
175
- *Justin Ko*
186
+ *Jonathan Calvert*
176
187
 
177
- * Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
188
+ * Fix `#merge` with `#or` or `#and` and a mixture of attributes and SQL strings resulting in an incorrect query.
178
189
 
179
- *Jean Boussier*
190
+ ```ruby
191
+ base = Comment.joins(:post).where(user_id: 1).where("recent = 1")
192
+ puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql
193
+ ```
180
194
 
181
- * Check invalid `enum` options for the new syntax.
195
+ Before:
182
196
 
183
- The options using `_` prefix in the old syntax are invalid in the new syntax.
197
+ ```SQL
198
+ SELECT "comments".* FROM "comments"
199
+ INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
200
+ WHERE (recent = 1)
201
+ AND (
202
+ "comments"."user_id" = 1
203
+ AND (recent = 1)
204
+ AND "comments"."draft" = 1
205
+ OR "posts"."archived" = 1
206
+ )
207
+ ```
184
208
 
185
- *Rafael Mendonça França*
209
+ After:
186
210
 
187
- * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
188
- actual cast type.
211
+ ```SQL
212
+ SELECT "comments".* FROM "comments"
213
+ INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
214
+ WHERE "comments"."user_id" = 1
215
+ AND (recent = 1)
216
+ AND (
217
+ "comments"."user_id" = 1
218
+ AND (recent = 1)
219
+ AND "comments"."draft" = 1
220
+ OR "posts"."archived" = 1
221
+ )
222
+ ```
189
223
 
190
- *Vasiliy Ermolovich*
224
+ *Joshua Young*
191
225
 
192
- * Fix `create_table` with `:auto_increment` option for MySQL adapter.
226
+ * Fix inline `has_and_belongs_to_many` fixtures for tables with composite primary keys.
193
227
 
194
228
  *fatkodima*
195
229
 
230
+ * Fix migration log message for down operations.
196
231
 
197
- ## Rails 7.2.0 (August 09, 2024) ##
232
+ *Bernardo Barreto*
198
233
 
199
- * Handle commas in Sqlite3 default function definitions.
234
+ * Prepend `extra_flags` in postgres' `structure_load`
200
235
 
201
- *Stephen Margheim*
202
-
203
- * Fixes `validates_associated` raising an exception when configured with a
204
- singular association and having `index_nested_attribute_errors` enabled.
236
+ When specifying `structure_load_flags` with a postgres adapter, the flags
237
+ were appended to the default flags, instead of prepended.
238
+ This caused issues with flags not being taken into account by postgres.
205
239
 
206
- *Martin Spickermann*
240
+ *Alice Loeser*
207
241
 
208
- * The constant `ActiveRecord::ImmutableRelation` has been deprecated because
209
- we want to reserve that name for a stronger sense of "immutable relation".
210
- Please use `ActiveRecord::UnmodifiableRelation` instead.
242
+ * Fix `annotate` comments to propagate to `update_all`/`delete_all`.
211
243
 
212
- *Xavier Noria*
244
+ *fatkodima*
213
245
 
214
- * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
215
- `DatabaseConfig`.
246
+ * Fix checking whether an unpersisted record is `include?`d in a strictly
247
+ loaded `has_and_belongs_to_many` association.
216
248
 
217
249
  *Hartley McGuire*
218
250
 
219
- * Fixed a memory performance issue in Active Record attribute methods definition.
251
+ * `create_or_find_by` will now correctly rollback a transaction.
220
252
 
221
- *Jean Boussier*
253
+ When using `create_or_find_by`, raising a ActiveRecord::Rollback error
254
+ in a `after_save` callback had no effect, the transaction was committed
255
+ and a record created.
222
256
 
223
- * Define the new Active Support notification event `start_transaction.active_record`.
257
+ *Edouard Chin*
224
258
 
225
- This event is fired when database transactions or savepoints start, and
226
- complements `transaction.active_record`, which is emitted when they finish.
259
+ * Gracefully handle `Timeout.timeout` firing during connection configuration.
227
260
 
228
- The payload has the transaction (`:transaction`) and the connection (`:connection`).
261
+ Use of `Timeout.timeout` could result in improperly initialized database connection.
229
262
 
230
- *Xavier Noria*
263
+ This could lead to a partially configured connection being used, resulting in various exceptions,
264
+ the most common being with the PostgreSQLAdapter raising `undefined method 'key?' for nil`
265
+ or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
231
266
 
232
- * Fix an issue where the IDs reader method did not return expected results
233
- for preloaded associations in models using composite primary keys.
267
+ *Jean Boussier*
234
268
 
235
- *Jay Ang*
269
+ * Fix stale state for composite foreign keys in belongs_to associations.
236
270
 
237
- * The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
271
+ *Varun Sharma*
238
272
 
239
- *Xavier Noria*
240
273
 
241
- * The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
274
+ ## Rails 8.0.2.1 (August 13, 2025) ##
242
275
 
243
- *Xavier Noria*
276
+ * Call inspect on ids in RecordNotFound error
244
277
 
245
- * Define `ActiveRecord::Transaction#uuid`, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.
278
+ [CVE-2025-55193]
246
279
 
247
- *Xavier Noria*
280
+ *Gannon McGibbon*, *John Hawthorn*
248
281
 
249
- * Fix inference of association model on nested models with the same demodularized name.
250
-
251
- E.g. with the following setup:
252
-
253
- ```ruby
254
- class Nested::Post < ApplicationRecord
255
- has_one :post, through: :other
256
- end
257
- ```
258
282
 
259
- Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
283
+ ## Rails 8.0.2 (March 12, 2025) ##
260
284
 
261
- *Joshua Young*
285
+ * Fix inverting `rename_enum_value` when `:from`/`:to` are provided.
262
286
 
263
- * PostgreSQL `Cidr#change?` detects the address prefix change.
287
+ *fatkodima*
264
288
 
265
- *Taketo Takashima*
289
+ * Prevent persisting invalid record.
266
290
 
267
- * Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
291
+ *Edouard Chin*
268
292
 
269
- Previously, it always returned `nil`.
293
+ * Fix inverting `drop_table` without options.
270
294
 
271
295
  *fatkodima*
272
296
 
273
- * Support `touch_all` in batches.
297
+ * Fix count with group by qualified name on loaded relation.
274
298
 
275
- ```ruby
276
- Post.in_batches.touch_all
277
- ```
299
+ *Ryuta Kamizono*
278
300
 
279
- *fatkodima*
301
+ * Fix `sum` with qualified name on loaded relation.
280
302
 
281
- * Add support for `:if_not_exists` and `:force` options to `create_schema`.
282
-
283
- *fatkodima*
303
+ *Chris Gunther*
284
304
 
285
- * Fix `index_errors` having incorrect index in association validation errors.
305
+ * The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".
286
306
 
287
- *lulalala*
288
-
289
- * Add `index_errors: :nested_attributes_order` mode.
307
+ *Mike Dalessio*
290
308
 
291
- This indexes the association validation errors based on the order received by nested attributes setter, and respects the `reject_if` configuration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.
309
+ * Handle libpq returning a database version of 0 on no/bad connection in `PostgreSQLAdapter`.
292
310
 
293
- *lulalala*
311
+ Before, this version would be cached and an error would be raised during connection configuration when
312
+ comparing it with the minimum required version for the adapter. This meant that the connection could
313
+ never be successfully configured on subsequent reconnection attempts.
294
314
 
295
- * Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
315
+ Now, this is treated as a connection failure consistent with libpq, raising a `ActiveRecord::ConnectionFailed`
316
+ and ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.
296
317
 
297
- *Joé Dupuis*
318
+ *Joshua Young*, *Rian McGuire*
298
319
 
299
- * Association option `query_constraints` is deprecated in favor of `foreign_key`.
320
+ * Fix error handling during connection configuration.
300
321
 
301
- *Nikita Vasilevsky*
322
+ Active Record wasn't properly handling errors during the connection configuration phase.
323
+ This could lead to a partially configured connection being used, resulting in various exceptions,
324
+ the most common being with the PostgreSQLAdapter raising `undefined method `key?' for nil`
325
+ or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
302
326
 
303
- * Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
327
+ *Jean Boussier*
304
328
 
305
- This cuts ~10s from the test run of HEY when run by 24 processes against the 178 tables, since ~4,000 table truncates can then be skipped.
329
+ * Fix a case where a non-retryable query could be marked retryable.
306
330
 
307
- *DHH*
331
+ *Hartley McGuire*
308
332
 
309
- * Added support for recursive common table expressions.
333
+ * Handle circular references when autosaving associations.
310
334
 
311
- ```ruby
312
- Post.with_recursive(
313
- post_and_replies: [
314
- Post.where(id: 42),
315
- Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
316
- ]
317
- )
318
- ```
335
+ *zzak*
319
336
 
320
- Generates the following SQL:
337
+ * PoolConfig no longer keeps a reference to the connection class.
321
338
 
322
- ```sql
323
- WITH RECURSIVE "post_and_replies" AS (
324
- (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
325
- UNION ALL
326
- (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
327
- )
328
- SELECT "posts".* FROM "posts"
329
- ```
339
+ Keeping a reference to the class caused subtle issues when combined with reloading in
340
+ development. Fixes #54343.
330
341
 
331
- *ClearlyClaire*
342
+ *Mike Dalessio*
332
343
 
333
- * `validate_constraint` can be called in a `change_table` block.
344
+ * Fix SQL notifications sometimes not sent when using async queries.
334
345
 
335
- ex:
336
346
  ```ruby
337
- change_table :products do |t|
338
- t.check_constraint "price > discounted_price", name: "price_check", validate: false
339
- t.validate_check_constraint "price_check"
347
+ Post.async_count
348
+ ActiveSupport::Notifications.subscribed(->(*) { "Will never reach here" }) do
349
+ Post.count
340
350
  end
341
351
  ```
342
352
 
343
- *Cody Cutrer*
353
+ In rare circumstances and under the right race condition, Active Support notifications
354
+ would no longer be dispatched after using an asynchronous query.
355
+ This is now fixed.
344
356
 
345
- * `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
357
+ *Edouard Chin*
346
358
 
347
- Ex:
348
- ```ruby
349
- ActiveRecord::Base.connection
350
- .select_value("select '2024-01-01'::date").class #=> Date
351
- ```
359
+ * Fix support for PostgreSQL enum types with commas in their name.
352
360
 
353
- *Joé Dupuis*
361
+ *Arthur Hess*
354
362
 
355
- * Strict loading using `:n_plus_one_only` does not eagerly load child associations.
363
+ * Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.
356
364
 
357
- With this change, child associations are no longer eagerly loaded, to
358
- match intended behavior and to prevent non-deterministic order issues caused
359
- by calling methods like `first` or `last`. As `first` and `last` don't cause
360
- an N+1 by themselves, calling child associations will no longer raise.
361
- Fixes #49473.
365
+ *Nikita Vasilevsky*
362
366
 
363
- Before:
367
+ * Fix joining on a scoped association with string joins and bind parameters.
364
368
 
365
369
  ```ruby
366
- person = Person.find(1)
367
- person.strict_loading!(mode: :n_plus_one_only)
368
- person.posts.first
369
- # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
370
- person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
371
- ```
370
+ class Instructor < ActiveRecord::Base
371
+ has_many :instructor_roles, -> { active }
372
+ end
372
373
 
373
- After:
374
+ class InstructorRole < ActiveRecord::Base
375
+ scope :active, -> {
376
+ joins("JOIN students ON instructor_roles.student_id = students.id")
377
+ .where(students { status: 1 })
378
+ }
379
+ end
374
380
 
375
- ```ruby
376
- person = Person.find(1)
377
- person.strict_loading!(mode: :n_plus_one_only)
378
- person.posts.first # this is 1+1, not N+1
379
- # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
380
- person.posts.first.firm # no longer raises
381
+ Instructor.joins(:instructor_roles).first
381
382
  ```
382
383
 
383
- *Reid Lynch*
384
+ The above example would result in `ActiveRecord::StatementInvalid` because the
385
+ `active` scope bind parameters would be lost.
384
386
 
385
- * Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
386
-
387
- *Mike Dalessio*
388
-
389
- * Allow `ActiveRecord::Base#pluck` to accept hash values.
390
-
391
- ```ruby
392
- # Before
393
- Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
394
-
395
- # After
396
- Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
397
- ```
398
-
399
- *fatkodima*
387
+ *Jean Boussier*
400
388
 
401
- * Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
389
+ * Fix a potential race condition with system tests and transactional fixtures.
402
390
 
403
- *Kevin McPhillips*
391
+ *Sjoerd Lagarde*
404
392
 
405
- * `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
393
+ * Fix autosave associations to no longer validated unmodified associated records.
406
394
 
407
- This allows to register callbacks on it.
395
+ Active Record was incorrectly performing validation on associated record that
396
+ weren't created nor modified as part of the transaction:
408
397
 
409
398
  ```ruby
410
- Article.transaction do |transaction|
411
- article.update(published: true)
412
- transaction.after_commit do
413
- PublishNotificationMailer.with(article: article).deliver_later
414
- end
415
- end
399
+ Post.create!(author: User.find(1)) # Fail if user is invalid
416
400
  ```
417
401
 
418
402
  *Jean Boussier*
419
403
 
420
- * Add `ActiveRecord::Base.current_transaction`.
404
+ * Remember when a database connection has recently been verified (for
405
+ two seconds, by default), to avoid repeated reverifications during a
406
+ single request.
421
407
 
422
- Returns the current transaction, to allow registering callbacks on it.
408
+ This should recreate a similar rate of verification as in Rails 7.1,
409
+ where connections are leased for the duration of a request, and thus
410
+ only verified once.
423
411
 
424
- ```ruby
425
- Article.current_transaction.after_commit do
426
- PublishNotificationMailer.with(article: article).deliver_later
427
- end
428
- ```
412
+ *Matthew Draper*
429
413
 
430
- *Jean Boussier*
431
414
 
432
- * Add `ActiveRecord.after_all_transactions_commit` callback.
415
+ ## Rails 8.0.1 (December 13, 2024) ##
433
416
 
434
- Useful for code that may run either inside or outside a transaction and needs
435
- to perform work after the state changes have been properly persisted.
417
+ * Fix removing foreign keys with :restrict action for MySQL.
436
418
 
437
- ```ruby
438
- def publish_article(article)
439
- article.update(published: true)
440
- ActiveRecord.after_all_transactions_commit do
441
- PublishNotificationMailer.with(article: article).deliver_later
442
- end
443
- end
444
- ```
419
+ *fatkodima*
445
420
 
446
- In the above example, the block is either executed immediately if called outside
447
- of a transaction, or called after the open transaction is committed.
421
+ * Fix a race condition in `ActiveRecord::Base#method_missing` when lazily defining attributes.
448
422
 
449
- If the transaction is rolled back, the block isn't called.
423
+ If multiple thread were concurrently triggering attribute definition on the same model,
424
+ it could result in a `NoMethodError` being raised.
450
425
 
451
426
  *Jean Boussier*
452
427
 
453
- * Add the ability to ignore counter cache columns until they are backfilled.
428
+ * Fix MySQL default functions getting dropped when changing a column's nullability.
454
429
 
455
- Starting to use counter caches on existing large tables can be troublesome, because the column
456
- values must be backfilled separately of the column addition (to not lock the table for too long)
457
- and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
458
- counter caches internally, can produce incorrect results). People usually use database triggers
459
- or callbacks on child associations while backfilling before introducing a counter cache
460
- configuration to the association.
430
+ *Bastian Bartmann*
461
431
 
462
- Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
432
+ * Fix `add_unique_constraint`/`add_check_constraint`/`add_foreign_key` to be revertible when given invalid options.
463
433
 
464
- ```ruby
465
- class Comment < ApplicationRecord
466
- belongs_to :post, counter_cache: { active: false }
467
- end
468
- ```
434
+ *fatkodima*
469
435
 
470
- While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
471
- but get the results directly from the database. After the counter cache column is backfilled, simply
472
- remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
473
- mentioned methods.
436
+ * Fix asynchronous destroying of polymorphic `belongs_to` associations.
474
437
 
475
438
  *fatkodima*
476
439
 
477
- * Retry known idempotent SELECT queries on connection-related exceptions.
440
+ * Fix `insert_all` to not update existing records.
478
441
 
479
- SELECT queries we construct by walking the Arel tree and / or with known model attributes
480
- are idempotent and can safely be retried in the case of a connection error. Previously,
481
- adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
482
- when encountering a connection error mid-request.
442
+ *fatkodima*
483
443
 
484
- *Adrianna Chang*
444
+ * `NOT VALID` constraints should not dump in `create_table`.
485
445
 
486
- * Allow association's `foreign_key` to be composite.
446
+ *Ryuta Kamizono*
487
447
 
488
- `query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
489
- Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
448
+ * Fix finding by nil composite primary key association.
490
449
 
491
- *Nikita Vasilevsky*
492
-
493
- * Allow association's `primary_key` to be composite.
450
+ *fatkodima*
494
451
 
495
- Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
496
- Now it's possible to explicitly set it as composite on the association.
452
+ * Properly reset composite primary key configuration when setting a primary key.
497
453
 
498
- *Nikita Vasilevsky*
454
+ *fatkodima*
499
455
 
500
- * Add `config.active_record.permanent_connection_checkout` setting.
456
+ * Fix Mysql2Adapter support for prepared statements
501
457
 
502
- Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
458
+ Using prepared statements with MySQL could result in a `NoMethodError` exception.
503
459
 
504
- `ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
505
- the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
506
- is available connections.
460
+ *Jean Boussier*, *Leo Arnold*, *zzak*
507
461
 
508
- This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
509
- migrate it to use `ActiveRecord::Base.with_connection` instead.
462
+ * Fix parsing of SQLite foreign key names when they contain non-ASCII characters
510
463
 
511
- The default behavior remains unchanged, and there is currently no plans to change the default.
464
+ *Zacharias Knudsen*
512
465
 
513
- *Jean Boussier*
466
+ * Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines.
514
467
 
515
- * Add dirties option to uncached.
468
+ *Steve Hill*
516
469
 
517
- This adds a `dirties` option to `ActiveRecord::Base.uncached` and
518
- `ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
470
+ * Ensure normalized attribute queries use `IS NULL` consistently for `nil` and normalized `nil` values.
519
471
 
520
- When set to `true` (the default), writes will clear all query caches belonging to the current thread.
521
- When set to `false`, writes to the affected connection pool will not clear any query cache.
472
+ *Joshua Young*
522
473
 
523
- This is needed by Solid Cache so that cache writes do not clear query caches.
474
+ * Fix `sum` when performing a grouped calculation.
524
475
 
525
- *Donal McBreen*
476
+ `User.group(:friendly).sum` no longer worked. This is fixed.
526
477
 
527
- * Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
478
+ *Edouard Chin*
528
479
 
529
- The method has been renamed as `lease_connection` to better reflect that the returned
530
- connection will be held for the duration of the request or job.
480
+ * Restore back the ability to pass only database name to `DATABASE_URL`.
531
481
 
532
- This deprecation is a soft deprecation, no warnings will be issued and there is no
533
- current plan to remove the method.
482
+ *fatkodima*
534
483
 
535
- *Jean Boussier*
536
484
 
537
- * Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
485
+ ## Rails 8.0.0.1 (December 10, 2024) ##
538
486
 
539
- The method has been renamed as `lease_connection` to better reflect that the returned
540
- connection will be held for the duration of the request or job.
487
+ * No changes.
541
488
 
542
- *Jean Boussier*
543
489
 
544
- * Expose a generic fixture accessor for fixture names that may conflict with Minitest.
490
+ ## Rails 8.0.0 (November 07, 2024) ##
545
491
 
546
- ```ruby
547
- assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
548
- assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
549
- ```
492
+ * Fix support for `query_cache: false` in `database.yml`.
550
493
 
551
- *Jean Boussier*
494
+ `query_cache: false` would no longer entirely disable the Active Record query cache.
552
495
 
553
- * Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
554
- incorrect error message.
496
+ *zzak*
555
497
 
556
- This has been fixed to raise with a more appropriate error message.
557
498
 
558
- *Joshua Young*
499
+ ## Rails 8.0.0.rc2 (October 30, 2024) ##
559
500
 
560
- * Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
501
+ * NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.
561
502
 
562
- This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
563
- an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
503
+ *Ryuta Kamizono*
564
504
 
565
- *Joshua Young*
505
+ * The `db:prepare` task no longer loads seeds when a non-primary database is created.
566
506
 
567
- * Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
507
+ Previously, the `db:prepare` task would load seeds whenever a new database
508
+ is created, leading to potential loss of data if a database is added to an
509
+ existing environment.
568
510
 
569
- *Rafael Mendonça França*
511
+ Introduces a new database config property `seeds` to control whether seeds
512
+ are loaded during `db:prepare` which defaults to `true` for primary database
513
+ configs and `false` otherwise.
570
514
 
571
- * Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
515
+ Fixes #53348.
572
516
 
573
- *Rafael Mendonça França*
517
+ *Mike Dalessio*
574
518
 
575
- * Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
519
+ * `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
576
520
 
577
- *Rafael Mendonça França*
521
+ *Kazuma Watanabe*
578
522
 
579
- * Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
523
+ * Fix strict loading propagation even if statement cache is not used.
580
524
 
581
- *Rafael Mendonça França*
525
+ *Ryuta Kamizono*
582
526
 
583
- * Remove deprecated support to quote `ActiveSupport::Duration`.
527
+ * Allow `rename_enum` accepts two from/to name arguments as `rename_table` does so.
584
528
 
585
- *Rafael Mendonça França*
529
+ *Ryuta Kamizono*
586
530
 
587
- * Remove deprecated `#quote_bound_value`.
588
531
 
589
- *Rafael Mendonça França*
532
+ ## Rails 8.0.0.rc1 (October 19, 2024) ##
590
533
 
591
- * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
534
+ * Remove deprecated support to setting `ENV["SCHEMA_CACHE"]`.
592
535
 
593
536
  *Rafael Mendonça França*
594
537
 
595
- * Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
596
- `#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
597
- for the current role when the `role` argument isn't provided.
538
+ * Remove deprecated support to passing a database name to `cache_dump_filename`.
598
539
 
599
540
  *Rafael Mendonça França*
600
541
 
601
- * Remove deprecated `#all_connection_pools`.
542
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
602
543
 
603
544
  *Rafael Mendonça França*
604
545
 
605
- * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
546
+ * Remove deprecated `config.active_record.sqlite3_deprecated_warning`.
606
547
 
607
548
  *Rafael Mendonça França*
608
549
 
609
- * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
550
+ * Remove deprecated `config.active_record.warn_on_records_fetched_greater_than`.
610
551
 
611
552
  *Rafael Mendonça França*
612
553
 
613
- * Remove deprecated `#all_foreign_keys_valid?` from database adapters.
554
+ * Remove deprecated support for defining `enum` with keyword arguments.
614
555
 
615
556
  *Rafael Mendonça França*
616
557
 
617
- * Remove deprecated support to passing coder and class as second argument to `serialize`.
558
+ * Remove deprecated support to finding database adapters that aren't registered to Active Record.
618
559
 
619
560
  *Rafael Mendonça França*
620
561
 
621
- * Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
562
+ * Remove deprecated `config.active_record.allow_deprecated_singular_associations_name`.
622
563
 
623
564
  *Rafael Mendonça França*
624
565
 
625
- * Remove deprecated `TestFixtures.fixture_path`.
566
+ * Remove deprecated `config.active_record.commit_transaction_on_non_local_return`.
626
567
 
627
568
  *Rafael Mendonça França*
628
569
 
629
- * Remove deprecated behavior to support referring to a singular association by its plural name.
570
+ * Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
630
571
 
631
- *Rafael Mendonça França*
572
+ *David Stosik*
632
573
 
633
- * Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
574
+ * Allow to save records with polymorphic join tables that have `inverse_of`
575
+ specified.
634
576
 
635
- *Rafael Mendonça França*
577
+ *Markus Doits*
636
578
 
637
- * Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
638
- `ActiveRecord::MigrationContext`.
579
+ * Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
639
580
 
640
- *Rafael Mendonça França*
581
+ *Joshua Young*
641
582
 
642
- * Remove deprecated `ActiveRecord::Migration.check_pending!` method.
583
+ * Allow `ActiveRecord::Base#pluck` to accept hash arguments with symbol and string values.
643
584
 
644
- *Rafael Mendonça França*
585
+ ```ruby
586
+ Post.joins(:comments).pluck(:id, comments: :id)
587
+ Post.joins(:comments).pluck("id", "comments" => "id")
588
+ ```
645
589
 
646
- * Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
590
+ *Joshua Young*
647
591
 
648
- *Rafael Mendonça França*
592
+ * Make Float distinguish between `float4` and `float8` in PostgreSQL.
649
593
 
650
- * Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
594
+ Fixes #52742
651
595
 
652
- *Rafael Mendonça França*
596
+ *Ryota Kitazawa*, *Takayuki Nagatomi*
653
597
 
654
- * Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
655
598
 
656
- *Rafael Mendonça França*
599
+ ## Rails 8.0.0.beta1 (September 26, 2024) ##
657
600
 
658
- * Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
601
+ * Allow `drop_table` to accept an array of table names.
659
602
 
660
- *Rafael Mendonça França*
603
+ This will let you to drop multiple tables in a single call.
661
604
 
662
- * Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
605
+ ```ruby
606
+ ActiveRecord::Base.lease_connection.drop_table(:users, :posts)
607
+ ```
663
608
 
664
- *Rafael Mendonça França*
609
+ *Gabriel Sobrinho*
665
610
 
666
- * Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
611
+ * Add support for PostgreSQL `IF NOT EXISTS` via the `:if_not_exists` option
612
+ on the `add_enum_value` method.
667
613
 
668
- *Rafael Mendonça França*
614
+ *Ariel Rzezak*
669
615
 
670
- * Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
616
+ * When running `db:migrate` on a fresh database, load the databases schemas before running migrations.
671
617
 
672
- *Rafael Mendonça França*
618
+ *Andrew Novoselac*, *Marek Kasztelnik*
673
619
 
674
- * Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
620
+ * Fix an issue where `.left_outer_joins` used with multiple associations that have
621
+ the same child association but different parents does not join all parents.
675
622
 
676
- *Rafael Mendonça França*
623
+ Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
677
624
 
678
- * Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
625
+ Now it will correctly join both parents.
679
626
 
680
- *Rafael Mendonça França*
627
+ Fixes #41498.
681
628
 
682
- * Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
629
+ *Garrett Blehm*
683
630
 
684
- *Rafael Mendonça França*
631
+ * Deprecate `unsigned_float` and `unsigned_decimal` short-hand column methods.
685
632
 
686
- * Remove deprecated support to call `alias_attribute` with non-existent attribute names.
633
+ As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE,
634
+ and DECIMAL. Consider using a simple CHECK constraint instead for such columns.
687
635
 
688
- *Rafael Mendonça França*
636
+ https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
689
637
 
690
- * Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
638
+ *Ryuta Kamizono*
691
639
 
692
- *Rafael Mendonça França*
640
+ * Drop MySQL 5.5 support.
693
641
 
694
- * Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
642
+ MySQL 5.5 is the only version that does not support datetime with precision,
643
+ which we have supported in the core. Now we support MySQL 5.6.4 or later, which
644
+ is the first version to support datetime with precision.
695
645
 
696
- Serialize data to the MessagePack format, for efficient storage in binary columns.
646
+ *Ryuta Kamizono*
697
647
 
698
- The binary encoding requires around 30% less space than the base64 encoding
699
- used by the default serializer.
648
+ * Make Active Record asynchronous queries compatible with transactional fixtures.
700
649
 
701
- *Donal McBreen*
650
+ Previously transactional fixtures would disable asynchronous queries, because transactional
651
+ fixtures impose all queries use the same connection.
702
652
 
703
- * Add support for encrypting binary columns.
653
+ Now asynchronous queries will use the connection pinned by transactional fixtures, and behave
654
+ much closer to production.
704
655
 
705
- Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
656
+ *Jean Boussier*
706
657
 
707
- Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
708
- incidentally worked for MySQL and SQLite, but not PostgreSQL.
658
+ * Deserialize binary data before decrypting
659
+
660
+ This ensures that we call `PG::Connection.unescape_bytea` on PostgreSQL before decryption.
709
661
 
710
662
  *Donal McBreen*
711
663
 
712
- * Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
664
+ * Ensure `ActiveRecord::Encryption.config` is always ready before access.
713
665
 
714
- *Rafael Mendonça França*
666
+ Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
667
+ was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
668
+ `ActiveRecord::Base` was loaded would give incorrect results.
715
669
 
716
- * Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
670
+ `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
671
+ soon as needed.
717
672
 
718
- The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
719
- will yield that same connection.
673
+ When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
674
+ `ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
675
+ before any use of `ActiveRecord::Base`.
720
676
 
721
- This is useful to perform a few database operations without causing a connection to be leased for the
722
- entire duration of the request or job.
677
+ *Maxime Réty*
723
678
 
724
- *Jean Boussier*
679
+ * Add `TimeZoneConverter#==` method, so objects will be properly compared by
680
+ their type, scale, limit & precision.
725
681
 
726
- * Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
727
- notification includes `:row_count` field.
682
+ Address #52699.
728
683
 
729
- *Jason Nochlin*
684
+ *Ruy Rocha*
730
685
 
731
- * The fix ensures that the association is joined using the appropriate join type
732
- (either inner join or left outer join) based on the existing joins in the scope.
686
+ * Add support for SQLite3 full-text-search and other virtual tables.
733
687
 
734
- This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
688
+ Previously, adding sqlite3 virtual tables messed up `schema.rb`.
735
689
 
736
- Example:
690
+ Now, virtual tables can safely be added using `create_virtual_table`.
737
691
 
692
+ *Zacharias Knudsen*
738
693
 
694
+ * Support use of alternative database interfaces via the `database_cli` ActiveRecord configuration option.
739
695
 
740
696
  ```ruby
741
- # `associated` will use `LEFT JOIN` instead of using `JOIN`
742
- Post.left_joins(:author).where.associated(:author)
697
+ Rails.application.configure do
698
+ config.active_record.database_cli = { postgresql: "pgcli" }
699
+ end
743
700
  ```
744
701
 
745
- *Saleh Alhaddad*
702
+ *T S Vallender*
746
703
 
747
- * Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
748
- of Active Record models, when an application is eager loaded. As a result, encrypted attributes
749
- could be misconfigured in some cases.
704
+ * Add support for dumping table inheritance and native partitioning table definitions for PostgeSQL adapter
750
705
 
751
- *Maxime Réty*
706
+ *Justin Talbott*
707
+
708
+ * Add support for `ActiveRecord::Point` type casts using `Hash` values
752
709
 
753
- * Deprecate defining an `enum` with keyword arguments.
710
+ This allows `ActiveRecord::Point` to be cast or serialized from a hash
711
+ with `:x` and `:y` keys of numeric values, mirroring the functionality of
712
+ existing casts for string and array values. Both string and symbol keys are
713
+ supported.
754
714
 
755
715
  ```ruby
756
- class Function > ApplicationRecord
757
- # BAD
758
- enum color: [:red, :blue],
759
- type: [:instance, :class]
760
-
761
- # GOOD
762
- enum :color, [:red, :blue]
763
- enum :type, [:instance, :class]
716
+ class PostgresqlPoint < ActiveRecord::Base
717
+ attribute :x, :point
718
+ attribute :y, :point
719
+ attribute :z, :point
764
720
  end
721
+
722
+ val = PostgresqlPoint.new({
723
+ x: '(12.34, -43.21)',
724
+ y: [12.34, '-43.21'],
725
+ z: {x: '12.34', y: -43.21}
726
+ })
727
+ ActiveRecord::Point.new(12.32, -43.21) == val.x == val.y == val.z
765
728
  ```
766
729
 
767
- *Hartley McGuire*
730
+ *Stephen Drew*
768
731
 
769
- * Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
732
+ * Replace `SQLite3::Database#busy_timeout` with `#busy_handler_timeout=`.
770
733
 
771
- When set, validates that the timestamp prefix for a migration is no more than a day ahead of
772
- the timestamp associated with the current time. This is designed to prevent migrations prefixes
773
- from being hand-edited to future timestamps, which impacts migration generation and other
774
- migration commands.
734
+ Provides a non-GVL-blocking, fair retry interval busy handler implementation.
775
735
 
776
- *Adrianna Chang*
736
+ *Stephen Margheim*
777
737
 
778
- * Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
738
+ * SQLite3Adapter: Translate `SQLite3::BusyException` into `ActiveRecord::StatementTimeout`.
779
739
 
780
- As well as `disconnect!` and `verify!`.
740
+ *Matthew Nguyen*
781
741
 
782
- This generally isn't a big problem as connections must not be shared between
783
- threads, but is required when running transactional tests or system tests
784
- and could lead to a SEGV.
742
+ * Include schema name in `enable_extension` statements in `db/schema.rb`.
785
743
 
786
- *Jean Boussier*
744
+ The schema dumper will now include the schema name in generated
745
+ `enable_extension` statements if they differ from the current schema.
787
746
 
788
- * Support `:source_location` tag option for query log tags.
747
+ For example, if you have a migration:
789
748
 
790
749
  ```ruby
791
- config.active_record.query_log_tags << :source_location
750
+ enable_extension "heroku_ext.pgcrypto"
751
+ enable_extension "pg_stat_statements"
792
752
  ```
793
753
 
794
- Calculating the caller location is a costly operation and should be used primarily in development
795
- (note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
796
- or occasionally on production for debugging purposes.
797
-
798
- *fatkodima*
799
-
800
- * Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
801
-
802
- Allow compression to be disabled by setting `compress: false`
754
+ then the generated schema dump will also contain:
803
755
 
804
756
  ```ruby
805
- class User
806
- encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
807
- end
757
+ enable_extension "heroku_ext.pgcrypto"
758
+ enable_extension "pg_stat_statements"
808
759
  ```
809
760
 
810
- *Donal McBreen*
811
-
812
- * Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
813
-
814
- A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
815
-
816
- *Rafael Mendonça França*
817
-
818
- * Add `row_count` field to `sql.active_record` notification.
819
-
820
- This field returns the amount of rows returned by the query that emitted the notification.
821
-
822
- This metric is useful in cases where one wants to detect queries with big result sets.
823
-
824
- *Marvin Bitterlich*
825
-
826
- * Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
827
-
828
- Previously, this would only raise on collection associations and produce a generic error on singular associations.
829
-
830
- Now, it will raise on both collection and singular associations.
831
-
832
- *Joshua Young*
833
-
834
- * Fix single quote escapes on default generated MySQL columns.
835
-
836
- MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
837
-
838
- Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
839
-
840
- This would result in issues when importing the schema on a fresh instance of a MySQL database.
841
-
842
- Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
843
-
844
- *Yash Kapadia*
845
-
846
- * Fix Migrations with versions older than 7.1 validating options given to
847
- `add_reference` and `t.references`.
848
-
849
- *Hartley McGuire*
850
-
851
- * Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
852
-
853
- *JP Rosevear*
854
-
855
- * Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
761
+ *Tony Novak*
856
762
 
857
- This wouldn't always work previously because boolean values would be interpreted as strings.
763
+ * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
764
+ actual cast type.
858
765
 
859
- e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
860
- cache.
766
+ *Vasiliy Ermolovich*
861
767
 
862
- *Mike Coutermarsh*, *Jean Boussier*
768
+ * SQLite3Adapter: Bulk insert fixtures.
863
769
 
864
- * Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
770
+ Previously one insert command was executed for each fixture, now they are
771
+ aggregated in a single bulk insert command.
865
772
 
866
- It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
867
- but with support for `after_commit` and `after_rollback` callback options.
773
+ *Lázaro Nixon*
868
774
 
869
- *Joshua Young*
775
+ * PostgreSQLAdapter: Allow `disable_extension` to be called with schema-qualified name.
870
776
 
871
- * Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
777
+ For parity with `enable_extension`, the `disable_extension` method can be called with a schema-qualified
778
+ name (e.g. `disable_extension "myschema.pgcrypto"`). Note that PostgreSQL's `DROP EXTENSION` does not
779
+ actually take a schema name (unlike `CREATE EXTENSION`), so the resulting SQL statement will only name
780
+ the extension, e.g. `DROP EXTENSION IF EXISTS "pgcrypto"`.
872
781
 
873
- Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
782
+ *Tony Novak*
874
783
 
875
- Now, the encryptor lets the configured `message_serializer` decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize `ActiveRecord::Encryption::Message` objects using a type other than `String`.
784
+ * Make `create_schema` / `drop_schema` reversible in migrations.
876
785
 
877
- The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
786
+ Previously, `create_schema` and `drop_schema` were irreversible migration operations.
878
787
 
879
- *Maxime Réty*
788
+ *Tony Novak*
880
789
 
881
- * Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
882
-
883
- *Maxime Réty*
884
-
885
- * The object returned by `explain` now responds to `pluck`, `first`,
886
- `last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
887
- new methods run `EXPLAIN` on the corresponding queries:
790
+ * Support batching using custom columns.
888
791
 
889
792
  ```ruby
890
- User.all.explain.count
891
- # EXPLAIN SELECT COUNT(*) FROM `users`
892
- # ...
893
-
894
- User.all.explain.maximum(:id)
895
- # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
896
- # ...
793
+ Product.in_batches(cursor: [:shop_id, :id]) do |relation|
794
+ # do something with relation
795
+ end
897
796
  ```
898
797
 
899
- *Petrik de Heus*
900
-
901
- * Fixes an issue where `validates_associated` `:on` option wasn't respected
902
- when validating associated records.
903
-
904
- *Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
798
+ *fatkodima*
905
799
 
906
- * Allow overriding SQLite defaults from `database.yml`.
800
+ * Use SQLite `IMMEDIATE` transactions when possible.
907
801
 
908
- Any PRAGMA configuration set under the `pragmas` key in the configuration
909
- file takes precedence over Rails' defaults, and additional PRAGMAs can be
910
- set as well.
911
-
912
- ```yaml
913
- database: storage/development.sqlite3
914
- timeout: 5000
915
- pragmas:
916
- journal_mode: off
917
- temp_store: memory
918
- ```
802
+ Transactions run against the SQLite3 adapter default to IMMEDIATE mode to improve concurrency support and avoid busy exceptions.
919
803
 
920
804
  *Stephen Margheim*
921
805
 
922
- * Remove warning message when running SQLite in production, but leave it unconfigured.
923
-
924
- There are valid use cases for running SQLite in production. However, it must be done
925
- with care, so instead of a warning most users won't see anyway, it's preferable to
926
- leave the configuration commented out to force them to think about having the database
927
- on a persistent volume etc.
806
+ * Raise specific exception when a connection is not defined.
928
807
 
929
- *Jacopo Beschi*, *Jean Boussier*
808
+ The new `ConnectionNotDefined` exception provides connection name, shard and role accessors indicating the details of the connection that was requested.
930
809
 
931
- * Add support for generated columns to the SQLite3 adapter.
810
+ *Hana Harencarova*, *Matthew Draper*
932
811
 
933
- Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
934
- This adds support for those to the SQLite3 adapter.
812
+ * Delete the deprecated constant `ActiveRecord::ImmutableRelation`.
935
813
 
936
- ```ruby
937
- create_table :users do |t|
938
- t.string :name
939
- t.virtual :name_upper, type: :string, as: 'UPPER(name)'
940
- t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
941
- end
942
- ```
943
-
944
- *Stephen Margheim*
945
-
946
- * TrilogyAdapter: ignore `host` if `socket` parameter is set.
814
+ *Xavier Noria*
947
815
 
948
- This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
816
+ * Fix duplicate callback execution when child autosaves parent with `has_one` and `belongs_to`.
949
817
 
950
- ```
951
- DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
952
- ```
818
+ Before, persisting a new child record with a new associated parent record would run `before_validation`,
819
+ `after_validation`, `before_save` and `after_save` callbacks twice.
953
820
 
954
- *Jean Boussier*
821
+ Now, these callbacks are only executed once as expected.
955
822
 
956
- * Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
957
- `assert_no_queries_match` assertions public.
823
+ *Joshua Young*
958
824
 
959
- To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
960
- `assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
961
- `assert_no_queries_match` are used. These assertions can now be used in applications as well.
825
+ * `ActiveRecord::Encryption::Encryptor` now supports a `:compressor` option to customize the compression algorithm used.
962
826
 
963
827
  ```ruby
964
- class ArticleTest < ActiveSupport::TestCase
965
- test "queries are made" do
966
- assert_queries_count(1) { Article.first }
828
+ module ZstdCompressor
829
+ def self.deflate(data)
830
+ Zstd.compress(data)
967
831
  end
968
832
 
969
- test "creates a foreign key" do
970
- assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
971
- @connection.add_foreign_key(:comments, :posts)
972
- end
833
+ def self.inflate(data)
834
+ Zstd.decompress(data)
973
835
  end
974
836
  end
975
- ```
976
-
977
- *Petrik de Heus*, *fatkodima*
978
-
979
- * Fix `has_secure_token` calls the setter method on initialize.
980
837
 
981
- *Abeid Ahmed*
838
+ class User
839
+ encrypts :name, compressor: ZstdCompressor
840
+ end
841
+ ```
982
842
 
983
- * When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
984
- adapter. This allows decoupling the adapter the application chooses to use from the database connection details
985
- set in the deployment environment.
843
+ You disable compression by passing `compress: false`.
986
844
 
987
845
  ```ruby
988
- # ENV['DATABASE_URL'] = "mysql://localhost/example_database"
989
- config.active_record.protocol_adapters.mysql = "trilogy"
990
- # will connect to MySQL using the trilogy adapter
846
+ class User
847
+ encrypts :name, compress: false
848
+ end
991
849
  ```
992
850
 
993
- *Jean Boussier*, *Kevin McPhillips*
851
+ *heka1024*
994
852
 
995
- * In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
996
- the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
997
- called with a generic warning message rather than silently ignoring the warning(s).
853
+ * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
854
+ `DatabaseConfig`.
998
855
 
999
- *Kevin McPhillips*
856
+ *Hartley McGuire*
1000
857
 
1001
- * `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
858
+ * Add `.shard_keys`, `.sharded?`, & `.connected_to_all_shards` methods.
1002
859
 
1003
- *Andrew Novoselac*
860
+ ```ruby
861
+ class ShardedBase < ActiveRecord::Base
862
+ self.abstract_class = true
1004
863
 
1005
- * Fix `where(field: values)` queries when `field` is a serialized attribute
1006
- (for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
1007
- column).
864
+ connects_to shards: {
865
+ shard_one: { writing: :shard_one },
866
+ shard_two: { writing: :shard_two }
867
+ }
868
+ end
1008
869
 
1009
- *João Alves*
870
+ class ShardedModel < ShardedBase
871
+ end
1010
872
 
1011
- * Make the output of `ActiveRecord::Core#inspect` configurable.
873
+ ShardedModel.shard_keys => [:shard_one, :shard_two]
874
+ ShardedModel.sharded? => true
875
+ ShardedBase.connected_to_all_shards { ShardedModel.current_shard } => [:shard_one, :shard_two]
876
+ ```
1012
877
 
1013
- By default, calling `inspect` on a record will yield a formatted string including just the `id`.
878
+ *Nony Dutton*
1014
879
 
1015
- ```ruby
1016
- Post.first.inspect #=> "#<Post id: 1>"
1017
- ```
880
+ * Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
881
+ by these values.
1018
882
 
1019
- The attributes to be included in the output of `inspect` can be configured with
1020
- `ActiveRecord::Core#attributes_for_inspect`.
883
+ *Igor Depolli*
1021
884
 
1022
- ```ruby
1023
- Post.attributes_for_inspect = [:id, :title]
1024
- Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
1025
- ```
885
+ * Fix an issue where the IDs reader method did not return expected results
886
+ for preloaded associations in models using composite primary keys.
1026
887
 
1027
- With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
888
+ *Jay Ang*
1028
889
 
1029
- ```ruby
1030
- Post.attributes_for_inspect = :all
1031
- Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
1032
- ```
890
+ * Allow to configure `strict_loading_mode` globally or within a model.
1033
891
 
1034
- In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
892
+ Defaults to `:all`, can be changed to `:n_plus_one_only`.
1035
893
 
1036
- You can also call `full_inspect` to get an inspection with all the attributes.
894
+ *Garen Torikian*
1037
895
 
1038
- The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
896
+ * Add `ActiveRecord::Relation#readonly?`.
1039
897
 
1040
- *Andrew Novoselac*
898
+ Reflects if the relation has been marked as readonly.
1041
899
 
1042
- * Don't mark attributes as changed when reassigned to `Float::INFINITY` or
1043
- `-Float::INFINITY`.
900
+ *Theodor Tonum*
1044
901
 
1045
- *Maicol Bentancor*
902
+ * Improve `ActiveRecord::Store` to raise a descriptive exception if the column is not either
903
+ structured (e.g., PostgreSQL +hstore+/+json+, or MySQL +json+) or declared serializable via
904
+ `ActiveRecord.store`.
1046
905
 
1047
- * Support the `RETURNING` clause for MariaDB.
906
+ Previously, a `NoMethodError` would be raised when the accessor was read or written:
1048
907
 
1049
- *fatkodima*, *Nikolay Kondratyev*
908
+ NoMethodError: undefined method `accessor' for an instance of ActiveRecord::Type::Text
1050
909
 
1051
- * The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
910
+ Now, a descriptive `ConfigurationError` is raised:
1052
911
 
1053
- Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
912
+ ActiveRecord::ConfigurationError: the column 'metadata' has not been configured as a store.
913
+ Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your
914
+ database supports it, use a structured column type like hstore or json.
1054
915
 
1055
- ```ruby
1056
- add_reference :person, :alias, foreign_key: { deferrable: :deferred }
1057
- add_reference :alias, :person, foreign_key: { deferrable: :deferred }
1058
- ```
916
+ *Mike Dalessio*
1059
917
 
1060
- *Stephen Margheim*
918
+ * Fix inference of association model on nested models with the same demodularized name.
1061
919
 
1062
- * Add the `set_constraints` helper to PostgreSQL connections.
920
+ E.g. with the following setup:
1063
921
 
1064
922
  ```ruby
1065
- Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
1066
-
1067
- Post.transaction do
1068
- Post.connection.set_constraints(:deferred)
1069
- p = Post.create!(user_id: -1)
1070
- u = User.create!
1071
- p.user = u
1072
- p.save!
923
+ class Nested::Post < ApplicationRecord
924
+ has_one :post, through: :other
1073
925
  end
1074
926
  ```
1075
927
 
1076
- *Cody Cutrer*
1077
-
1078
- * Include `ActiveModel::API` in `ActiveRecord::Base`.
1079
-
1080
- *Sean Doyle*
1081
-
1082
- * Ensure `#signed_id` outputs `url_safe` strings.
1083
-
1084
- *Jason Meller*
928
+ Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
1085
929
 
1086
- * Add `nulls_last` and working `desc.nulls_first` for MySQL.
930
+ *Joshua Young*
1087
931
 
1088
- *Tristan Fellows*
932
+ * Add public method for checking if a table is ignored by the schema cache.
1089
933
 
1090
- * Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
934
+ Previously, an application would need to reimplement `ignored_table?` from the schema cache class to check if a table was set to be ignored. This adds a public method to support this and updates the schema cache to use that directly.
1091
935
 
1092
936
  ```ruby
1093
- Topic.includes(:posts).order(posts: { created_at: :desc })
937
+ ActiveRecord.schema_cache_ignored_tables = ["developers"]
938
+ ActiveRecord.schema_cache_ignored_table?("developers")
939
+ => true
1094
940
  ```
1095
941
 
1096
- *Myles Boone*
942
+ *Eileen M. Uchitelle*
1097
943
 
1098
- Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.
944
+ Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activerecord/CHANGELOG.md) for previous changes.