activerecord 8.0.3 → 8.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +540 -509
- data/README.rdoc +1 -1
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/belongs_to_association.rb +2 -0
- data/lib/active_record/associations/builder/association.rb +16 -5
- data/lib/active_record/associations/builder/belongs_to.rb +17 -4
- data/lib/active_record/associations/builder/collection_association.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +1 -1
- data/lib/active_record/associations/builder/singular_association.rb +33 -5
- data/lib/active_record/associations/collection_proxy.rb +22 -4
- data/lib/active_record/associations/deprecation.rb +88 -0
- data/lib/active_record/associations/errors.rb +3 -0
- data/lib/active_record/associations/join_dependency.rb +2 -0
- data/lib/active_record/associations/preloader/branch.rb +1 -0
- data/lib/active_record/associations.rb +159 -21
- data/lib/active_record/attribute_methods/serialization.rb +16 -3
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +10 -2
- data/lib/active_record/attributes.rb +3 -0
- data/lib/active_record/autosave_association.rb +1 -1
- data/lib/active_record/base.rb +0 -2
- data/lib/active_record/coders/json.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +51 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +405 -72
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +55 -40
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +19 -3
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -24
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +26 -34
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +85 -22
- data/lib/active_record/connection_adapters/abstract/transaction.rb +25 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -20
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +43 -13
- data/lib/active_record/connection_adapters/column.rb +17 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +4 -4
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +42 -5
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +26 -4
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +27 -22
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +17 -15
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +21 -10
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +8 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +8 -21
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +67 -31
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +81 -48
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -7
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +37 -25
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +56 -32
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +4 -3
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +1 -1
- data/lib/active_record/connection_adapters.rb +1 -0
- data/lib/active_record/connection_handling.rb +14 -9
- data/lib/active_record/core.rb +5 -4
- data/lib/active_record/counter_cache.rb +33 -8
- data/lib/active_record/database_configurations/database_config.rb +5 -1
- data/lib/active_record/database_configurations/hash_config.rb +53 -9
- data/lib/active_record/database_configurations/url_config.rb +13 -3
- data/lib/active_record/database_configurations.rb +7 -3
- data/lib/active_record/delegated_type.rb +1 -1
- data/lib/active_record/dynamic_matchers.rb +54 -69
- data/lib/active_record/encryption/encryptable_record.rb +4 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +1 -1
- data/lib/active_record/encryption/encryptor.rb +12 -0
- data/lib/active_record/encryption/scheme.rb +1 -1
- data/lib/active_record/enum.rb +24 -8
- data/lib/active_record/errors.rb +20 -4
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/explain_registry.rb +51 -2
- data/lib/active_record/filter_attribute_handler.rb +73 -0
- data/lib/active_record/fixtures.rb +2 -2
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +1 -1
- data/lib/active_record/insert_all.rb +12 -7
- data/lib/active_record/locking/optimistic.rb +7 -0
- data/lib/active_record/locking/pessimistic.rb +5 -0
- data/lib/active_record/log_subscriber.rb +2 -6
- data/lib/active_record/middleware/shard_selector.rb +34 -17
- data/lib/active_record/migration/command_recorder.rb +14 -1
- data/lib/active_record/migration/compatibility.rb +34 -24
- data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
- data/lib/active_record/migration.rb +26 -16
- data/lib/active_record/model_schema.rb +36 -10
- data/lib/active_record/nested_attributes.rb +2 -0
- data/lib/active_record/persistence.rb +34 -3
- data/lib/active_record/query_cache.rb +22 -15
- data/lib/active_record/query_logs.rb +3 -7
- data/lib/active_record/railtie.rb +33 -4
- data/lib/active_record/railties/controller_runtime.rb +11 -6
- data/lib/active_record/railties/databases.rake +15 -3
- data/lib/active_record/railties/job_checkpoints.rb +15 -0
- data/lib/active_record/railties/job_runtime.rb +10 -11
- data/lib/active_record/reflection.rb +35 -0
- data/lib/active_record/relation/batches.rb +25 -11
- data/lib/active_record/relation/calculations.rb +20 -9
- data/lib/active_record/relation/delegation.rb +0 -1
- data/lib/active_record/relation/finder_methods.rb +27 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -9
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +7 -7
- data/lib/active_record/relation/predicate_builder.rb +9 -7
- data/lib/active_record/relation/query_attribute.rb +3 -1
- data/lib/active_record/relation/query_methods.rb +40 -29
- data/lib/active_record/relation/where_clause.rb +1 -8
- data/lib/active_record/relation.rb +27 -13
- data/lib/active_record/result.rb +44 -21
- data/lib/active_record/runtime_registry.rb +41 -58
- data/lib/active_record/sanitization.rb +2 -0
- data/lib/active_record/schema_dumper.rb +12 -10
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/signed_id.rb +43 -15
- data/lib/active_record/statement_cache.rb +13 -9
- data/lib/active_record/store.rb +44 -19
- data/lib/active_record/structured_event_subscriber.rb +85 -0
- data/lib/active_record/table_metadata.rb +5 -20
- data/lib/active_record/tasks/abstract_tasks.rb +76 -0
- data/lib/active_record/tasks/database_tasks.rb +25 -34
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -40
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -39
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -26
- data/lib/active_record/test_databases.rb +14 -4
- data/lib/active_record/test_fixtures.rb +27 -2
- data/lib/active_record/testing/query_assertions.rb +8 -2
- data/lib/active_record/timestamp.rb +4 -2
- data/lib/active_record/transaction.rb +2 -5
- data/lib/active_record/transactions.rb +32 -10
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
- data/lib/active_record/type/internal/timezone.rb +7 -0
- data/lib/active_record/type/json.rb +15 -2
- data/lib/active_record/type/serialized.rb +11 -4
- data/lib/active_record/type/type_map.rb +1 -1
- data/lib/active_record/type_caster/connection.rb +2 -1
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record.rb +65 -3
- data/lib/arel/alias_predication.rb +2 -0
- data/lib/arel/crud.rb +6 -11
- data/lib/arel/nodes/count.rb +2 -2
- data/lib/arel/nodes/function.rb +4 -10
- data/lib/arel/nodes/named_function.rb +2 -2
- data/lib/arel/nodes/node.rb +1 -1
- data/lib/arel/nodes.rb +0 -2
- data/lib/arel/select_manager.rb +7 -2
- data/lib/arel/visitors/dot.rb +0 -3
- data/lib/arel/visitors/postgresql.rb +55 -0
- data/lib/arel/visitors/sqlite.rb +55 -8
- data/lib/arel/visitors/to_sql.rb +3 -21
- data/lib/arel.rb +3 -1
- data/lib/rails/generators/active_record/application_record/USAGE +1 -1
- metadata +14 -10
- data/lib/active_record/explain_subscriber.rb +0 -34
- data/lib/active_record/normalization.rb +0 -163
data/CHANGELOG.md
CHANGED
|
@@ -1,808 +1,839 @@
|
|
|
1
|
-
## Rails 8.
|
|
1
|
+
## Rails 8.1.1 (October 28, 2025) ##
|
|
2
2
|
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
When a pinned connection is used across separate threads, they now use a separate cache store
|
|
6
|
-
for each thread.
|
|
7
|
-
|
|
8
|
-
This improve accuracy of system tests, and any test using multiple threads.
|
|
9
|
-
|
|
10
|
-
*Heinrich Lee Yu*, *Jean Boussier*
|
|
11
|
-
|
|
12
|
-
* Don't add `id_value` attribute alias when attribute/column with that name already exists.
|
|
13
|
-
|
|
14
|
-
*Rob Lewis*
|
|
3
|
+
* No changes.
|
|
15
4
|
|
|
16
|
-
* Fix false positive change detection involving STI and polymorphic has one relationships.
|
|
17
5
|
|
|
18
|
-
|
|
19
|
-
class, causing nedless extra autosaves.
|
|
6
|
+
## Rails 8.1.0 (October 22, 2025) ##
|
|
20
7
|
|
|
21
|
-
|
|
8
|
+
* Fix SQLite3 data loss during table alterations with CASCADE foreign keys.
|
|
22
9
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
When altering a table in SQLite3 that is referenced by child tables with
|
|
11
|
+
`ON DELETE CASCADE` foreign keys, ActiveRecord would silently delete all
|
|
12
|
+
data from the child tables. This occurred because SQLite requires table
|
|
13
|
+
recreation for schema changes, and during this process the original table
|
|
14
|
+
is temporarily dropped, triggering CASCADE deletes on child tables.
|
|
26
15
|
|
|
27
|
-
|
|
16
|
+
The root cause was incorrect ordering of operations. The original code
|
|
17
|
+
wrapped `disable_referential_integrity` inside a transaction, but
|
|
18
|
+
`PRAGMA foreign_keys` cannot be modified inside a transaction in SQLite -
|
|
19
|
+
attempting to do so simply has no effect. This meant foreign keys remained
|
|
20
|
+
enabled during table recreation, causing CASCADE deletes to fire.
|
|
28
21
|
|
|
29
|
-
|
|
22
|
+
The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
|
|
23
|
+
procedure: `disable_referential_integrity` now wraps the transaction instead
|
|
24
|
+
of being wrapped by it. This ensures foreign keys are properly disabled
|
|
25
|
+
before the transaction starts and re-enabled after it commits, preventing
|
|
26
|
+
CASCADE deletes while maintaining data integrity through atomic transactions.
|
|
30
27
|
|
|
31
|
-
*
|
|
28
|
+
*Ruy Rocha*
|
|
32
29
|
|
|
33
|
-
*
|
|
30
|
+
* Add replicas to test database parallelization setup.
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
Setup and configuration of databases for parallel testing now includes replicas.
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
This fixes an issue when using a replica database, database selector middleware,
|
|
35
|
+
and non-transactional tests, where integration tests running in parallel would select
|
|
36
|
+
the base test database, i.e. `db_test`, instead of the numbered parallel worker database,
|
|
37
|
+
i.e. `db_test_{n}`.
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
primary:
|
|
41
|
-
schema_format: ruby
|
|
42
|
-
```
|
|
39
|
+
*Adam Maas*
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
* Support virtual (not persisted) generated columns on PostgreSQL 18+
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
* Use ntuples to populate row_count instead of count for Postgres
|
|
49
|
-
|
|
50
|
-
*Jonathan Calvert*
|
|
51
|
-
|
|
52
|
-
* Fix `#merge` with `#or` or `#and` and a mixture of attributes and SQL strings resulting in an incorrect query.
|
|
43
|
+
PostgreSQL 18 introduces virtual (not persisted) generated columns,
|
|
44
|
+
which are now the default unless the `stored: true` option is explicitly specified on PostgreSQL 18+.
|
|
53
45
|
|
|
54
46
|
```ruby
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
create_table :users do |t|
|
|
48
|
+
t.string :name
|
|
49
|
+
t.virtual :lower_name, type: :string, as: "LOWER(name)", stored: false
|
|
50
|
+
t.virtual :name_length, type: :integer, as: "LENGTH(name)"
|
|
51
|
+
end
|
|
57
52
|
```
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```SQL
|
|
62
|
-
SELECT "comments".* FROM "comments"
|
|
63
|
-
INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
|
|
64
|
-
WHERE (recent = 1)
|
|
65
|
-
AND (
|
|
66
|
-
"comments"."user_id" = 1
|
|
67
|
-
AND (recent = 1)
|
|
68
|
-
AND "comments"."draft" = 1
|
|
69
|
-
OR "posts"."archived" = 1
|
|
70
|
-
)
|
|
71
|
-
```
|
|
54
|
+
*Yasuo Honda*
|
|
72
55
|
|
|
73
|
-
|
|
56
|
+
* Optimize schema dumping to prevent duplicate file generation.
|
|
74
57
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
AND (recent = 1)
|
|
80
|
-
AND (
|
|
81
|
-
"comments"."user_id" = 1
|
|
82
|
-
AND (recent = 1)
|
|
83
|
-
AND "comments"."draft" = 1
|
|
84
|
-
OR "posts"."archived" = 1
|
|
85
|
-
)
|
|
86
|
-
```
|
|
58
|
+
`ActiveRecord::Tasks::DatabaseTasks.dump_all` now tracks which schema files
|
|
59
|
+
have already been dumped and skips dumping the same file multiple times.
|
|
60
|
+
This improves performance when multiple database configurations share the
|
|
61
|
+
same schema dump path.
|
|
87
62
|
|
|
88
|
-
*
|
|
63
|
+
*Mikey Gough*, *Hartley McGuire*
|
|
89
64
|
|
|
90
|
-
*
|
|
65
|
+
* Add structured events for Active Record:
|
|
66
|
+
- `active_record.strict_loading_violation`
|
|
67
|
+
- `active_record.sql`
|
|
91
68
|
|
|
92
|
-
*
|
|
69
|
+
*Gannon McGibbon*
|
|
93
70
|
|
|
94
|
-
*
|
|
71
|
+
* Add support for integer shard keys.
|
|
72
|
+
```ruby
|
|
73
|
+
# Now accepts symbols as shard keys.
|
|
74
|
+
ActiveRecord::Base.connects_to(shards: {
|
|
75
|
+
1: { writing: :primary_shard_one, reading: :primary_shard_one },
|
|
76
|
+
2: { writing: :primary_shard_two, reading: :primary_shard_two},
|
|
77
|
+
})
|
|
95
78
|
|
|
96
|
-
|
|
79
|
+
ActiveRecord::Base.connected_to(shard: 1) do
|
|
80
|
+
# ..
|
|
81
|
+
end
|
|
82
|
+
```
|
|
97
83
|
|
|
98
|
-
*
|
|
84
|
+
*Nony Dutton*
|
|
99
85
|
|
|
100
|
-
|
|
101
|
-
were appended to the default flags, instead of prepended.
|
|
102
|
-
This caused issues with flags not being taken into account by postgres.
|
|
86
|
+
* Add `ActiveRecord::Base.only_columns`
|
|
103
87
|
|
|
104
|
-
|
|
88
|
+
Similar in use case to `ignored_columns` but listing columns to consider rather than the ones
|
|
89
|
+
to ignore.
|
|
105
90
|
|
|
106
|
-
|
|
91
|
+
Can be useful when working with a legacy or shared database schema, or to make safe schema change
|
|
92
|
+
in two deploys rather than three.
|
|
107
93
|
|
|
108
|
-
*
|
|
94
|
+
*Anton Kandratski*
|
|
109
95
|
|
|
110
|
-
*
|
|
111
|
-
|
|
96
|
+
* Use `PG::Connection#close_prepared` (protocol level Close) to deallocate
|
|
97
|
+
prepared statements when available.
|
|
112
98
|
|
|
113
|
-
|
|
99
|
+
To enable its use, you must have pg >= 1.6.0, libpq >= 17, and a PostgreSQL
|
|
100
|
+
database version >= 17.
|
|
114
101
|
|
|
115
|
-
*
|
|
102
|
+
*Hartley McGuire*, *Andrew Jackson*
|
|
116
103
|
|
|
117
|
-
|
|
118
|
-
in a `after_save` callback had no effect, the transaction was committed
|
|
119
|
-
and a record created.
|
|
104
|
+
* Fix query cache for pinned connections in multi threaded transactional tests
|
|
120
105
|
|
|
121
|
-
|
|
106
|
+
When a pinned connection is used across separate threads, they now use a separate cache store
|
|
107
|
+
for each thread.
|
|
122
108
|
|
|
123
|
-
|
|
109
|
+
This improve accuracy of system tests, and any test using multiple threads.
|
|
124
110
|
|
|
125
|
-
|
|
111
|
+
*Heinrich Lee Yu*, *Jean Boussier*
|
|
126
112
|
|
|
127
|
-
|
|
128
|
-
the most common being with the PostgreSQLAdapter raising `undefined method 'key?' for nil`
|
|
129
|
-
or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
|
|
113
|
+
* Fix time attribute dirty tracking with timezone conversions.
|
|
130
114
|
|
|
131
|
-
|
|
115
|
+
Time-only attributes now maintain a fixed date of 2000-01-01 during timezone conversions,
|
|
116
|
+
preventing them from being incorrectly marked as changed due to date shifts.
|
|
132
117
|
|
|
133
|
-
|
|
118
|
+
This fixes an issue where time attributes would be marked as changed when setting the same time value
|
|
119
|
+
due to timezone conversion causing internal date shifts.
|
|
134
120
|
|
|
135
|
-
*
|
|
121
|
+
*Prateek Choudhary*
|
|
136
122
|
|
|
123
|
+
* Skip calling `PG::Connection#cancel` in `cancel_any_running_query`
|
|
124
|
+
when using libpq >= 18 with pg < 1.6.0, due to incompatibility.
|
|
125
|
+
Rollback still runs, but may take longer.
|
|
137
126
|
|
|
138
|
-
|
|
127
|
+
*Yasuo Honda*, *Lars Kanis*
|
|
139
128
|
|
|
140
|
-
*
|
|
129
|
+
* Don't add `id_value` attribute alias when attribute/column with that name already exists.
|
|
141
130
|
|
|
142
|
-
|
|
131
|
+
*Rob Lewis*
|
|
143
132
|
|
|
144
|
-
|
|
133
|
+
* Remove deprecated `:unsigned_float` and `:unsigned_decimal` column methods for MySQL.
|
|
145
134
|
|
|
135
|
+
*Rafael Mendonça França*
|
|
146
136
|
|
|
147
|
-
|
|
137
|
+
* Remove deprecated `:retries` option for the SQLite3 adapter.
|
|
148
138
|
|
|
149
|
-
*
|
|
139
|
+
*Rafael Mendonça França*
|
|
150
140
|
|
|
151
|
-
|
|
141
|
+
* Introduce new database configuration options `keepalive`, `max_age`, and
|
|
142
|
+
`min_connections` -- and rename `pool` to `max_connections` to match.
|
|
152
143
|
|
|
153
|
-
|
|
144
|
+
There are no changes to default behavior, but these allow for more specific
|
|
145
|
+
control over pool behavior.
|
|
154
146
|
|
|
155
|
-
*
|
|
147
|
+
*Matthew Draper*, *Chris AtLee*, *Rachael Wright-Munn*
|
|
156
148
|
|
|
157
|
-
*
|
|
149
|
+
* Move `LIMIT` validation from query generation to when `limit()` is called.
|
|
158
150
|
|
|
159
|
-
*
|
|
151
|
+
*Hartley McGuire*, *Shuyang*
|
|
160
152
|
|
|
161
|
-
*
|
|
153
|
+
* Add `ActiveRecord::CheckViolation` error class for check constraint violations.
|
|
162
154
|
|
|
163
155
|
*Ryuta Kamizono*
|
|
164
156
|
|
|
165
|
-
*
|
|
166
|
-
|
|
167
|
-
*Chris Gunther*
|
|
168
|
-
|
|
169
|
-
* The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".
|
|
170
|
-
|
|
171
|
-
*Mike Dalessio*
|
|
172
|
-
|
|
173
|
-
* Handle libpq returning a database version of 0 on no/bad connection in `PostgreSQLAdapter`.
|
|
174
|
-
|
|
175
|
-
Before, this version would be cached and an error would be raised during connection configuration when
|
|
176
|
-
comparing it with the minimum required version for the adapter. This meant that the connection could
|
|
177
|
-
never be successfully configured on subsequent reconnection attempts.
|
|
178
|
-
|
|
179
|
-
Now, this is treated as a connection failure consistent with libpq, raising a `ActiveRecord::ConnectionFailed`
|
|
180
|
-
and ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.
|
|
157
|
+
* Add `ActiveRecord::ExclusionViolation` error class for exclusion constraint violations.
|
|
181
158
|
|
|
182
|
-
|
|
159
|
+
When an exclusion constraint is violated in PostgreSQL, the error will now be raised
|
|
160
|
+
as `ActiveRecord::ExclusionViolation` instead of the generic `ActiveRecord::StatementInvalid`,
|
|
161
|
+
making it easier to handle these specific constraint violations in application code.
|
|
183
162
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
This could lead to a partially configured connection being used, resulting in various exceptions,
|
|
188
|
-
the most common being with the PostgreSQLAdapter raising `undefined method `key?' for nil`
|
|
189
|
-
or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
|
|
190
|
-
|
|
191
|
-
*Jean Boussier*
|
|
163
|
+
This follows the same pattern as other constraint violation error classes like
|
|
164
|
+
`RecordNotUnique` for unique constraint violations and `InvalidForeignKey` for
|
|
165
|
+
foreign key constraint violations.
|
|
192
166
|
|
|
193
|
-
*
|
|
167
|
+
*Ryuta Kamizono*
|
|
194
168
|
|
|
195
|
-
|
|
169
|
+
* Attributes filtered by `filter_attributes` will now also be filtered by `filter_parameters`
|
|
170
|
+
so sensitive information is not leaked.
|
|
196
171
|
|
|
197
|
-
*
|
|
172
|
+
*Jill Klang*
|
|
198
173
|
|
|
199
|
-
|
|
174
|
+
* Add `connection.current_transaction.isolation` API to check current transaction's isolation level.
|
|
200
175
|
|
|
201
|
-
|
|
176
|
+
Returns the isolation level if it was explicitly set via the `isolation:` parameter
|
|
177
|
+
or through `ActiveRecord.with_transaction_isolation_level`, otherwise returns `nil`.
|
|
178
|
+
Nested transactions return the parent transaction's isolation level.
|
|
202
179
|
|
|
203
|
-
|
|
204
|
-
|
|
180
|
+
```ruby
|
|
181
|
+
# Returns nil when no transaction
|
|
182
|
+
User.connection.current_transaction.isolation # => nil
|
|
205
183
|
|
|
206
|
-
|
|
184
|
+
# Returns explicitly set isolation level
|
|
185
|
+
User.transaction(isolation: :serializable) do
|
|
186
|
+
User.connection.current_transaction.isolation # => :serializable
|
|
187
|
+
end
|
|
207
188
|
|
|
208
|
-
|
|
189
|
+
# Returns nil when isolation not explicitly set
|
|
190
|
+
User.transaction do
|
|
191
|
+
User.connection.current_transaction.isolation # => nil
|
|
192
|
+
end
|
|
209
193
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
194
|
+
# Nested transactions inherit parent's isolation
|
|
195
|
+
User.transaction(isolation: :read_committed) do
|
|
196
|
+
User.transaction do
|
|
197
|
+
User.connection.current_transaction.isolation # => :read_committed
|
|
198
|
+
end
|
|
214
199
|
end
|
|
215
200
|
```
|
|
216
201
|
|
|
217
|
-
|
|
218
|
-
would no longer be dispatched after using an asynchronous query.
|
|
219
|
-
This is now fixed.
|
|
220
|
-
|
|
221
|
-
*Edouard Chin*
|
|
222
|
-
|
|
223
|
-
* Fix support for PostgreSQL enum types with commas in their name.
|
|
202
|
+
*Kir Shatrov*
|
|
224
203
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
* Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.
|
|
228
|
-
|
|
229
|
-
*Nikita Vasilevsky*
|
|
230
|
-
|
|
231
|
-
* Fix joining on a scoped association with string joins and bind parameters.
|
|
204
|
+
* Fix `#merge` with `#or` or `#and` and a mixture of attributes and SQL strings resulting in an incorrect query.
|
|
232
205
|
|
|
233
206
|
```ruby
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
207
|
+
base = Comment.joins(:post).where(user_id: 1).where("recent = 1")
|
|
208
|
+
puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql
|
|
209
|
+
```
|
|
237
210
|
|
|
238
|
-
|
|
239
|
-
scope :active, -> {
|
|
240
|
-
joins("JOIN students ON instructor_roles.student_id = students.id")
|
|
241
|
-
.where(students { status: 1 })
|
|
242
|
-
}
|
|
243
|
-
end
|
|
211
|
+
Before:
|
|
244
212
|
|
|
245
|
-
|
|
213
|
+
```SQL
|
|
214
|
+
SELECT "comments".* FROM "comments"
|
|
215
|
+
INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
|
|
216
|
+
WHERE (recent = 1)
|
|
217
|
+
AND (
|
|
218
|
+
"comments"."user_id" = 1
|
|
219
|
+
AND (recent = 1)
|
|
220
|
+
AND "comments"."draft" = 1
|
|
221
|
+
OR "posts"."archived" = 1
|
|
222
|
+
)
|
|
246
223
|
```
|
|
247
224
|
|
|
248
|
-
|
|
249
|
-
`active` scope bind parameters would be lost.
|
|
225
|
+
After:
|
|
250
226
|
|
|
251
|
-
|
|
227
|
+
```SQL
|
|
228
|
+
SELECT "comments".* FROM "comments"
|
|
229
|
+
INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
|
|
230
|
+
WHERE "comments"."user_id" = 1
|
|
231
|
+
AND (recent = 1)
|
|
232
|
+
AND (
|
|
233
|
+
"comments"."user_id" = 1
|
|
234
|
+
AND (recent = 1)
|
|
235
|
+
AND "comments"."draft" = 1
|
|
236
|
+
OR "posts"."archived" = 1
|
|
237
|
+
)
|
|
238
|
+
```
|
|
252
239
|
|
|
253
|
-
*
|
|
240
|
+
*Joshua Young*
|
|
254
241
|
|
|
255
|
-
|
|
242
|
+
* Make schema dumper to account for `ActiveRecord.dump_schemas` when dumping in `:ruby` format.
|
|
256
243
|
|
|
257
|
-
*
|
|
244
|
+
*fatkodima*
|
|
258
245
|
|
|
259
|
-
|
|
260
|
-
weren't created nor modified as part of the transaction:
|
|
246
|
+
* Add `:touch` option to `update_column`/`update_columns` methods.
|
|
261
247
|
|
|
262
248
|
```ruby
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
# Will update :updated_at/:updated_on alongside :nice column.
|
|
250
|
+
user.update_column(:nice, true, touch: true)
|
|
265
251
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
two seconds, by default), to avoid repeated reverifications during a
|
|
270
|
-
single request.
|
|
252
|
+
# Will update :updated_at/:updated_on alongside :last_ip column
|
|
253
|
+
user.update_columns(last_ip: request.remote_ip, touch: true)
|
|
254
|
+
```
|
|
271
255
|
|
|
272
|
-
|
|
273
|
-
where connections are leased for the duration of a request, and thus
|
|
274
|
-
only verified once.
|
|
256
|
+
*Dmitrii Ivliev*
|
|
275
257
|
|
|
276
|
-
|
|
258
|
+
* Optimize Active Record batching further when using ranges.
|
|
277
259
|
|
|
260
|
+
Tested on a PostgreSQL table with 10M records and batches of 10k records, the generation
|
|
261
|
+
of relations for the 1000 batches was `4.8x` faster (`6.8s` vs. `1.4s`), used `900x`
|
|
262
|
+
less bandwidth (`180MB` vs. `0.2MB`) and allocated `45x` less memory (`490MB` vs. `11MB`).
|
|
278
263
|
|
|
279
|
-
|
|
264
|
+
*Maxime Réty*, *fatkodima*
|
|
280
265
|
|
|
281
|
-
*
|
|
266
|
+
* Include current character length in error messages for index and table name length validations.
|
|
282
267
|
|
|
283
|
-
*
|
|
268
|
+
*Joshua Young*
|
|
284
269
|
|
|
285
|
-
*
|
|
270
|
+
* Add `rename_schema` method for PostgreSQL.
|
|
286
271
|
|
|
287
|
-
|
|
288
|
-
it could result in a `NoMethodError` being raised.
|
|
272
|
+
*T S Vallender*
|
|
289
273
|
|
|
290
|
-
|
|
274
|
+
* Implement support for deprecating associations:
|
|
291
275
|
|
|
292
|
-
|
|
276
|
+
```ruby
|
|
277
|
+
has_many :posts, deprecated: true
|
|
278
|
+
```
|
|
293
279
|
|
|
294
|
-
|
|
280
|
+
With that, Active Record will report any usage of the `posts` association.
|
|
295
281
|
|
|
296
|
-
|
|
282
|
+
Three reporting modes are supported (`:warn`, `:raise`, and `:notify`), and
|
|
283
|
+
backtraces can be enabled or disabled. Defaults are `:warn` mode and
|
|
284
|
+
disabled backtraces.
|
|
297
285
|
|
|
298
|
-
|
|
286
|
+
Please, check the docs for further details.
|
|
299
287
|
|
|
300
|
-
*
|
|
301
|
-
|
|
302
|
-
*fatkodima*
|
|
288
|
+
*Xavier Noria*
|
|
303
289
|
|
|
304
|
-
*
|
|
290
|
+
* PostgreSQL adapter create DB now supports `locale_provider` and `locale`.
|
|
305
291
|
|
|
306
|
-
*
|
|
292
|
+
*Bengt-Ove Hollaender*
|
|
307
293
|
|
|
308
|
-
*
|
|
294
|
+
* Use ntuples to populate row_count instead of count for Postgres
|
|
309
295
|
|
|
310
|
-
*
|
|
296
|
+
*Jonathan Calvert*
|
|
311
297
|
|
|
312
|
-
* Fix
|
|
298
|
+
* Fix checking whether an unpersisted record is `include?`d in a strictly
|
|
299
|
+
loaded `has_and_belongs_to_many` association.
|
|
313
300
|
|
|
314
|
-
*
|
|
301
|
+
*Hartley McGuire*
|
|
315
302
|
|
|
316
|
-
*
|
|
303
|
+
* Add ability to change transaction isolation for all pools within a block.
|
|
317
304
|
|
|
318
|
-
|
|
305
|
+
This functionality is useful if your application needs to change the database
|
|
306
|
+
transaction isolation for a request or action.
|
|
319
307
|
|
|
320
|
-
|
|
308
|
+
Calling `ActiveRecord.with_transaction_isolation_level(level) {}` in an around filter or
|
|
309
|
+
middleware will set the transaction isolation for all pools accessed within the block,
|
|
310
|
+
but not for the pools that aren't.
|
|
321
311
|
|
|
322
|
-
|
|
312
|
+
This works with explicit and implicit transactions:
|
|
323
313
|
|
|
324
|
-
|
|
314
|
+
```ruby
|
|
315
|
+
ActiveRecord.with_transaction_isolation_level(:read_committed) do
|
|
316
|
+
Tag.transaction do # opens a transaction explicitly
|
|
317
|
+
Tag.create!
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
```
|
|
325
321
|
|
|
326
|
-
|
|
322
|
+
```ruby
|
|
323
|
+
ActiveRecord.with_transaction_isolation_level(:read_committed) do
|
|
324
|
+
Tag.create! # opens a transaction implicitly
|
|
325
|
+
end
|
|
326
|
+
```
|
|
327
327
|
|
|
328
|
-
*
|
|
328
|
+
*Eileen M. Uchitelle*
|
|
329
329
|
|
|
330
|
-
*
|
|
330
|
+
* Raise `ActiveRecord::MissingRequiredOrderError` when order dependent finder methods (e.g. `#first`, `#last`) are
|
|
331
|
+
called without `order` values on the relation, and the model does not have any order columns (`implicit_order_column`,
|
|
332
|
+
`query_constraints`, or `primary_key`) to fall back on.
|
|
331
333
|
|
|
332
|
-
|
|
334
|
+
This change will be introduced with a new framework default for Rails 8.1, and the current behavior of not raising
|
|
335
|
+
an error has been deprecated with the aim of removing the configuration option in Rails 8.2.
|
|
333
336
|
|
|
334
|
-
|
|
337
|
+
```ruby
|
|
338
|
+
config.active_record.raise_on_missing_required_finder_order_columns = true
|
|
339
|
+
```
|
|
335
340
|
|
|
336
341
|
*Joshua Young*
|
|
337
342
|
|
|
338
|
-
*
|
|
343
|
+
* `:class_name` is now invalid in polymorphic `belongs_to` associations.
|
|
339
344
|
|
|
340
|
-
`
|
|
345
|
+
Reason is `:class_name` does not make sense in those associations because
|
|
346
|
+
the class name of target records is dynamic and stored in the type column.
|
|
341
347
|
|
|
342
|
-
|
|
348
|
+
Existing polymorphic associations setting this option can just delete it.
|
|
349
|
+
While it did not raise, it had no effect anyway.
|
|
343
350
|
|
|
344
|
-
*
|
|
351
|
+
*Xavier Noria*
|
|
345
352
|
|
|
346
|
-
|
|
353
|
+
* Add support for multiple databases to `db:migrate:reset`.
|
|
347
354
|
|
|
355
|
+
*Joé Dupuis*
|
|
348
356
|
|
|
349
|
-
|
|
357
|
+
* Add `affected_rows` to `ActiveRecord::Result`.
|
|
350
358
|
|
|
351
|
-
*
|
|
359
|
+
*Jenny Shen*
|
|
352
360
|
|
|
361
|
+
* Enable passing retryable SqlLiterals to `#where`.
|
|
353
362
|
|
|
354
|
-
|
|
363
|
+
*Hartley McGuire*
|
|
355
364
|
|
|
356
|
-
*
|
|
365
|
+
* Set default for primary keys in `insert_all`/`upsert_all`.
|
|
357
366
|
|
|
358
|
-
|
|
367
|
+
Previously in Postgres, updating and inserting new records in one upsert wasn't possible
|
|
368
|
+
due to null primary key values. `nil` primary key values passed into `insert_all`/`upsert_all`
|
|
369
|
+
are now implicitly set to the default insert value specified by adapter.
|
|
359
370
|
|
|
360
|
-
*
|
|
371
|
+
*Jenny Shen*
|
|
361
372
|
|
|
373
|
+
* Add a load hook `active_record_database_configurations` for `ActiveRecord::DatabaseConfigurations`
|
|
362
374
|
|
|
363
|
-
|
|
375
|
+
*Mike Dalessio*
|
|
364
376
|
|
|
365
|
-
*
|
|
377
|
+
* Use `TRUE` and `FALSE` for SQLite queries with boolean columns.
|
|
366
378
|
|
|
367
|
-
*
|
|
379
|
+
*Hartley McGuire*
|
|
368
380
|
|
|
369
|
-
*
|
|
381
|
+
* Bump minimum supported SQLite to 3.23.0.
|
|
370
382
|
|
|
371
|
-
|
|
372
|
-
is created, leading to potential loss of data if a database is added to an
|
|
373
|
-
existing environment.
|
|
383
|
+
*Hartley McGuire*
|
|
374
384
|
|
|
375
|
-
|
|
376
|
-
are loaded during `db:prepare` which defaults to `true` for primary database
|
|
377
|
-
configs and `false` otherwise.
|
|
385
|
+
* Allow allocated Active Records to lookup associations.
|
|
378
386
|
|
|
379
|
-
|
|
387
|
+
Previously, the association cache isn't setup on allocated record objects, so association
|
|
388
|
+
lookups will crash. Test frameworks like mocha use allocate to check for stubbable instance
|
|
389
|
+
methods, which can trigger an association lookup.
|
|
380
390
|
|
|
381
|
-
*
|
|
391
|
+
*Gannon McGibbon*
|
|
382
392
|
|
|
383
|
-
*
|
|
393
|
+
* Encryption now supports `support_unencrypted_data: true` being set per-attribute.
|
|
384
394
|
|
|
385
|
-
|
|
395
|
+
Previously this only worked if `ActiveRecord::Encryption.config.support_unencrypted_data == true`.
|
|
396
|
+
Now, if the global config is turned off, you can still opt in for a specific attribute.
|
|
386
397
|
|
|
387
|
-
|
|
398
|
+
```ruby
|
|
399
|
+
# ActiveRecord::Encryption.config.support_unencrypted_data = true
|
|
400
|
+
class User < ActiveRecord::Base
|
|
401
|
+
encrypts :name, support_unencrypted_data: false # only supports encrypted data
|
|
402
|
+
encrypts :email # supports encrypted or unencrypted data
|
|
403
|
+
end
|
|
404
|
+
```
|
|
388
405
|
|
|
389
|
-
|
|
406
|
+
```ruby
|
|
407
|
+
# ActiveRecord::Encryption.config.support_unencrypted_data = false
|
|
408
|
+
class User < ActiveRecord::Base
|
|
409
|
+
encrypts :name, support_unencrypted_data: true # supports encrypted or unencrypted data
|
|
410
|
+
encrypts :email # only supports encrypted data
|
|
411
|
+
end
|
|
412
|
+
```
|
|
390
413
|
|
|
391
|
-
*
|
|
414
|
+
*Alex Ghiculescu*
|
|
392
415
|
|
|
393
|
-
|
|
416
|
+
* Model generator no longer needs a database connection to validate column types.
|
|
394
417
|
|
|
418
|
+
*Mike Dalessio*
|
|
395
419
|
|
|
396
|
-
|
|
420
|
+
* Allow signed ID verifiers to be configurable via `Rails.application.message_verifiers`
|
|
397
421
|
|
|
398
|
-
|
|
422
|
+
Prior to this change, the primary way to configure signed ID verifiers was
|
|
423
|
+
to set `signed_id_verifier` on each model class:
|
|
399
424
|
|
|
400
|
-
|
|
425
|
+
```ruby
|
|
426
|
+
Post.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
|
|
427
|
+
Comment.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
|
|
428
|
+
```
|
|
401
429
|
|
|
402
|
-
|
|
430
|
+
And if the developer did not set `signed_id_verifier`, a verifier would be
|
|
431
|
+
instantiated with a secret derived from `secret_key_base` and the following
|
|
432
|
+
options:
|
|
403
433
|
|
|
404
|
-
|
|
434
|
+
```ruby
|
|
435
|
+
{ digest: "SHA256", serializer: JSON, url_safe: true }
|
|
436
|
+
```
|
|
405
437
|
|
|
406
|
-
|
|
438
|
+
Thus it was cumbersome to rotate configuration for all verifiers.
|
|
407
439
|
|
|
408
|
-
|
|
440
|
+
This change defines a new Rails config: [`config.active_record.use_legacy_signed_id_verifier`][].
|
|
441
|
+
The default value is `:generate_and_verify`, which preserves the previous
|
|
442
|
+
behavior. However, when set to `:verify`, signed ID verifiers will use
|
|
443
|
+
configuration from `Rails.application.message_verifiers` (specifically,
|
|
444
|
+
`Rails.application.message_verifiers["active_record/signed_id"]`) to
|
|
445
|
+
generate and verify signed IDs, but will also verify signed IDs using the
|
|
446
|
+
older configuration.
|
|
409
447
|
|
|
410
|
-
|
|
448
|
+
To avoid complication, the new behavior only applies when `signed_id_verifier_secret`
|
|
449
|
+
is not set on a model class or any of its ancestors. Additionally,
|
|
450
|
+
`signed_id_verifier_secret` is now deprecated. If you are currently setting
|
|
451
|
+
`signed_id_verifier_secret` on a model class, you can set `signed_id_verifier`
|
|
452
|
+
instead:
|
|
411
453
|
|
|
412
|
-
|
|
454
|
+
```ruby
|
|
455
|
+
# BEFORE
|
|
456
|
+
Post.signed_id_verifier_secret = "my secret"
|
|
413
457
|
|
|
414
|
-
|
|
458
|
+
# AFTER
|
|
459
|
+
Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
|
|
460
|
+
```
|
|
415
461
|
|
|
416
|
-
|
|
462
|
+
To ease migration, `signed_id_verifier` has also been changed to behave as a
|
|
463
|
+
`class_attribute` (i.e. inheritable), but _only when `signed_id_verifier_secret`
|
|
464
|
+
is not set_:
|
|
417
465
|
|
|
418
|
-
|
|
466
|
+
```ruby
|
|
467
|
+
# BEFORE
|
|
468
|
+
ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
|
|
469
|
+
Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
|
|
419
470
|
|
|
420
|
-
|
|
471
|
+
# AFTER
|
|
472
|
+
ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
|
|
473
|
+
Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
|
|
421
474
|
|
|
422
|
-
|
|
475
|
+
Post.signed_id_verifier_secret = "my secret" # => deprecation warning
|
|
476
|
+
Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
|
|
477
|
+
```
|
|
423
478
|
|
|
424
|
-
|
|
479
|
+
Note, however, that it is recommended to eventually migrate from
|
|
480
|
+
model-specific verifiers to a unified configuration managed by
|
|
481
|
+
`Rails.application.message_verifiers`. `ActiveSupport::MessageVerifier#rotate`
|
|
482
|
+
can facilitate that transition. For example:
|
|
425
483
|
|
|
426
|
-
|
|
484
|
+
```ruby
|
|
485
|
+
# BEFORE
|
|
486
|
+
# Generate and verify signed Post IDs using Post-specific configuration
|
|
487
|
+
Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("post secret", ...)
|
|
427
488
|
|
|
428
|
-
|
|
489
|
+
# AFTER
|
|
490
|
+
# Generate and verify signed Post IDs using the unified configuration
|
|
491
|
+
Post.signed_id_verifier = Post.signed_id_verifier.dup
|
|
492
|
+
# Fall back to Post-specific configuration when verifying signed IDs
|
|
493
|
+
Post.signed_id_verifier.rotate("post secret", ...)
|
|
494
|
+
```
|
|
429
495
|
|
|
430
|
-
|
|
496
|
+
[`config.active_record.use_legacy_signed_id_verifier`]: https://guides.rubyonrails.org/v8.1/configuring.html#config-active-record-use-legacy-signed-id-verifier
|
|
431
497
|
|
|
432
|
-
*
|
|
498
|
+
*Ali Sepehri*, *Jonathan Hefner*
|
|
433
499
|
|
|
434
|
-
*
|
|
500
|
+
* Prepend `extra_flags` in postgres' `structure_load`
|
|
435
501
|
|
|
436
|
-
|
|
502
|
+
When specifying `structure_load_flags` with a postgres adapter, the flags
|
|
503
|
+
were appended to the default flags, instead of prepended.
|
|
504
|
+
This caused issues with flags not being taken into account by postgres.
|
|
437
505
|
|
|
438
|
-
*
|
|
439
|
-
specified.
|
|
506
|
+
*Alice Loeser*
|
|
440
507
|
|
|
441
|
-
|
|
508
|
+
* Allow bypassing primary key/constraint addition in `implicit_order_column`
|
|
442
509
|
|
|
443
|
-
|
|
510
|
+
When specifying multiple columns in an array for `implicit_order_column`, adding
|
|
511
|
+
`nil` as the last element will prevent appending the primary key to order
|
|
512
|
+
conditions. This allows more precise control of indexes used by
|
|
513
|
+
generated queries. It should be noted that this feature does introduce the risk
|
|
514
|
+
of API misbehavior if the specified columns are not fully unique.
|
|
444
515
|
|
|
445
|
-
*
|
|
516
|
+
*Issy Long*
|
|
446
517
|
|
|
447
|
-
* Allow `
|
|
518
|
+
* Allow setting the `schema_format` via database configuration.
|
|
448
519
|
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
|
|
520
|
+
```
|
|
521
|
+
primary:
|
|
522
|
+
schema_format: ruby
|
|
452
523
|
```
|
|
453
524
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
|
457
|
-
|
|
458
|
-
Fixes #52742
|
|
525
|
+
Useful for multi-database setups when apps require different formats per-database.
|
|
459
526
|
|
|
460
|
-
*
|
|
527
|
+
*T S Vallender*
|
|
461
528
|
|
|
529
|
+
* Support disabling indexes for MySQL v8.0.0+ and MariaDB v10.6.0+
|
|
462
530
|
|
|
463
|
-
|
|
531
|
+
MySQL 8.0.0 added an option to disable indexes from being used by the query
|
|
532
|
+
optimizer by making them "invisible". This allows the index to still be maintained
|
|
533
|
+
and updated but no queries will be permitted to use it. This can be useful for adding
|
|
534
|
+
new invisible indexes or making existing indexes invisible before dropping them
|
|
535
|
+
to ensure queries are not negatively affected.
|
|
536
|
+
See https://dev.mysql.com/blog-archive/mysql-8-0-invisible-indexes/ for more details.
|
|
464
537
|
|
|
465
|
-
|
|
538
|
+
MariaDB 10.6.0 also added support for this feature by allowing indexes to be "ignored"
|
|
539
|
+
in queries. See https://mariadb.com/kb/en/ignored-indexes/ for more details.
|
|
466
540
|
|
|
467
|
-
|
|
541
|
+
Active Record now supports this option for MySQL 8.0.0+ and MariaDB 10.6.0+ for
|
|
542
|
+
index creation and alteration where the new index option `enabled: true/false` can be
|
|
543
|
+
passed to column and index methods as below:
|
|
468
544
|
|
|
469
545
|
```ruby
|
|
470
|
-
|
|
546
|
+
add_index :users, :email, enabled: false
|
|
547
|
+
enable_index :users, :email
|
|
548
|
+
add_column :users, :dob, :string, index: { enabled: false }
|
|
549
|
+
|
|
550
|
+
change_table :users do |t|
|
|
551
|
+
t.index :name, enabled: false
|
|
552
|
+
t.index :dob
|
|
553
|
+
t.disable_index :dob
|
|
554
|
+
t.column :username, :string, index: { enabled: false }
|
|
555
|
+
t.references :account, index: { enabled: false }
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
create_table :users do |t|
|
|
559
|
+
t.string :name, index: { enabled: false }
|
|
560
|
+
t.string :email
|
|
561
|
+
t.index :email, enabled: false
|
|
562
|
+
end
|
|
471
563
|
```
|
|
472
564
|
|
|
473
|
-
*
|
|
565
|
+
*Merve Taner*
|
|
474
566
|
|
|
475
|
-
*
|
|
476
|
-
on the `add_enum_value` method.
|
|
567
|
+
* Respect `implicit_order_column` in `ActiveRecord::Relation#reverse_order`.
|
|
477
568
|
|
|
478
|
-
*
|
|
569
|
+
*Joshua Young*
|
|
479
570
|
|
|
480
|
-
*
|
|
571
|
+
* Add column types to `ActiveRecord::Result` for SQLite3.
|
|
481
572
|
|
|
482
|
-
*Andrew
|
|
573
|
+
*Andrew Kane*
|
|
483
574
|
|
|
484
|
-
*
|
|
485
|
-
the same child association but different parents does not join all parents.
|
|
575
|
+
* Raise `ActiveRecord::ReadOnlyError` when pessimistically locking with a readonly role.
|
|
486
576
|
|
|
487
|
-
|
|
577
|
+
*Joshua Young*
|
|
488
578
|
|
|
489
|
-
|
|
579
|
+
* Fix using the `SQLite3Adapter`'s `dbconsole` method outside of a Rails application.
|
|
490
580
|
|
|
491
|
-
|
|
581
|
+
*Hartley McGuire*
|
|
492
582
|
|
|
493
|
-
|
|
583
|
+
* Fix migrating multiple databases with `ActiveRecord::PendingMigration` action.
|
|
494
584
|
|
|
495
|
-
*
|
|
585
|
+
*Gannon McGibbon*
|
|
496
586
|
|
|
497
|
-
|
|
498
|
-
|
|
587
|
+
* Enable automatically retrying idempotent association queries on connection
|
|
588
|
+
errors.
|
|
499
589
|
|
|
500
|
-
|
|
590
|
+
*Hartley McGuire*
|
|
501
591
|
|
|
502
|
-
|
|
592
|
+
* Add `allow_retry` to `sql.active_record` instrumentation.
|
|
503
593
|
|
|
504
|
-
|
|
594
|
+
This enables identifying queries which queries are automatically retryable on connection errors.
|
|
505
595
|
|
|
506
|
-
|
|
507
|
-
which we have supported in the core. Now we support MySQL 5.6.4 or later, which
|
|
508
|
-
is the first version to support datetime with precision.
|
|
596
|
+
*Hartley McGuire*
|
|
509
597
|
|
|
510
|
-
|
|
598
|
+
* Better support UPDATE with JOIN for Postgresql and SQLite3
|
|
511
599
|
|
|
512
|
-
|
|
600
|
+
Previously when generating update queries with one or more JOIN clauses,
|
|
601
|
+
Active Record would use a sub query which would prevent to reference the joined
|
|
602
|
+
tables in the `SET` clause, for instance:
|
|
513
603
|
|
|
514
|
-
|
|
515
|
-
|
|
604
|
+
```ruby
|
|
605
|
+
Comment.joins(:post).update_all("title = posts.title")
|
|
606
|
+
```
|
|
516
607
|
|
|
517
|
-
|
|
518
|
-
|
|
608
|
+
This is now supported as long as the relation doesn't also use a `LIMIT`, `ORDER` or
|
|
609
|
+
`GROUP BY` clause. This was supported by the MySQL adapter for a long time.
|
|
519
610
|
|
|
520
611
|
*Jean Boussier*
|
|
521
612
|
|
|
522
|
-
*
|
|
523
|
-
|
|
524
|
-
This ensures that we call `PG::Connection.unescape_bytea` on PostgreSQL before decryption.
|
|
525
|
-
|
|
526
|
-
*Donal McBreen*
|
|
527
|
-
|
|
528
|
-
* Ensure `ActiveRecord::Encryption.config` is always ready before access.
|
|
613
|
+
* Introduce a before-fork hook in `ActiveSupport::Testing::Parallelization` to clear existing
|
|
614
|
+
connections, to avoid fork-safety issues with the mysql2 adapter.
|
|
529
615
|
|
|
530
|
-
|
|
531
|
-
was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
|
|
532
|
-
`ActiveRecord::Base` was loaded would give incorrect results.
|
|
616
|
+
Fixes #41776
|
|
533
617
|
|
|
534
|
-
|
|
535
|
-
soon as needed.
|
|
618
|
+
*Mike Dalessio*, *Donal McBreen*
|
|
536
619
|
|
|
537
|
-
|
|
538
|
-
`ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
|
|
539
|
-
before any use of `ActiveRecord::Base`.
|
|
540
|
-
|
|
541
|
-
*Maxime Réty*
|
|
542
|
-
|
|
543
|
-
* Add `TimeZoneConverter#==` method, so objects will be properly compared by
|
|
544
|
-
their type, scale, limit & precision.
|
|
545
|
-
|
|
546
|
-
Address #52699.
|
|
547
|
-
|
|
548
|
-
*Ruy Rocha*
|
|
549
|
-
|
|
550
|
-
* Add support for SQLite3 full-text-search and other virtual tables.
|
|
551
|
-
|
|
552
|
-
Previously, adding sqlite3 virtual tables messed up `schema.rb`.
|
|
620
|
+
* PoolConfig no longer keeps a reference to the connection class.
|
|
553
621
|
|
|
554
|
-
|
|
622
|
+
Keeping a reference to the class caused subtle issues when combined with reloading in
|
|
623
|
+
development. Fixes #54343.
|
|
555
624
|
|
|
556
|
-
*
|
|
625
|
+
*Mike Dalessio*
|
|
557
626
|
|
|
558
|
-
*
|
|
627
|
+
* Fix SQL notifications sometimes not sent when using async queries.
|
|
559
628
|
|
|
560
629
|
```ruby
|
|
561
|
-
|
|
562
|
-
|
|
630
|
+
Post.async_count
|
|
631
|
+
ActiveSupport::Notifications.subscribed(->(*) { "Will never reach here" }) do
|
|
632
|
+
Post.count
|
|
563
633
|
end
|
|
564
634
|
```
|
|
565
635
|
|
|
566
|
-
|
|
636
|
+
In rare circumstances and under the right race condition, Active Support notifications
|
|
637
|
+
would no longer be dispatched after using an asynchronous query.
|
|
638
|
+
This is now fixed.
|
|
567
639
|
|
|
568
|
-
*
|
|
640
|
+
*Edouard Chin*
|
|
569
641
|
|
|
570
|
-
|
|
642
|
+
* Eliminate queries loading dumped schema cache on Postgres
|
|
571
643
|
|
|
572
|
-
|
|
644
|
+
Improve resiliency by avoiding needing to open a database connection to load the
|
|
645
|
+
type map while defining attribute methods at boot when a schema cache file is
|
|
646
|
+
configured on PostgreSQL databases.
|
|
573
647
|
|
|
574
|
-
|
|
575
|
-
with `:x` and `:y` keys of numeric values, mirroring the functionality of
|
|
576
|
-
existing casts for string and array values. Both string and symbol keys are
|
|
577
|
-
supported.
|
|
648
|
+
*James Coleman*
|
|
578
649
|
|
|
579
|
-
|
|
580
|
-
class PostgresqlPoint < ActiveRecord::Base
|
|
581
|
-
attribute :x, :point
|
|
582
|
-
attribute :y, :point
|
|
583
|
-
attribute :z, :point
|
|
584
|
-
end
|
|
650
|
+
* `ActiveRecord::Coder::JSON` can be instantiated
|
|
585
651
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
z: {x: '12.34', y: -43.21}
|
|
590
|
-
})
|
|
591
|
-
ActiveRecord::Point.new(12.32, -43.21) == val.x == val.y == val.z
|
|
652
|
+
Options can now be passed to `ActiveRecord::Coder::JSON` when instantiating the coder. This allows:
|
|
653
|
+
```ruby
|
|
654
|
+
serialize :config, coder: ActiveRecord::Coder::JSON.new(symbolize_names: true)
|
|
592
655
|
```
|
|
656
|
+
*matthaigh27*
|
|
593
657
|
|
|
594
|
-
|
|
658
|
+
* Deprecate using `insert_all`/`upsert_all` with unpersisted records in associations.
|
|
595
659
|
|
|
596
|
-
|
|
660
|
+
Using these methods on associations containing unpersisted records will now
|
|
661
|
+
show a deprecation warning, as the unpersisted records will be lost after
|
|
662
|
+
the operation.
|
|
597
663
|
|
|
598
|
-
|
|
664
|
+
*Nick Schwaderer*
|
|
599
665
|
|
|
600
|
-
|
|
666
|
+
* Make column name optional for `index_exists?`.
|
|
601
667
|
|
|
602
|
-
|
|
668
|
+
This aligns well with `remove_index` signature as well, where
|
|
669
|
+
index name doesn't need to be derived from the column names.
|
|
603
670
|
|
|
604
|
-
*
|
|
671
|
+
*Ali Ismayiliov*
|
|
605
672
|
|
|
606
|
-
*
|
|
673
|
+
* Change the payload name of `sql.active_record` notification for eager
|
|
674
|
+
loading from "SQL" to "#{model.name} Eager Load".
|
|
607
675
|
|
|
608
|
-
|
|
609
|
-
`enable_extension` statements if they differ from the current schema.
|
|
676
|
+
*zzak*
|
|
610
677
|
|
|
611
|
-
|
|
678
|
+
* Enable automatically retrying idempotent `#exists?` queries on connection
|
|
679
|
+
errors.
|
|
612
680
|
|
|
613
|
-
|
|
614
|
-
enable_extension "heroku_ext.pgcrypto"
|
|
615
|
-
enable_extension "pg_stat_statements"
|
|
616
|
-
```
|
|
681
|
+
*Hartley McGuire*, *classidied*
|
|
617
682
|
|
|
618
|
-
|
|
683
|
+
* Deprecate usage of unsupported methods in conjunction with `update_all`:
|
|
619
684
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
```
|
|
685
|
+
`update_all` will now print a deprecation message if a query includes either `WITH`,
|
|
686
|
+
`WITH RECURSIVE` or `DISTINCT` statements. Those were never supported and were ignored
|
|
687
|
+
when generating the SQL query.
|
|
624
688
|
|
|
625
|
-
|
|
689
|
+
An error will be raised in a future Rails release. This behavior will be consistent
|
|
690
|
+
with `delete_all` which currently raises an error for unsupported statements.
|
|
626
691
|
|
|
627
|
-
*
|
|
628
|
-
actual cast type.
|
|
692
|
+
*Edouard Chin*
|
|
629
693
|
|
|
630
|
-
|
|
694
|
+
* The table columns inside `schema.rb` are now sorted alphabetically.
|
|
631
695
|
|
|
632
|
-
|
|
696
|
+
Previously they'd be sorted by creation order, which can cause merge conflicts when two
|
|
697
|
+
branches modify the same table concurrently.
|
|
633
698
|
|
|
634
|
-
|
|
635
|
-
aggregated in a single bulk insert command.
|
|
699
|
+
*John Duff*
|
|
636
700
|
|
|
637
|
-
|
|
701
|
+
* Introduce versions formatter for the schema dumper.
|
|
638
702
|
|
|
639
|
-
|
|
703
|
+
It is now possible to override how schema dumper formats versions information inside the
|
|
704
|
+
`structure.sql` file. Currently, the versions are simply sorted in the decreasing order.
|
|
705
|
+
Within large teams, this can potentially cause many merge conflicts near the top of the list.
|
|
640
706
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
actually take a schema name (unlike `CREATE EXTENSION`), so the resulting SQL statement will only name
|
|
644
|
-
the extension, e.g. `DROP EXTENSION IF EXISTS "pgcrypto"`.
|
|
707
|
+
Now, the custom formatter can be provided with a custom sorting logic (e.g. by hash values
|
|
708
|
+
of the versions), which can greatly reduce the number of conflicts.
|
|
645
709
|
|
|
646
|
-
*
|
|
710
|
+
*fatkodima*
|
|
647
711
|
|
|
648
|
-
*
|
|
712
|
+
* Serialized attributes can now be marked as comparable.
|
|
649
713
|
|
|
650
|
-
|
|
714
|
+
A not rare issue when working with serialized attributes is that the serialized representation of an object
|
|
715
|
+
can change over time. Either because you are migrating from one serializer to the other (e.g. YAML to JSON or to msgpack),
|
|
716
|
+
or because the serializer used subtly changed its output.
|
|
651
717
|
|
|
652
|
-
|
|
718
|
+
One example is libyaml that used to have some extra trailing whitespaces, and recently fixed that.
|
|
719
|
+
When this sorts of thing happen, you end up with lots of records that report being changed even though
|
|
720
|
+
they aren't, which in the best case leads to a lot more writes to the database and in the worst case lead to nasty bugs.
|
|
653
721
|
|
|
654
|
-
|
|
722
|
+
The solution is to instead compare the deserialized representation of the object, however Active Record
|
|
723
|
+
can't assume the deserialized object has a working `==` method. Hence why this new functionality is opt-in.
|
|
655
724
|
|
|
656
725
|
```ruby
|
|
657
|
-
|
|
658
|
-
# do something with relation
|
|
659
|
-
end
|
|
726
|
+
serialize :config, type: Hash, coder: JSON, comparable: true
|
|
660
727
|
```
|
|
661
728
|
|
|
662
|
-
*
|
|
663
|
-
|
|
664
|
-
* Use SQLite `IMMEDIATE` transactions when possible.
|
|
665
|
-
|
|
666
|
-
Transactions run against the SQLite3 adapter default to IMMEDIATE mode to improve concurrency support and avoid busy exceptions.
|
|
667
|
-
|
|
668
|
-
*Stephen Margheim*
|
|
669
|
-
|
|
670
|
-
* Raise specific exception when a connection is not defined.
|
|
671
|
-
|
|
672
|
-
The new `ConnectionNotDefined` exception provides connection name, shard and role accessors indicating the details of the connection that was requested.
|
|
673
|
-
|
|
674
|
-
*Hana Harencarova*, *Matthew Draper*
|
|
729
|
+
*Jean Boussier*
|
|
675
730
|
|
|
676
|
-
*
|
|
731
|
+
* Fix MySQL default functions getting dropped when changing a column's nullability.
|
|
677
732
|
|
|
678
|
-
*
|
|
733
|
+
*Bastian Bartmann*
|
|
679
734
|
|
|
680
|
-
*
|
|
735
|
+
* SQLite extensions can be configured in `config/database.yml`.
|
|
681
736
|
|
|
682
|
-
|
|
683
|
-
|
|
737
|
+
The database configuration option `extensions:` allows an application to load SQLite extensions
|
|
738
|
+
when using `sqlite3` >= v2.4.0. The array members may be filesystem paths or the names of
|
|
739
|
+
modules that respond to `.to_path`:
|
|
684
740
|
|
|
685
|
-
|
|
741
|
+
``` yaml
|
|
742
|
+
development:
|
|
743
|
+
adapter: sqlite3
|
|
744
|
+
extensions:
|
|
745
|
+
- SQLean::UUID # module name responding to `.to_path`
|
|
746
|
+
- .sqlpkg/nalgeon/crypto/crypto.so # or a filesystem path
|
|
747
|
+
- <%= AppExtensions.location %> # or ruby code returning a path
|
|
748
|
+
```
|
|
686
749
|
|
|
687
|
-
*
|
|
750
|
+
*Mike Dalessio*
|
|
688
751
|
|
|
689
|
-
* `ActiveRecord::
|
|
752
|
+
* `ActiveRecord::Middleware::ShardSelector` supports granular database connection switching.
|
|
690
753
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
end
|
|
754
|
+
A new configuration option, `class_name:`, is introduced to
|
|
755
|
+
`config.active_record.shard_selector` to allow an application to specify the abstract connection
|
|
756
|
+
class to be switched by the shard selection middleware. The default class is
|
|
757
|
+
`ActiveRecord::Base`.
|
|
696
758
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
end
|
|
700
|
-
end
|
|
759
|
+
For example, this configuration tells `ShardSelector` to switch shards using
|
|
760
|
+
`AnimalsRecord.connected_to`:
|
|
701
761
|
|
|
702
|
-
class User
|
|
703
|
-
encrypts :name, compressor: ZstdCompressor
|
|
704
|
-
end
|
|
705
762
|
```
|
|
706
|
-
|
|
707
|
-
You disable compression by passing `compress: false`.
|
|
708
|
-
|
|
709
|
-
```ruby
|
|
710
|
-
class User
|
|
711
|
-
encrypts :name, compress: false
|
|
712
|
-
end
|
|
763
|
+
config.active_record.shard_selector = { class_name: "AnimalsRecord" }
|
|
713
764
|
```
|
|
714
765
|
|
|
715
|
-
*
|
|
716
|
-
|
|
717
|
-
* Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
|
|
718
|
-
`DatabaseConfig`.
|
|
719
|
-
|
|
720
|
-
*Hartley McGuire*
|
|
721
|
-
|
|
722
|
-
* Add `.shard_keys`, `.sharded?`, & `.connected_to_all_shards` methods.
|
|
723
|
-
|
|
724
|
-
```ruby
|
|
725
|
-
class ShardedBase < ActiveRecord::Base
|
|
726
|
-
self.abstract_class = true
|
|
727
|
-
|
|
728
|
-
connects_to shards: {
|
|
729
|
-
shard_one: { writing: :shard_one },
|
|
730
|
-
shard_two: { writing: :shard_two }
|
|
731
|
-
}
|
|
732
|
-
end
|
|
766
|
+
*Mike Dalessio*
|
|
733
767
|
|
|
734
|
-
|
|
735
|
-
end
|
|
768
|
+
* Reset relations after `insert_all`/`upsert_all`.
|
|
736
769
|
|
|
737
|
-
|
|
738
|
-
ShardedModel.sharded? => true
|
|
739
|
-
ShardedBase.connected_to_all_shards { ShardedModel.current_shard } => [:shard_one, :shard_two]
|
|
740
|
-
```
|
|
770
|
+
Bulk insert/upsert methods will now call `reset` if used on a relation, matching the behavior of `update_all`.
|
|
741
771
|
|
|
742
|
-
*
|
|
772
|
+
*Milo Winningham*
|
|
743
773
|
|
|
744
|
-
*
|
|
745
|
-
by these values.
|
|
774
|
+
* Use `_N` as a parallel tests databases suffixes
|
|
746
775
|
|
|
747
|
-
|
|
776
|
+
Peviously, `-N` was used as a suffix. This can cause problems for RDBMSes
|
|
777
|
+
which do not support dashes in database names.
|
|
748
778
|
|
|
749
|
-
*
|
|
750
|
-
for preloaded associations in models using composite primary keys.
|
|
751
|
-
|
|
752
|
-
*Jay Ang*
|
|
779
|
+
*fatkodima*
|
|
753
780
|
|
|
754
|
-
*
|
|
781
|
+
* Remember when a database connection has recently been verified (for
|
|
782
|
+
two seconds, by default), to avoid repeated reverifications during a
|
|
783
|
+
single request.
|
|
755
784
|
|
|
756
|
-
|
|
785
|
+
This should recreate a similar rate of verification as in Rails 7.1,
|
|
786
|
+
where connections are leased for the duration of a request, and thus
|
|
787
|
+
only verified once.
|
|
757
788
|
|
|
758
|
-
*
|
|
789
|
+
*Matthew Draper*
|
|
759
790
|
|
|
760
|
-
*
|
|
791
|
+
* Allow to reset cache counters for multiple records.
|
|
761
792
|
|
|
762
|
-
|
|
793
|
+
```
|
|
794
|
+
Aircraft.reset_counters([1, 2, 3], :wheels_count)
|
|
795
|
+
```
|
|
763
796
|
|
|
764
|
-
|
|
797
|
+
It produces much fewer queries compared to the custom implementation using looping over ids.
|
|
798
|
+
Previously: `O(ids.size * counters.size)` queries, now: `O(ids.size + counters.size)` queries.
|
|
765
799
|
|
|
766
|
-
*
|
|
767
|
-
structured (e.g., PostgreSQL +hstore+/+json+, or MySQL +json+) or declared serializable via
|
|
768
|
-
`ActiveRecord.store`.
|
|
800
|
+
*fatkodima*
|
|
769
801
|
|
|
770
|
-
|
|
802
|
+
* Add `affected_rows` to `sql.active_record` Notification.
|
|
771
803
|
|
|
772
|
-
|
|
804
|
+
*Hartley McGuire*
|
|
773
805
|
|
|
774
|
-
|
|
806
|
+
* Fix `sum` when performing a grouped calculation.
|
|
775
807
|
|
|
776
|
-
|
|
777
|
-
Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your
|
|
778
|
-
database supports it, use a structured column type like hstore or json.
|
|
808
|
+
`User.group(:friendly).sum` no longer worked. This is fixed.
|
|
779
809
|
|
|
780
|
-
*
|
|
810
|
+
*Edouard Chin*
|
|
781
811
|
|
|
782
|
-
*
|
|
812
|
+
* Add support for enabling or disabling transactional tests per database.
|
|
783
813
|
|
|
784
|
-
|
|
814
|
+
A test class can now override the default `use_transactional_tests` setting
|
|
815
|
+
for individual databases, which can be useful if some databases need their
|
|
816
|
+
current state to be accessible to an external process while tests are running.
|
|
785
817
|
|
|
786
818
|
```ruby
|
|
787
|
-
class
|
|
788
|
-
|
|
819
|
+
class MostlyTransactionalTest < ActiveSupport::TestCase
|
|
820
|
+
self.use_transactional_tests = true
|
|
821
|
+
skip_transactional_tests_for_database :shared
|
|
789
822
|
end
|
|
790
823
|
```
|
|
791
824
|
|
|
792
|
-
|
|
825
|
+
*Matthew Cheetham*, *Morgan Mareve*
|
|
793
826
|
|
|
794
|
-
|
|
827
|
+
* Cast `query_cache` value when using URL configuration.
|
|
795
828
|
|
|
796
|
-
*
|
|
829
|
+
*zzak*
|
|
797
830
|
|
|
798
|
-
|
|
831
|
+
* NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.
|
|
799
832
|
|
|
800
|
-
|
|
801
|
-
ActiveRecord.schema_cache_ignored_tables = ["developers"]
|
|
802
|
-
ActiveRecord.schema_cache_ignored_table?("developers")
|
|
803
|
-
=> true
|
|
804
|
-
```
|
|
833
|
+
*Ryuta Kamizono*
|
|
805
834
|
|
|
806
|
-
|
|
835
|
+
* `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
|
|
836
|
+
|
|
837
|
+
*Kazuma Watanabe*
|
|
807
838
|
|
|
808
|
-
Please check [
|
|
839
|
+
Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/activerecord/CHANGELOG.md) for previous changes.
|