activerecord 7.2.1 → 8.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +188 -786
  3. data/README.rdoc +1 -1
  4. data/lib/active_record/associations/association.rb +25 -5
  5. data/lib/active_record/associations/builder/association.rb +7 -6
  6. data/lib/active_record/associations/collection_association.rb +10 -8
  7. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  8. data/lib/active_record/associations/has_many_through_association.rb +3 -2
  9. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  10. data/lib/active_record/associations/join_dependency.rb +4 -4
  11. data/lib/active_record/associations/preloader/association.rb +2 -2
  12. data/lib/active_record/associations/singular_association.rb +8 -3
  13. data/lib/active_record/associations.rb +34 -4
  14. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  15. data/lib/active_record/attribute_assignment.rb +9 -1
  16. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
  17. data/lib/active_record/attributes.rb +1 -2
  18. data/lib/active_record/autosave_association.rb +69 -27
  19. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +16 -10
  20. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
  21. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
  22. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +0 -1
  23. data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
  24. data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -4
  25. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  26. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  27. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +26 -5
  28. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
  29. data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -25
  30. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +20 -38
  31. data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
  32. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
  33. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -45
  34. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +42 -98
  35. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
  36. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -42
  37. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  38. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  39. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -1
  40. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +50 -6
  41. data/lib/active_record/connection_adapters/postgresql_adapter.rb +38 -90
  42. data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
  43. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +76 -100
  44. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
  45. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
  46. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +8 -1
  47. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -12
  48. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
  49. data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
  50. data/lib/active_record/connection_handling.rb +22 -0
  51. data/lib/active_record/core.rb +14 -7
  52. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  53. data/lib/active_record/encryption/config.rb +3 -1
  54. data/lib/active_record/encryption/encryptable_record.rb +4 -4
  55. data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
  56. data/lib/active_record/encryption/encryptor.rb +15 -8
  57. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  58. data/lib/active_record/encryption/key_provider.rb +1 -1
  59. data/lib/active_record/encryption/scheme.rb +8 -1
  60. data/lib/active_record/encryption.rb +2 -0
  61. data/lib/active_record/enum.rb +7 -10
  62. data/lib/active_record/errors.rb +13 -5
  63. data/lib/active_record/fixtures.rb +0 -1
  64. data/lib/active_record/future_result.rb +14 -10
  65. data/lib/active_record/gem_version.rb +4 -4
  66. data/lib/active_record/insert_all.rb +1 -1
  67. data/lib/active_record/migration/command_recorder.rb +22 -5
  68. data/lib/active_record/migration/compatibility.rb +5 -2
  69. data/lib/active_record/migration.rb +35 -33
  70. data/lib/active_record/model_schema.rb +2 -3
  71. data/lib/active_record/nested_attributes.rb +11 -2
  72. data/lib/active_record/persistence.rb +128 -130
  73. data/lib/active_record/query_logs.rb +97 -39
  74. data/lib/active_record/query_logs_formatter.rb +17 -28
  75. data/lib/active_record/querying.rb +6 -6
  76. data/lib/active_record/railtie.rb +8 -14
  77. data/lib/active_record/reflection.rb +9 -4
  78. data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
  79. data/lib/active_record/relation/batches.rb +132 -72
  80. data/lib/active_record/relation/calculations.rb +24 -19
  81. data/lib/active_record/relation/delegation.rb +25 -14
  82. data/lib/active_record/relation/finder_methods.rb +18 -18
  83. data/lib/active_record/relation/merger.rb +8 -8
  84. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
  85. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  86. data/lib/active_record/relation/predicate_builder.rb +6 -1
  87. data/lib/active_record/relation/query_methods.rb +58 -37
  88. data/lib/active_record/relation/record_fetch_warning.rb +2 -2
  89. data/lib/active_record/relation/spawn_methods.rb +1 -1
  90. data/lib/active_record/relation.rb +72 -61
  91. data/lib/active_record/result.rb +68 -7
  92. data/lib/active_record/sanitization.rb +7 -6
  93. data/lib/active_record/schema_dumper.rb +5 -0
  94. data/lib/active_record/schema_migration.rb +2 -1
  95. data/lib/active_record/scoping/named.rb +5 -2
  96. data/lib/active_record/statement_cache.rb +12 -12
  97. data/lib/active_record/store.rb +7 -3
  98. data/lib/active_record/tasks/database_tasks.rb +36 -16
  99. data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
  100. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
  101. data/lib/active_record/test_fixtures.rb +12 -0
  102. data/lib/active_record/token_for.rb +1 -1
  103. data/lib/active_record/validations/uniqueness.rb +9 -8
  104. data/lib/active_record.rb +15 -0
  105. data/lib/arel/collectors/bind.rb +1 -1
  106. metadata +14 -14
data/CHANGELOG.md CHANGED
@@ -1,944 +1,346 @@
1
- ## Rails 7.2.1 (August 22, 2024) ##
1
+ ## Rails 8.0.0.beta1 (September 26, 2024) ##
2
2
 
3
- * Fix detection for `enum` columns with parallelized tests and PostgreSQL.
3
+ * Allow `drop_table` to accept an array of table names.
4
4
 
5
- *Rafael Mendonça França*
5
+ This will let you to drop multiple tables in a single call.
6
6
 
7
- * Allow to eager load nested nil associations.
8
-
9
- *fatkodima*
10
-
11
- * Fix swallowing ignore order warning when batching using `BatchEnumerator`.
12
-
13
- *fatkodima*
14
-
15
- * Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
16
-
17
- *Jean Boussier*
18
-
19
- * Restore inferred association class with the same modularized name.
7
+ ```ruby
8
+ ActiveRecord::Base.lease_connection.drop_table(:users, :posts)
9
+ ```
20
10
 
21
- *Justin Ko*
11
+ *Gabriel Sobrinho*
22
12
 
23
- * Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
13
+ * Add support for PostgreSQL `IF NOT EXISTS` via the `:if_not_exists` option
14
+ on the `add_enum_value` method.
24
15
 
25
- *Jean Boussier*
16
+ *Ariel Rzezak*
26
17
 
27
- * Check invalid `enum` options for the new syntax.
18
+ * When running `db:migrate` on a fresh database, load the database schema before running migrations.
28
19
 
29
- The options using `_` prefix in the old syntax are invalid in the new syntax.
20
+ *Andrew Novoselac*
30
21
 
31
- *Rafael Mendonça França*
22
+ * Fix an issue where `.left_outer_joins` used with multiple associations that have
23
+ the same child association but different parents does not join all parents.
32
24
 
33
- * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
34
- actual cast type.
25
+ Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
35
26
 
36
- *Vasiliy Ermolovich*
27
+ Now it will correctly join both parents.
37
28
 
38
- * Fix `create_table` with `:auto_increment` option for MySQL adapter.
29
+ Fixes #41498.
39
30
 
40
- *fatkodima*
31
+ *Garrett Blehm*
41
32
 
33
+ * Deprecate `unsigned_float` and `unsigned_decimal` short-hand column methods.
42
34
 
43
- ## Rails 7.2.0 (August 09, 2024) ##
35
+ As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE,
36
+ and DECIMAL. Consider using a simple CHECK constraint instead for such columns.
44
37
 
45
- * Handle commas in Sqlite3 default function definitions.
38
+ https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
46
39
 
47
- *Stephen Margheim*
40
+ *Ryuta Kamizono*
48
41
 
49
- * Fixes `validates_associated` raising an exception when configured with a
50
- singular association and having `index_nested_attribute_errors` enabled.
42
+ * Drop MySQL 5.5 support.
51
43
 
52
- *Martin Spickermann*
44
+ MySQL 5.5 is the only version that does not support datetime with precision,
45
+ which we have supported in the core. Now we support MySQL 5.6.4 or later, which
46
+ is the first version to support datetime with precision.
53
47
 
54
- * The constant `ActiveRecord::ImmutableRelation` has been deprecated because
55
- we want to reserve that name for a stronger sense of "immutable relation".
56
- Please use `ActiveRecord::UnmodifiableRelation` instead.
48
+ *Ryuta Kamizono*
57
49
 
58
- *Xavier Noria*
50
+ * Make Active Record asynchronous queries compatible with transactional fixtures.
59
51
 
60
- * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
61
- `DatabaseConfig`.
62
-
63
- *Hartley McGuire*
52
+ Previously transactional fixtures would disable asynchronous queries, because transactional
53
+ fixtures impose all queries use the same connection.
64
54
 
65
- * Fixed a memory performance issue in Active Record attribute methods definition.
55
+ Now asynchronous queries will use the connection pinned by transactional fixtures, and behave
56
+ much closer to production.
66
57
 
67
58
  *Jean Boussier*
68
59
 
69
- * Define the new Active Support notification event `start_transaction.active_record`.
60
+ * Deserialize binary data before decrypting
70
61
 
71
- This event is fired when database transactions or savepoints start, and
72
- complements `transaction.active_record`, which is emitted when they finish.
62
+ This ensures that we call `PG::Connection.unescape_bytea` on PostgreSQL before decryption.
73
63
 
74
- The payload has the transaction (`:transaction`) and the connection (`:connection`).
75
-
76
- *Xavier Noria*
77
-
78
- * Fix an issue where the IDs reader method did not return expected results
79
- for preloaded associations in models using composite primary keys.
80
-
81
- *Jay Ang*
82
-
83
- * The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
84
-
85
- *Xavier Noria*
86
-
87
- * The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
88
-
89
- *Xavier Noria*
64
+ *Donal McBreen*
90
65
 
91
- * 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.
66
+ * Ensure `ActiveRecord::Encryption.config` is always ready before access.
92
67
 
93
- *Xavier Noria*
68
+ Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
69
+ was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
70
+ `ActiveRecord::Base` was loaded would give incorrect results.
94
71
 
95
- * Fix inference of association model on nested models with the same demodularized name.
72
+ `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
73
+ soon as needed.
96
74
 
97
- E.g. with the following setup:
75
+ When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
76
+ `ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
77
+ before any use of `ActiveRecord::Base`.
98
78
 
99
- ```ruby
100
- class Nested::Post < ApplicationRecord
101
- has_one :post, through: :other
102
- end
103
- ```
79
+ *Maxime Réty*
104
80
 
105
- Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
81
+ * Add `TimeZoneConverter#==` method, so objects will be properly compared by
82
+ their type, scale, limit & precision.
106
83
 
107
- *Joshua Young*
84
+ Address #52699.
108
85
 
109
- * PostgreSQL `Cidr#change?` detects the address prefix change.
86
+ *Ruy Rocha*
110
87
 
111
- *Taketo Takashima*
88
+ * Add support for SQLite3 full-text-search and other virtual tables.
112
89
 
113
- * Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
90
+ Previously, adding sqlite3 virtual tables messed up `schema.rb`.
114
91
 
115
- Previously, it always returned `nil`.
92
+ Now, virtual tables can safely be added using `create_virtual_table`.
116
93
 
117
- *fatkodima*
94
+ *Zacharias Knudsen*
118
95
 
119
- * Support `touch_all` in batches.
96
+ * Support use of alternative database interfaces via the `database_cli` ActiveRecord configuration option.
120
97
 
121
98
  ```ruby
122
- Post.in_batches.touch_all
99
+ Rails.application.configure do
100
+ config.active_record.database_cli = { postgresql: "pgcli" }
101
+ end
123
102
  ```
124
103
 
125
- *fatkodima*
126
-
127
- * Add support for `:if_not_exists` and `:force` options to `create_schema`.
128
-
129
- *fatkodima*
130
-
131
- * Fix `index_errors` having incorrect index in association validation errors.
132
-
133
- *lulalala*
134
-
135
- * Add `index_errors: :nested_attributes_order` mode.
136
-
137
- 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.
138
-
139
- *lulalala*
140
-
141
- * Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
142
-
143
- *Joé Dupuis*
144
-
145
- * Association option `query_constraints` is deprecated in favor of `foreign_key`.
146
-
147
- *Nikita Vasilevsky*
148
-
149
- * Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
150
-
151
- 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.
152
-
153
- *DHH*
154
-
155
- * Added support for recursive common table expressions.
156
-
157
- ```ruby
158
- Post.with_recursive(
159
- post_and_replies: [
160
- Post.where(id: 42),
161
- Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
162
- ]
163
- )
164
- ```
104
+ *T S Vallender*
165
105
 
166
- Generates the following SQL:
106
+ * Add support for dumping table inheritance and native partitioning table definitions for PostgeSQL adapter
167
107
 
168
- ```sql
169
- WITH RECURSIVE "post_and_replies" AS (
170
- (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
171
- UNION ALL
172
- (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
173
- )
174
- SELECT "posts".* FROM "posts"
175
- ```
108
+ *Justin Talbott*
176
109
 
177
- *ClearlyClaire*
110
+ * Add support for `ActiveRecord::Point` type casts using `Hash` values
178
111
 
179
- * `validate_constraint` can be called in a `change_table` block.
112
+ This allows `ActiveRecord::Point` to be cast or serialized from a hash
113
+ with `:x` and `:y` keys of numeric values, mirroring the functionality of
114
+ existing casts for string and array values. Both string and symbol keys are
115
+ supported.
180
116
 
181
- ex:
182
117
  ```ruby
183
- change_table :products do |t|
184
- t.check_constraint "price > discounted_price", name: "price_check", validate: false
185
- t.validate_check_constraint "price_check"
118
+ class PostgresqlPoint < ActiveRecord::Base
119
+ attribute :x, :point
120
+ attribute :y, :point
121
+ attribute :z, :point
186
122
  end
187
- ```
188
123
 
189
- *Cody Cutrer*
190
-
191
- * `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
192
-
193
- Ex:
194
- ```ruby
195
- ActiveRecord::Base.connection
196
- .select_value("select '2024-01-01'::date").class #=> Date
124
+ val = PostgresqlPoint.new({
125
+ x: '(12.34, -43.21)',
126
+ y: [12.34, '-43.21'],
127
+ z: {x: '12.34', y: -43.21}
128
+ })
129
+ ActiveRecord::Point.new(12.32, -43.21) == val.x == val.y == val.z
197
130
  ```
198
131
 
199
- *Joé Dupuis*
132
+ *Stephen Drew*
200
133
 
201
- * Strict loading using `:n_plus_one_only` does not eagerly load child associations.
134
+ * Replace `SQLite3::Database#busy_timeout` with `#busy_handler_timeout=`.
202
135
 
203
- With this change, child associations are no longer eagerly loaded, to
204
- match intended behavior and to prevent non-deterministic order issues caused
205
- by calling methods like `first` or `last`. As `first` and `last` don't cause
206
- an N+1 by themselves, calling child associations will no longer raise.
207
- Fixes #49473.
136
+ Provides a non-GVL-blocking, fair retry interval busy handler implementation.
208
137
 
209
- Before:
138
+ *Stephen Margheim*
210
139
 
211
- ```ruby
212
- person = Person.find(1)
213
- person.strict_loading!(mode: :n_plus_one_only)
214
- person.posts.first
215
- # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
216
- person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
217
- ```
140
+ * SQLite3Adapter: Translate `SQLite3::BusyException` into `ActiveRecord::StatementTimeout`.
218
141
 
219
- After:
142
+ *Matthew Nguyen*
220
143
 
221
- ```ruby
222
- person = Person.find(1)
223
- person.strict_loading!(mode: :n_plus_one_only)
224
- person.posts.first # this is 1+1, not N+1
225
- # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
226
- person.posts.first.firm # no longer raises
227
- ```
144
+ * Include schema name in `enable_extension` statements in `db/schema.rb`.
228
145
 
229
- *Reid Lynch*
146
+ The schema dumper will now include the schema name in generated
147
+ `enable_extension` statements if they differ from the current schema.
230
148
 
231
- * Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
232
-
233
- *Mike Dalessio*
234
-
235
- * Allow `ActiveRecord::Base#pluck` to accept hash values.
149
+ For example, if you have a migration:
236
150
 
237
151
  ```ruby
238
- # Before
239
- Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
240
-
241
- # After
242
- Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
152
+ enable_extension "heroku_ext.pgcrypto"
153
+ enable_extension "pg_stat_statements"
243
154
  ```
244
155
 
245
- *fatkodima*
246
-
247
- * Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
248
-
249
- *Kevin McPhillips*
250
-
251
- * `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
252
-
253
- This allows to register callbacks on it.
156
+ then the generated schema dump will also contain:
254
157
 
255
158
  ```ruby
256
- Article.transaction do |transaction|
257
- article.update(published: true)
258
- transaction.after_commit do
259
- PublishNotificationMailer.with(article: article).deliver_later
260
- end
261
- end
159
+ enable_extension "heroku_ext.pgcrypto"
160
+ enable_extension "pg_stat_statements"
262
161
  ```
263
162
 
264
- *Jean Boussier*
163
+ *Tony Novak*
265
164
 
266
- * Add `ActiveRecord::Base.current_transaction`.
165
+ * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
166
+ actual cast type.
267
167
 
268
- Returns the current transaction, to allow registering callbacks on it.
168
+ *Vasiliy Ermolovich*
269
169
 
270
- ```ruby
271
- Article.current_transaction.after_commit do
272
- PublishNotificationMailer.with(article: article).deliver_later
273
- end
274
- ```
170
+ * SQLite3Adapter: Bulk insert fixtures.
275
171
 
276
- *Jean Boussier*
172
+ Previously one insert command was executed for each fixture, now they are
173
+ aggregated in a single bulk insert command.
277
174
 
278
- * Add `ActiveRecord.after_all_transactions_commit` callback.
175
+ *Lázaro Nixon*
279
176
 
280
- Useful for code that may run either inside or outside a transaction and needs
281
- to perform work after the state changes have been properly persisted.
177
+ * PostgreSQLAdapter: Allow `disable_extension` to be called with schema-qualified name.
282
178
 
283
- ```ruby
284
- def publish_article(article)
285
- article.update(published: true)
286
- ActiveRecord.after_all_transactions_commit do
287
- PublishNotificationMailer.with(article: article).deliver_later
288
- end
289
- end
290
- ```
179
+ For parity with `enable_extension`, the `disable_extension` method can be called with a schema-qualified
180
+ name (e.g. `disable_extension "myschema.pgcrypto"`). Note that PostgreSQL's `DROP EXTENSION` does not
181
+ actually take a schema name (unlike `CREATE EXTENSION`), so the resulting SQL statement will only name
182
+ the extension, e.g. `DROP EXTENSION IF EXISTS "pgcrypto"`.
291
183
 
292
- In the above example, the block is either executed immediately if called outside
293
- of a transaction, or called after the open transaction is committed.
184
+ *Tony Novak*
294
185
 
295
- If the transaction is rolled back, the block isn't called.
186
+ * Make `create_schema` / `drop_schema` reversible in migrations.
296
187
 
297
- *Jean Boussier*
188
+ Previously, `create_schema` and `drop_schema` were irreversible migration operations.
298
189
 
299
- * Add the ability to ignore counter cache columns until they are backfilled.
190
+ *Tony Novak*
300
191
 
301
- Starting to use counter caches on existing large tables can be troublesome, because the column
302
- values must be backfilled separately of the column addition (to not lock the table for too long)
303
- and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
304
- counter caches internally, can produce incorrect results). People usually use database triggers
305
- or callbacks on child associations while backfilling before introducing a counter cache
306
- configuration to the association.
307
-
308
- Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
192
+ * Support batching using custom columns.
309
193
 
310
194
  ```ruby
311
- class Comment < ApplicationRecord
312
- belongs_to :post, counter_cache: { active: false }
195
+ Product.in_batches(cursor: [:shop_id, :id]) do |relation|
196
+ # do something with relation
313
197
  end
314
198
  ```
315
199
 
316
- While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
317
- but get the results directly from the database. After the counter cache column is backfilled, simply
318
- remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
319
- mentioned methods.
320
-
321
200
  *fatkodima*
322
201
 
323
- * Retry known idempotent SELECT queries on connection-related exceptions.
324
-
325
- SELECT queries we construct by walking the Arel tree and / or with known model attributes
326
- are idempotent and can safely be retried in the case of a connection error. Previously,
327
- adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
328
- when encountering a connection error mid-request.
329
-
330
- *Adrianna Chang*
331
-
332
- * Allow association's `foreign_key` to be composite.
333
-
334
- `query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
335
- Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
336
-
337
- *Nikita Vasilevsky*
338
-
339
- * Allow association's `primary_key` to be composite.
340
-
341
- Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
342
- Now it's possible to explicitly set it as composite on the association.
343
-
344
- *Nikita Vasilevsky*
345
-
346
- * Add `config.active_record.permanent_connection_checkout` setting.
202
+ * Use SQLite `IMMEDIATE` transactions when possible.
347
203
 
348
- Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
204
+ Transactions run against the SQLite3 adapter default to IMMEDIATE mode to improve concurrency support and avoid busy exceptions.
349
205
 
350
- `ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
351
- the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
352
- is available connections.
353
-
354
- This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
355
- migrate it to use `ActiveRecord::Base.with_connection` instead.
356
-
357
- The default behavior remains unchanged, and there is currently no plans to change the default.
358
-
359
- *Jean Boussier*
360
-
361
- * Add dirties option to uncached.
362
-
363
- This adds a `dirties` option to `ActiveRecord::Base.uncached` and
364
- `ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
365
-
366
- When set to `true` (the default), writes will clear all query caches belonging to the current thread.
367
- When set to `false`, writes to the affected connection pool will not clear any query cache.
368
-
369
- This is needed by Solid Cache so that cache writes do not clear query caches.
370
-
371
- *Donal McBreen*
372
-
373
- * Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
374
-
375
- The method has been renamed as `lease_connection` to better reflect that the returned
376
- connection will be held for the duration of the request or job.
377
-
378
- This deprecation is a soft deprecation, no warnings will be issued and there is no
379
- current plan to remove the method.
380
-
381
- *Jean Boussier*
382
-
383
- * Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
384
-
385
- The method has been renamed as `lease_connection` to better reflect that the returned
386
- connection will be held for the duration of the request or job.
387
-
388
- *Jean Boussier*
206
+ *Stephen Margheim*
389
207
 
390
- * Expose a generic fixture accessor for fixture names that may conflict with Minitest.
208
+ * Raise specific exception when a connection is not defined.
391
209
 
392
- ```ruby
393
- assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
394
- assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
395
- ```
210
+ The new `ConnectionNotDefined` exception provides connection name, shard and role accessors indicating the details of the connection that was requested.
396
211
 
397
- *Jean Boussier*
212
+ *Hana Harencarova*, *Matthew Draper*
398
213
 
399
- * Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
400
- incorrect error message.
214
+ * Delete the deprecated constant `ActiveRecord::ImmutableRelation`.
401
215
 
402
- This has been fixed to raise with a more appropriate error message.
216
+ *Xavier Noria*
403
217
 
404
- *Joshua Young*
218
+ * Fix duplicate callback execution when child autosaves parent with `has_one` and `belongs_to`.
405
219
 
406
- * Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
220
+ Before, persisting a new child record with a new associated parent record would run `before_validation`,
221
+ `after_validation`, `before_save` and `after_save` callbacks twice.
407
222
 
408
- This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
409
- an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
223
+ Now, these callbacks are only executed once as expected.
410
224
 
411
225
  *Joshua Young*
412
226
 
413
- * Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
414
-
415
- *Rafael Mendonça França*
416
-
417
- * Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
418
-
419
- *Rafael Mendonça França*
420
-
421
- * Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
422
-
423
- *Rafael Mendonça França*
424
-
425
- * Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
426
-
427
- *Rafael Mendonça França*
428
-
429
- * Remove deprecated support to quote `ActiveSupport::Duration`.
430
-
431
- *Rafael Mendonça França*
432
-
433
- * Remove deprecated `#quote_bound_value`.
434
-
435
- *Rafael Mendonça França*
436
-
437
- * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
438
-
439
- *Rafael Mendonça França*
440
-
441
- * Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
442
- `#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
443
- for the current role when the `role` argument isn't provided.
444
-
445
- *Rafael Mendonça França*
446
-
447
- * Remove deprecated `#all_connection_pools`.
448
-
449
- *Rafael Mendonça França*
450
-
451
- * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
452
-
453
- *Rafael Mendonça França*
454
-
455
- * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
456
-
457
- *Rafael Mendonça França*
458
-
459
- * Remove deprecated `#all_foreign_keys_valid?` from database adapters.
460
-
461
- *Rafael Mendonça França*
462
-
463
- * Remove deprecated support to passing coder and class as second argument to `serialize`.
464
-
465
- *Rafael Mendonça França*
466
-
467
- * Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
468
-
469
- *Rafael Mendonça França*
470
-
471
- * Remove deprecated `TestFixtures.fixture_path`.
472
-
473
- *Rafael Mendonça França*
474
-
475
- * Remove deprecated behavior to support referring to a singular association by its plural name.
476
-
477
- *Rafael Mendonça França*
478
-
479
- * Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
480
-
481
- *Rafael Mendonça França*
482
-
483
- * Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
484
- `ActiveRecord::MigrationContext`.
485
-
486
- *Rafael Mendonça França*
487
-
488
- * Remove deprecated `ActiveRecord::Migration.check_pending!` method.
489
-
490
- *Rafael Mendonça França*
491
-
492
- * Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
493
-
494
- *Rafael Mendonça França*
495
-
496
- * Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
497
-
498
- *Rafael Mendonça França*
499
-
500
- * Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
501
-
502
- *Rafael Mendonça França*
503
-
504
- * Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
505
-
506
- *Rafael Mendonça França*
507
-
508
- * Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
509
-
510
- *Rafael Mendonça França*
511
-
512
- * Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
513
-
514
- *Rafael Mendonça França*
515
-
516
- * Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
517
-
518
- *Rafael Mendonça França*
519
-
520
- * Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
521
-
522
- *Rafael Mendonça França*
523
-
524
- * Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
525
-
526
- *Rafael Mendonça França*
527
-
528
- * Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
529
-
530
- *Rafael Mendonça França*
531
-
532
- * Remove deprecated support to call `alias_attribute` with non-existent attribute names.
533
-
534
- *Rafael Mendonça França*
535
-
536
- * Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
537
-
538
- *Rafael Mendonça França*
539
-
540
- * Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
541
-
542
- Serialize data to the MessagePack format, for efficient storage in binary columns.
543
-
544
- The binary encoding requires around 30% less space than the base64 encoding
545
- used by the default serializer.
546
-
547
- *Donal McBreen*
548
-
549
- * Add support for encrypting binary columns.
550
-
551
- Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
552
-
553
- Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
554
- incidentally worked for MySQL and SQLite, but not PostgreSQL.
555
-
556
- *Donal McBreen*
557
-
558
- * Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
559
-
560
- *Rafael Mendonça França*
561
-
562
- * Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
563
-
564
- The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
565
- will yield that same connection.
566
-
567
- This is useful to perform a few database operations without causing a connection to be leased for the
568
- entire duration of the request or job.
569
-
570
- *Jean Boussier*
571
-
572
- * Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
573
- notification includes `:row_count` field.
574
-
575
- *Jason Nochlin*
576
-
577
- * The fix ensures that the association is joined using the appropriate join type
578
- (either inner join or left outer join) based on the existing joins in the scope.
579
-
580
- This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
581
-
582
- Example:
583
-
584
-
227
+ * `ActiveRecord::Encryption::Encryptor` now supports a `:compressor` option to customize the compression algorithm used.
585
228
 
586
229
  ```ruby
587
- # `associated` will use `LEFT JOIN` instead of using `JOIN`
588
- Post.left_joins(:author).where.associated(:author)
589
- ```
590
-
591
- *Saleh Alhaddad*
592
-
593
- * Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
594
- of Active Record models, when an application is eager loaded. As a result, encrypted attributes
595
- could be misconfigured in some cases.
596
-
597
- *Maxime Réty*
598
-
599
- * Deprecate defining an `enum` with keyword arguments.
230
+ module ZstdCompressor
231
+ def self.deflate(data)
232
+ Zstd.compress(data)
233
+ end
600
234
 
601
- ```ruby
602
- class Function > ApplicationRecord
603
- # BAD
604
- enum color: [:red, :blue],
605
- type: [:instance, :class]
606
-
607
- # GOOD
608
- enum :color, [:red, :blue]
609
- enum :type, [:instance, :class]
235
+ def self.inflate(data)
236
+ Zstd.decompress(data)
237
+ end
610
238
  end
611
- ```
612
-
613
- *Hartley McGuire*
614
-
615
- * Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
616
-
617
- When set, validates that the timestamp prefix for a migration is no more than a day ahead of
618
- the timestamp associated with the current time. This is designed to prevent migrations prefixes
619
- from being hand-edited to future timestamps, which impacts migration generation and other
620
- migration commands.
621
-
622
- *Adrianna Chang*
623
-
624
- * Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
625
239
 
626
- As well as `disconnect!` and `verify!`.
627
-
628
- This generally isn't a big problem as connections must not be shared between
629
- threads, but is required when running transactional tests or system tests
630
- and could lead to a SEGV.
631
-
632
- *Jean Boussier*
633
-
634
- * Support `:source_location` tag option for query log tags.
635
-
636
- ```ruby
637
- config.active_record.query_log_tags << :source_location
240
+ class User
241
+ encrypts :name, compressor: ZstdCompressor
242
+ end
638
243
  ```
639
244
 
640
- Calculating the caller location is a costly operation and should be used primarily in development
641
- (note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
642
- or occasionally on production for debugging purposes.
643
-
644
- *fatkodima*
645
-
646
- * Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
647
-
648
- Allow compression to be disabled by setting `compress: false`
245
+ You disable compression by passing `compress: false`.
649
246
 
650
247
  ```ruby
651
- class User
652
- encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
653
- end
248
+ class User
249
+ encrypts :name, compress: false
250
+ end
654
251
  ```
655
252
 
656
- *Donal McBreen*
657
-
658
- * Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
659
-
660
- A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
661
-
662
- *Rafael Mendonça França*
663
-
664
- * Add `row_count` field to `sql.active_record` notification.
665
-
666
- This field returns the amount of rows returned by the query that emitted the notification.
667
-
668
- This metric is useful in cases where one wants to detect queries with big result sets.
669
-
670
- *Marvin Bitterlich*
671
-
672
- * Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
673
-
674
- Previously, this would only raise on collection associations and produce a generic error on singular associations.
253
+ *heka1024*
675
254
 
676
- Now, it will raise on both collection and singular associations.
677
-
678
- *Joshua Young*
679
-
680
- * Fix single quote escapes on default generated MySQL columns.
681
-
682
- MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
683
-
684
- Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
685
-
686
- This would result in issues when importing the schema on a fresh instance of a MySQL database.
687
-
688
- Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
689
-
690
- *Yash Kapadia*
691
-
692
- * Fix Migrations with versions older than 7.1 validating options given to
693
- `add_reference` and `t.references`.
255
+ * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
256
+ `DatabaseConfig`.
694
257
 
695
258
  *Hartley McGuire*
696
259
 
697
- * Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
698
-
699
- *JP Rosevear*
700
-
701
- * Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
702
-
703
- This wouldn't always work previously because boolean values would be interpreted as strings.
704
-
705
- e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
706
- cache.
707
-
708
- *Mike Coutermarsh*, *Jean Boussier*
709
-
710
- * Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
711
-
712
- It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
713
- but with support for `after_commit` and `after_rollback` callback options.
714
-
715
- *Joshua Young*
716
-
717
- * Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
718
-
719
- Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
720
-
721
- 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`.
722
-
723
- The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
724
-
725
- *Maxime Réty*
726
-
727
- * Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
728
-
729
- *Maxime Réty*
730
-
731
- * The object returned by `explain` now responds to `pluck`, `first`,
732
- `last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
733
- new methods run `EXPLAIN` on the corresponding queries:
260
+ * Add `.shard_keys`, `.sharded?`, & `.connected_to_all_shards` methods.
734
261
 
735
262
  ```ruby
736
- User.all.explain.count
737
- # EXPLAIN SELECT COUNT(*) FROM `users`
738
- # ...
739
-
740
- User.all.explain.maximum(:id)
741
- # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
742
- # ...
743
- ```
744
-
745
- *Petrik de Heus*
746
-
747
- * Fixes an issue where `validates_associated` `:on` option wasn't respected
748
- when validating associated records.
263
+ class ShardedBase < ActiveRecord::Base
264
+ self.abstract_class = true
749
265
 
750
- *Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
751
-
752
- * Allow overriding SQLite defaults from `database.yml`.
753
-
754
- Any PRAGMA configuration set under the `pragmas` key in the configuration
755
- file takes precedence over Rails' defaults, and additional PRAGMAs can be
756
- set as well.
757
-
758
- ```yaml
759
- database: storage/development.sqlite3
760
- timeout: 5000
761
- pragmas:
762
- journal_mode: off
763
- temp_store: memory
764
- ```
765
-
766
- *Stephen Margheim*
767
-
768
- * Remove warning message when running SQLite in production, but leave it unconfigured.
769
-
770
- There are valid use cases for running SQLite in production. However, it must be done
771
- with care, so instead of a warning most users won't see anyway, it's preferable to
772
- leave the configuration commented out to force them to think about having the database
773
- on a persistent volume etc.
774
-
775
- *Jacopo Beschi*, *Jean Boussier*
776
-
777
- * Add support for generated columns to the SQLite3 adapter.
778
-
779
- Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
780
- This adds support for those to the SQLite3 adapter.
781
-
782
- ```ruby
783
- create_table :users do |t|
784
- t.string :name
785
- t.virtual :name_upper, type: :string, as: 'UPPER(name)'
786
- t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
266
+ connects_to shards: {
267
+ shard_one: { writing: :shard_one },
268
+ shard_two: { writing: :shard_two }
269
+ }
787
270
  end
788
- ```
789
-
790
- *Stephen Margheim*
791
-
792
- * TrilogyAdapter: ignore `host` if `socket` parameter is set.
793
-
794
- This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
795
-
796
- ```
797
- DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
798
- ```
799
-
800
- *Jean Boussier*
801
271
 
802
- * Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
803
- `assert_no_queries_match` assertions public.
804
-
805
- To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
806
- `assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
807
- `assert_no_queries_match` are used. These assertions can now be used in applications as well.
808
-
809
- ```ruby
810
- class ArticleTest < ActiveSupport::TestCase
811
- test "queries are made" do
812
- assert_queries_count(1) { Article.first }
813
- end
814
-
815
- test "creates a foreign key" do
816
- assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
817
- @connection.add_foreign_key(:comments, :posts)
818
- end
819
- end
272
+ class ShardedModel < ShardedBase
820
273
  end
821
- ```
822
-
823
- *Petrik de Heus*, *fatkodima*
824
-
825
- * Fix `has_secure_token` calls the setter method on initialize.
826
274
 
827
- *Abeid Ahmed*
828
-
829
- * When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
830
- adapter. This allows decoupling the adapter the application chooses to use from the database connection details
831
- set in the deployment environment.
832
-
833
- ```ruby
834
- # ENV['DATABASE_URL'] = "mysql://localhost/example_database"
835
- config.active_record.protocol_adapters.mysql = "trilogy"
836
- # will connect to MySQL using the trilogy adapter
275
+ ShardedModel.shard_keys => [:shard_one, :shard_two]
276
+ ShardedModel.sharded? => true
277
+ ShardedBase.connected_to_all_shards { ShardedModel.current_shard } => [:shard_one, :shard_two]
837
278
  ```
838
279
 
839
- *Jean Boussier*, *Kevin McPhillips*
280
+ *Nony Dutton*
840
281
 
841
- * In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
842
- the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
843
- called with a generic warning message rather than silently ignoring the warning(s).
844
-
845
- *Kevin McPhillips*
846
-
847
- * `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
848
-
849
- *Andrew Novoselac*
850
-
851
- * Fix `where(field: values)` queries when `field` is a serialized attribute
852
- (for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
853
- column).
854
-
855
- *João Alves*
856
-
857
- * Make the output of `ActiveRecord::Core#inspect` configurable.
858
-
859
- By default, calling `inspect` on a record will yield a formatted string including just the `id`.
860
-
861
- ```ruby
862
- Post.first.inspect #=> "#<Post id: 1>"
863
- ```
282
+ * Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
283
+ by these values.
864
284
 
865
- The attributes to be included in the output of `inspect` can be configured with
866
- `ActiveRecord::Core#attributes_for_inspect`.
285
+ *Igor Depolli*
867
286
 
868
- ```ruby
869
- Post.attributes_for_inspect = [:id, :title]
870
- Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
871
- ```
287
+ * Fix an issue where the IDs reader method did not return expected results
288
+ for preloaded associations in models using composite primary keys.
872
289
 
873
- With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
290
+ *Jay Ang*
874
291
 
875
- ```ruby
876
- Post.attributes_for_inspect = :all
877
- Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
878
- ```
292
+ * Allow to configure `strict_loading_mode` globally or within a model.
879
293
 
880
- In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
294
+ Defaults to `:all`, can be changed to `:n_plus_one_only`.
881
295
 
882
- You can also call `full_inspect` to get an inspection with all the attributes.
296
+ *Garen Torikian*
883
297
 
884
- The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
298
+ * Add `ActiveRecord::Relation#readonly?`.
885
299
 
886
- *Andrew Novoselac*
300
+ Reflects if the relation has been marked as readonly.
887
301
 
888
- * Don't mark attributes as changed when reassigned to `Float::INFINITY` or
889
- `-Float::INFINITY`.
302
+ *Theodor Tonum*
890
303
 
891
- *Maicol Bentancor*
304
+ * Improve `ActiveRecord::Store` to raise a descriptive exception if the column is not either
305
+ structured (e.g., PostgreSQL +hstore+/+json+, or MySQL +json+) or declared serializable via
306
+ `ActiveRecord.store`.
892
307
 
893
- * Support the `RETURNING` clause for MariaDB.
308
+ Previously, a `NoMethodError` would be raised when the accessor was read or written:
894
309
 
895
- *fatkodima*, *Nikolay Kondratyev*
310
+ NoMethodError: undefined method `accessor' for an instance of ActiveRecord::Type::Text
896
311
 
897
- * The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
312
+ Now, a descriptive `ConfigurationError` is raised:
898
313
 
899
- Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
314
+ ActiveRecord::ConfigurationError: the column 'metadata' has not been configured as a store.
315
+ Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your
316
+ database supports it, use a structured column type like hstore or json.
900
317
 
901
- ```ruby
902
- add_reference :person, :alias, foreign_key: { deferrable: :deferred }
903
- add_reference :alias, :person, foreign_key: { deferrable: :deferred }
904
- ```
318
+ *Mike Dalessio*
905
319
 
906
- *Stephen Margheim*
320
+ * Fix inference of association model on nested models with the same demodularized name.
907
321
 
908
- * Add the `set_constraints` helper to PostgreSQL connections.
322
+ E.g. with the following setup:
909
323
 
910
324
  ```ruby
911
- Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
912
-
913
- Post.transaction do
914
- Post.connection.set_constraints(:deferred)
915
- p = Post.create!(user_id: -1)
916
- u = User.create!
917
- p.user = u
918
- p.save!
325
+ class Nested::Post < ApplicationRecord
326
+ has_one :post, through: :other
919
327
  end
920
328
  ```
921
329
 
922
- *Cody Cutrer*
923
-
924
- * Include `ActiveModel::API` in `ActiveRecord::Base`.
925
-
926
- *Sean Doyle*
927
-
928
- * Ensure `#signed_id` outputs `url_safe` strings.
929
-
930
- *Jason Meller*
330
+ Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
931
331
 
932
- * Add `nulls_last` and working `desc.nulls_first` for MySQL.
332
+ *Joshua Young*
933
333
 
934
- *Tristan Fellows*
334
+ * Add public method for checking if a table is ignored by the schema cache.
935
335
 
936
- * Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
336
+ 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.
937
337
 
938
338
  ```ruby
939
- Topic.includes(:posts).order(posts: { created_at: :desc })
339
+ ActiveRecord.schema_cache_ignored_tables = ["developers"]
340
+ ActiveRecord.schema_cache_ignored_table?("developers")
341
+ => true
940
342
  ```
941
343
 
942
- *Myles Boone*
344
+ *Eileen M. Uchitelle*
943
345
 
944
- Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.
346
+ Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activerecord/CHANGELOG.md) for previous changes.