activerecord 6.1.7.4 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1055 -1170
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +33 -17
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +18 -19
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +6 -2
- data/lib/active_record/associations/preloader/association.rb +186 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +49 -13
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +90 -82
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +49 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +13 -14
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +6 -21
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +43 -82
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +69 -18
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +35 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -76
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +27 -16
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +15 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +47 -53
- data/lib/active_record/core.rb +121 -146
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +52 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +90 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +49 -42
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +17 -20
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/locking/pessimistic.rb +9 -3
- data/lib/active_record/log_subscriber.rb +14 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +110 -80
- data/lib/active_record/model_schema.rb +45 -58
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +219 -52
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +138 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +127 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +66 -129
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +67 -50
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +40 -36
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +31 -35
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +235 -63
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +169 -84
- data/lib/active_record/result.rb +17 -7
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +10 -3
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +116 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/active_record.rb +204 -28
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +58 -14
data/CHANGELOG.md
CHANGED
@@ -1,134 +1,4 @@
|
|
1
|
-
## Rails
|
2
|
-
|
3
|
-
* No changes.
|
4
|
-
|
5
|
-
|
6
|
-
## Rails 6.1.7.3 (March 13, 2023) ##
|
7
|
-
|
8
|
-
* No changes.
|
9
|
-
|
10
|
-
|
11
|
-
## Rails 6.1.7.2 (January 24, 2023) ##
|
12
|
-
|
13
|
-
* No changes.
|
14
|
-
|
15
|
-
|
16
|
-
## Rails 6.1.7.1 (January 17, 2023) ##
|
17
|
-
|
18
|
-
* Make sanitize_as_sql_comment more strict
|
19
|
-
|
20
|
-
Though this method was likely never meant to take user input, it was
|
21
|
-
attempting sanitization. That sanitization could be bypassed with
|
22
|
-
carefully crafted input.
|
23
|
-
|
24
|
-
This commit makes the sanitization more robust by replacing any
|
25
|
-
occurrances of "/*" or "*/" with "/ *" or "* /". It also performs a
|
26
|
-
first pass to remove one surrounding comment to avoid compatibility
|
27
|
-
issues for users relying on the existing removal.
|
28
|
-
|
29
|
-
This also clarifies in the documentation of annotate that it should not
|
30
|
-
be provided user input.
|
31
|
-
|
32
|
-
[CVE-2023-22794]
|
33
|
-
|
34
|
-
* Added integer width check to PostgreSQL::Quoting
|
35
|
-
|
36
|
-
Given a value outside the range for a 64bit signed integer type
|
37
|
-
PostgreSQL will treat the column type as numeric. Comparing
|
38
|
-
integer values against numeric values can result in a slow
|
39
|
-
sequential scan.
|
40
|
-
|
41
|
-
This behavior is configurable via
|
42
|
-
ActiveRecord::Base.raise_int_wider_than_64bit which defaults to true.
|
43
|
-
|
44
|
-
[CVE-2022-44566]
|
45
|
-
|
46
|
-
## Rails 6.1.7 (September 09, 2022) ##
|
47
|
-
|
48
|
-
* Symbol is allowed by default for YAML columns
|
49
|
-
|
50
|
-
*Étienne Barrié*
|
51
|
-
|
52
|
-
* Fix `ActiveRecord::Store` to serialize as a regular Hash
|
53
|
-
|
54
|
-
Previously it would serialize as an `ActiveSupport::HashWithIndifferentAccess`
|
55
|
-
which is wasteful and cause problem with YAML safe_load.
|
56
|
-
|
57
|
-
*Jean Boussier*
|
58
|
-
|
59
|
-
* Fix PG.connect keyword arguments deprecation warning on ruby 2.7
|
60
|
-
|
61
|
-
Fixes #44307.
|
62
|
-
|
63
|
-
*Nikita Vasilevsky*
|
64
|
-
|
65
|
-
## Rails 6.1.6.1 (July 12, 2022) ##
|
66
|
-
|
67
|
-
* Change ActiveRecord::Coders::YAMLColumn default to safe_load
|
68
|
-
|
69
|
-
This adds two new configuration options The configuration options are as
|
70
|
-
follows:
|
71
|
-
|
72
|
-
* `config.active_storage.use_yaml_unsafe_load`
|
73
|
-
|
74
|
-
When set to true, this configuration option tells Rails to use the old
|
75
|
-
"unsafe" YAML loading strategy, maintaining the existing behavior but leaving
|
76
|
-
the possible escalation vulnerability in place. Setting this option to true
|
77
|
-
is *not* recommended, but can aid in upgrading.
|
78
|
-
|
79
|
-
* `config.active_record.yaml_column_permitted_classes`
|
80
|
-
|
81
|
-
The "safe YAML" loading method does not allow all classes to be deserialized
|
82
|
-
by default. This option allows you to specify classes deemed "safe" in your
|
83
|
-
application. For example, if your application uses Symbol and Time in
|
84
|
-
serialized data, you can add Symbol and Time to the allowed list as follows:
|
85
|
-
|
86
|
-
```
|
87
|
-
config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
|
88
|
-
```
|
89
|
-
|
90
|
-
[CVE-2022-32224]
|
91
|
-
|
92
|
-
|
93
|
-
## Rails 6.1.6 (May 09, 2022) ##
|
94
|
-
|
95
|
-
* No changes.
|
96
|
-
|
97
|
-
|
98
|
-
## Rails 6.1.5.1 (April 26, 2022) ##
|
99
|
-
|
100
|
-
* No changes.
|
101
|
-
|
102
|
-
|
103
|
-
## Rails 6.1.5 (March 09, 2022) ##
|
104
|
-
|
105
|
-
* Fix `ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate` for Ruby 2.6.
|
106
|
-
|
107
|
-
Ruby 2.6 and 2.7 have slightly different implementations of the `String#-@` method.
|
108
|
-
In Ruby 2.6, the receiver of the `String#-@` method is modified under certain circumstances.
|
109
|
-
This was later identified as a bug (https://bugs.ruby-lang.org/issues/15926) and only
|
110
|
-
fixed in Ruby 2.7.
|
111
|
-
|
112
|
-
Before the changes in this commit, the
|
113
|
-
`ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate` method, which internally
|
114
|
-
calls the `String#-@` method, could also modify an input string argument in Ruby 2.6 --
|
115
|
-
changing a tainted, unfrozen string into a tainted, frozen string.
|
116
|
-
|
117
|
-
Fixes #43056
|
118
|
-
|
119
|
-
*Eric O'Hanlon*
|
120
|
-
|
121
|
-
* Fix migration compatibility to create SQLite references/belongs_to column as integer when
|
122
|
-
migration version is 6.0.
|
123
|
-
|
124
|
-
`reference`/`belongs_to` in migrations with version 6.0 were creating columns as
|
125
|
-
bigint instead of integer for the SQLite Adapter.
|
126
|
-
|
127
|
-
*Marcelo Lauxen*
|
128
|
-
|
129
|
-
* Fix dbconsole for 3-tier config.
|
130
|
-
|
131
|
-
*Eileen M. Uchitelle*
|
1
|
+
## Rails 7.0.0 (December 15, 2021) ##
|
132
2
|
|
133
3
|
* Better handle SQL queries with invalid encoding.
|
134
4
|
|
@@ -144,1669 +14,1684 @@
|
|
144
14
|
|
145
15
|
*Jean Boussier*
|
146
16
|
|
147
|
-
*
|
148
|
-
|
149
|
-
*Kevin Sjöberg*
|
150
|
-
|
151
|
-
* Fix regression bug that caused ignoring additional conditions for preloading
|
152
|
-
`has_many` through relations.
|
153
|
-
|
154
|
-
Fixes #43132
|
155
|
-
|
156
|
-
*Alexander Pauly*
|
157
|
-
|
158
|
-
* Fix `ActiveRecord::InternalMetadata` to not be broken by
|
159
|
-
`config.active_record.record_timestamps = false`
|
160
|
-
|
161
|
-
Since the model always create the timestamp columns, it has to set them, otherwise it breaks
|
162
|
-
various DB management tasks.
|
163
|
-
|
164
|
-
Fixes #42983
|
165
|
-
|
166
|
-
*Jean Boussier*
|
167
|
-
|
168
|
-
* Fix duplicate active record objects on `inverse_of`.
|
169
|
-
|
170
|
-
*Justin Carvalho*
|
171
|
-
|
172
|
-
* Fix duplicate objects stored in has many association after save.
|
173
|
-
|
174
|
-
Fixes #42549.
|
175
|
-
|
176
|
-
*Alex Ghiculescu*
|
177
|
-
|
178
|
-
* Fix performance regression in `CollectionAssocation#build`.
|
179
|
-
|
180
|
-
*Alex Ghiculescu*
|
181
|
-
|
182
|
-
* Fix retrieving default value for text column for MariaDB.
|
183
|
-
|
184
|
-
*fatkodima*
|
17
|
+
* Move database and shard selection config options to a generator.
|
185
18
|
|
19
|
+
Rather than generating the config options in `production.rb` when applications are created, applications can now run a generator to create an initializer and uncomment / update options as needed. All multi-db configuration can be implemented in this initializer.
|
186
20
|
|
187
|
-
|
188
|
-
|
189
|
-
* No changes.
|
190
|
-
|
21
|
+
*Eileen M. Uchitelle*
|
191
22
|
|
192
|
-
## Rails
|
23
|
+
## Rails 7.0.0.rc3 (December 14, 2021) ##
|
193
24
|
|
194
25
|
* No changes.
|
195
26
|
|
196
27
|
|
197
|
-
## Rails
|
28
|
+
## Rails 7.0.0.rc2 (December 14, 2021) ##
|
198
29
|
|
199
30
|
* No changes.
|
200
31
|
|
32
|
+
## Rails 7.0.0.rc1 (December 06, 2021) ##
|
201
33
|
|
202
|
-
|
203
|
-
|
204
|
-
* No changes.
|
205
|
-
|
34
|
+
* Remove deprecated `ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name`.
|
206
35
|
|
207
|
-
|
36
|
+
*Rafael Mendonça França*
|
208
37
|
|
209
|
-
*
|
38
|
+
* Remove deprecated `ActiveRecord::Connection#in_clause_length`.
|
210
39
|
|
40
|
+
*Rafael Mendonça França*
|
211
41
|
|
212
|
-
|
42
|
+
* Remove deprecated `ActiveRecord::Connection#allowed_index_name_length`.
|
213
43
|
|
214
|
-
*
|
44
|
+
*Rafael Mendonça França*
|
215
45
|
|
46
|
+
* Remove deprecated `ActiveRecord::Base#remove_connection`.
|
216
47
|
|
217
|
-
|
48
|
+
*Rafael Mendonça França*
|
218
49
|
|
219
|
-
*
|
50
|
+
* Load STI Models in fixtures
|
220
51
|
|
52
|
+
Data from Fixtures now loads based on the specific class for models with
|
53
|
+
Single Table Inheritance. This affects enums defined in subclasses, previously
|
54
|
+
the value of these fields was not parsed and remained `nil`
|
221
55
|
|
222
|
-
|
56
|
+
*Andres Howard*
|
223
57
|
|
224
|
-
*
|
58
|
+
* `#authenticate` returns false when the password is blank instead of raising an error.
|
225
59
|
|
226
|
-
*
|
60
|
+
*Muhammad Muhammad Ibrahim*
|
227
61
|
|
228
|
-
*
|
62
|
+
* Fix `ActiveRecord::QueryMethods#in_order_of` behavior for integer enums.
|
229
63
|
|
230
|
-
|
64
|
+
`ActiveRecord::QueryMethods#in_order_of` didn't work as expected for enums stored as integers in the database when passing an array of strings or symbols as the order argument. This unexpected behavior occurred because the string or symbol values were not casted to match the integers in the database.
|
231
65
|
|
232
|
-
|
66
|
+
The following example now works as expected:
|
233
67
|
|
234
|
-
|
235
|
-
|
68
|
+
```ruby
|
69
|
+
class Book < ApplicationRecord
|
70
|
+
enum status: [:proposed, :written, :published]
|
71
|
+
end
|
236
72
|
|
237
|
-
|
73
|
+
Book.in_order_of(:status, %w[written published proposed])
|
74
|
+
```
|
238
75
|
|
239
|
-
*
|
76
|
+
*Alexandre Ruban*
|
240
77
|
|
241
|
-
|
78
|
+
* Ignore persisted in-memory records when merging target lists.
|
242
79
|
|
243
|
-
*
|
80
|
+
*Kevin Sjöberg*
|
244
81
|
|
245
|
-
|
82
|
+
* Add a new option `:update_only` to `upsert_all` to configure the list of columns to update in case of conflict.
|
246
83
|
|
247
|
-
|
84
|
+
Before, you could only customize the update SQL sentence via `:on_duplicate`. There is now a new option `:update_only` that lets you provide a list of columns to update in case of conflict:
|
248
85
|
|
249
|
-
|
86
|
+
```ruby
|
87
|
+
Commodity.upsert_all(
|
88
|
+
[
|
89
|
+
{ id: 2, name: "Copper", price: 4.84 },
|
90
|
+
{ id: 4, name: "Gold", price: 1380.87 },
|
91
|
+
{ id: 6, name: "Aluminium", price: 0.35 }
|
92
|
+
],
|
93
|
+
update_only: [:price] # Only prices will be updated
|
94
|
+
)
|
95
|
+
```
|
250
96
|
|
251
|
-
*
|
97
|
+
*Jorge Manrubia*
|
252
98
|
|
253
|
-
|
99
|
+
* Remove deprecated `ActiveRecord::Result#map!` and `ActiveRecord::Result#collect!`.
|
254
100
|
|
255
|
-
*
|
101
|
+
*Rafael Mendonça França*
|
256
102
|
|
257
|
-
|
103
|
+
* Remove deprecated `ActiveRecord::Base.configurations.to_h`.
|
258
104
|
|
259
|
-
*
|
260
|
-
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
105
|
+
*Rafael Mendonça França*
|
261
106
|
|
262
|
-
|
107
|
+
* Remove deprecated `ActiveRecord::Base.configurations.default_hash`.
|
263
108
|
|
264
|
-
*
|
109
|
+
*Rafael Mendonça França*
|
265
110
|
|
266
|
-
|
111
|
+
* Remove deprecated `ActiveRecord::Base.arel_attribute`.
|
267
112
|
|
268
|
-
*
|
113
|
+
*Rafael Mendonça França*
|
269
114
|
|
270
|
-
|
115
|
+
* Remove deprecated `ActiveRecord::Base.connection_config`.
|
271
116
|
|
272
|
-
*
|
117
|
+
*Rafael Mendonça França*
|
273
118
|
|
274
|
-
|
119
|
+
* Filter attributes in SQL logs
|
275
120
|
|
276
|
-
|
121
|
+
Previously, SQL queries in logs containing `ActiveRecord::Base.filter_attributes` were not filtered.
|
277
122
|
|
278
|
-
|
279
|
-
relation set `strict_loading` to false the false wasn't considered when
|
280
|
-
deciding whether to raise/warn about strict loading.
|
123
|
+
Now, the filter attributes will be masked `[FILTERED]` in the logs when `prepared_statement` is enabled.
|
281
124
|
|
282
125
|
```
|
283
|
-
|
284
|
-
|
126
|
+
# Before:
|
127
|
+
Foo Load (0.2ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "hello"], ["LIMIT", 1]]
|
285
128
|
|
286
|
-
|
287
|
-
|
129
|
+
# After:
|
130
|
+
Foo Load (0.5ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "[FILTERED]"], ["LIMIT", 1]]
|
288
131
|
```
|
289
132
|
|
290
|
-
|
291
|
-
`strict_loading` was set to false. This is a bug affecting more than
|
292
|
-
Active Storage which is why I made this PR superseding #41461. We need
|
293
|
-
to fix this for all applications since the behavior is a little
|
294
|
-
surprising. I took the test from #41461 and the code suggestion from #41453
|
295
|
-
with some additions.
|
296
|
-
|
297
|
-
*Eileen M. Uchitelle*, *Radamés Roriz*
|
133
|
+
*Aishwarya Subramanian*
|
298
134
|
|
299
|
-
*
|
135
|
+
* Remove deprecated `Tasks::DatabaseTasks.spec`.
|
300
136
|
|
301
|
-
*
|
137
|
+
*Rafael Mendonça França*
|
302
138
|
|
303
|
-
*
|
139
|
+
* Remove deprecated `Tasks::DatabaseTasks.current_config`.
|
304
140
|
|
305
|
-
*
|
141
|
+
*Rafael Mendonça França*
|
306
142
|
|
307
|
-
*
|
143
|
+
* Deprecate `Tasks::DatabaseTasks.schema_file_type`.
|
308
144
|
|
309
|
-
*
|
145
|
+
*Rafael Mendonça França*
|
310
146
|
|
311
|
-
*
|
147
|
+
* Remove deprecated `Tasks::DatabaseTasks.dump_filename`.
|
312
148
|
|
313
|
-
*
|
149
|
+
*Rafael Mendonça França*
|
314
150
|
|
315
|
-
*
|
151
|
+
* Remove deprecated `Tasks::DatabaseTasks.schema_file`.
|
316
152
|
|
317
|
-
*
|
153
|
+
*Rafael Mendonça França*
|
318
154
|
|
155
|
+
* Remove deprecated `environment` and `name` arguments from `Tasks::DatabaseTasks.schema_up_to_date?`.
|
319
156
|
|
320
|
-
|
157
|
+
*Rafael Mendonça França*
|
321
158
|
|
322
|
-
*
|
159
|
+
* Merging conditions on the same column no longer maintain both conditions,
|
160
|
+
and will be consistently replaced by the latter condition.
|
323
161
|
|
162
|
+
```ruby
|
163
|
+
# Rails 6.1 (IN clause is replaced by merger side equality condition)
|
164
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
165
|
+
# Rails 6.1 (both conflict conditions exists, deprecated)
|
166
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
|
167
|
+
# Rails 6.1 with rewhere to migrate to Rails 7.0's behavior
|
168
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
|
169
|
+
# Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
|
170
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
171
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
324
172
|
|
325
|
-
|
173
|
+
*Rafael Mendonça França*
|
326
174
|
|
327
|
-
*
|
175
|
+
* Remove deprecated support to `Model.reorder(nil).first` to search using non-deterministic order.
|
328
176
|
|
177
|
+
*Rafael Mendonça França*
|
329
178
|
|
330
|
-
|
179
|
+
* Remove deprecated rake tasks:
|
331
180
|
|
332
|
-
*
|
333
|
-
|
181
|
+
* `db:schema:load_if_ruby`
|
182
|
+
* `db:structure:dump`
|
183
|
+
* `db:structure:load`
|
184
|
+
* `db:structure:load_if_sql`
|
185
|
+
* `db:structure:dump:#{name}`
|
186
|
+
* `db:structure:load:#{name}`
|
187
|
+
* `db:test:load_structure`
|
188
|
+
* `db:test:load_structure:#{name}`
|
334
189
|
|
335
190
|
*Rafael Mendonça França*
|
336
191
|
|
337
|
-
*
|
338
|
-
are enabled.
|
192
|
+
* Remove deprecated `DatabaseConfig#config` method.
|
339
193
|
|
340
194
|
*Rafael Mendonça França*
|
341
195
|
|
342
|
-
*
|
343
|
-
an `IN` clause.
|
196
|
+
* Rollback transactions when the block returns earlier than expected.
|
344
197
|
|
345
|
-
|
198
|
+
Before this change, when a transaction block returned early, the transaction would be committed.
|
346
199
|
|
347
|
-
|
348
|
-
|
200
|
+
The problem is that timeouts triggered inside the transaction block was also making the incomplete transaction
|
201
|
+
to be committed, so in order to avoid this mistake, the transaction block is rolled back.
|
349
202
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
call #exists? on the relation instead, which effectively alters
|
354
|
-
the select values of the query (and thus removes the aliased select
|
355
|
-
values), but leaves the having clause intact. Because the having
|
356
|
-
clause is then referencing an aliased column that is no longer
|
357
|
-
present in the simplified query, an ActiveRecord::InvalidStatement
|
358
|
-
error was raised.
|
203
|
+
*Rafael Mendonça França*
|
204
|
+
|
205
|
+
* Add middleware for automatic shard swapping.
|
359
206
|
|
360
|
-
|
207
|
+
Provides a basic middleware to perform automatic shard swapping. Applications will provide a resolver which will determine for an individual request which shard should be used. Example:
|
361
208
|
|
362
209
|
```ruby
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
210
|
+
config.active_record.shard_resolver = ->(request) {
|
211
|
+
subdomain = request.subdomain
|
212
|
+
tenant = Tenant.find_by_subdomain!(subdomain)
|
213
|
+
tenant.shard
|
214
|
+
}
|
368
215
|
```
|
369
216
|
|
370
|
-
|
371
|
-
simplified #exists? query, which simply checks for the presence of
|
372
|
-
a having clause.
|
373
|
-
|
374
|
-
Fixes #41417
|
217
|
+
See guides for more details.
|
375
218
|
|
376
|
-
*
|
377
|
-
|
378
|
-
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
379
|
-
without Rails knowledge (e.g., if app gets kill -9d during long-running query or due to Rack::Timeout), app won't end
|
380
|
-
up in perpetual crash state for being inconsistent with Postgres.
|
381
|
-
|
382
|
-
*wbharding*, *Martin Tepper*
|
383
|
-
|
384
|
-
|
385
|
-
## Rails 6.1.2.1 (February 10, 2021) ##
|
219
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
386
220
|
|
387
|
-
*
|
221
|
+
* Remove deprecated support to pass a column to `type_cast`.
|
388
222
|
|
389
|
-
|
390
|
-
for validating the money format in the PostgreSQL adapter. This patch
|
391
|
-
fixes the regexp.
|
223
|
+
*Rafael Mendonça França*
|
392
224
|
|
393
|
-
|
225
|
+
* Remove deprecated support to type cast to database values `ActiveRecord::Base` objects.
|
394
226
|
|
395
|
-
|
227
|
+
*Rafael Mendonça França*
|
396
228
|
|
397
|
-
|
229
|
+
* Remove deprecated support to quote `ActiveRecord::Base` objects.
|
398
230
|
|
231
|
+
*Rafael Mendonça França*
|
399
232
|
|
400
|
-
|
233
|
+
* Remove deprecacated support to resolve connection using `"primary"` as connection specification name.
|
401
234
|
|
402
|
-
*
|
235
|
+
*Rafael Mendonça França*
|
403
236
|
|
404
|
-
|
237
|
+
* Remove deprecation warning when using `:interval` column is used in PostgreSQL database.
|
405
238
|
|
406
|
-
|
239
|
+
Now, interval columns will return `ActiveSupport::Duration` objects instead of strings.
|
407
240
|
|
408
|
-
|
409
|
-
case the job would enqueue even though the database deletion
|
410
|
-
rolledback putting things in a funky state.
|
241
|
+
To keep the old behavior, you can add this line to your model:
|
411
242
|
|
412
|
-
|
243
|
+
```ruby
|
244
|
+
attribute :column, :string
|
245
|
+
```
|
413
246
|
|
414
|
-
*
|
247
|
+
*Rafael Mendonça França*
|
415
248
|
|
416
|
-
*
|
249
|
+
* Remove deprecated support to YAML load `ActiveRecord::Base` instance in the Rails 4.2 and 4.1 formats.
|
417
250
|
|
418
|
-
*
|
251
|
+
*Rafael Mendonça França*
|
419
252
|
|
420
|
-
*
|
421
|
-
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
422
|
-
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
423
|
-
are assumed to be adapter specification urls.
|
253
|
+
* Remove deprecated option `:spec_name` in the `configs_for` method.
|
424
254
|
|
425
|
-
|
255
|
+
*Rafael Mendonça França*
|
426
256
|
|
427
|
-
|
257
|
+
* Remove deprecated `ActiveRecord::Base.allow_unsafe_raw_sql`.
|
428
258
|
|
429
|
-
*
|
259
|
+
*Rafael Mendonça França*
|
430
260
|
|
431
|
-
|
261
|
+
* Fix regression bug that caused ignoring additional conditions for preloading has_many-through relations.
|
432
262
|
|
433
|
-
|
263
|
+
Fixes #43132
|
434
264
|
|
435
|
-
*
|
265
|
+
*Alexander Pauly*
|
436
266
|
|
437
|
-
*
|
267
|
+
* Fix `has_many` inversing recursion on models with recursive associations.
|
438
268
|
|
439
|
-
*
|
269
|
+
*Gannon McGibbon*
|
440
270
|
|
441
|
-
*
|
271
|
+
* Add `accepts_nested_attributes_for` support for `delegated_type`
|
442
272
|
|
443
|
-
|
273
|
+
```ruby
|
274
|
+
class Entry < ApplicationRecord
|
275
|
+
delegated_type :entryable, types: %w[ Message Comment ]
|
276
|
+
accepts_nested_attributes_for :entryable
|
277
|
+
end
|
444
278
|
|
445
|
-
|
279
|
+
entry = Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
|
280
|
+
# => #<Entry:0x00>
|
281
|
+
# id: 1
|
282
|
+
# entryable_id: 1,
|
283
|
+
# entryable_type: 'Message'
|
284
|
+
# ...>
|
285
|
+
|
286
|
+
entry.entryable
|
287
|
+
# => #<Message:0x01>
|
288
|
+
# id: 1
|
289
|
+
# content: 'Hello world'
|
290
|
+
# ...>
|
291
|
+
```
|
446
292
|
|
447
|
-
|
293
|
+
Previously it would raise an error:
|
448
294
|
|
295
|
+
```ruby
|
296
|
+
Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
|
297
|
+
# ArgumentError: Cannot build association `entryable'. Are you trying to build a polymorphic one-to-one association?
|
298
|
+
```
|
449
299
|
|
450
|
-
|
300
|
+
*Sjors Baltus*
|
451
301
|
|
452
|
-
*
|
302
|
+
* Use subquery for DELETE with GROUP_BY and HAVING clauses.
|
453
303
|
|
454
|
-
|
304
|
+
Prior to this change, deletes with GROUP_BY and HAVING were returning an error.
|
455
305
|
|
456
|
-
|
306
|
+
After this change, GROUP_BY and HAVING are valid clauses in DELETE queries, generating the following query:
|
457
307
|
|
458
|
-
|
308
|
+
```sql
|
309
|
+
DELETE FROM "posts" WHERE "posts"."id" IN (
|
310
|
+
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."id" HAVING (count(comments.id) >= 2))
|
311
|
+
) [["flagged", "t"]]
|
312
|
+
```
|
459
313
|
|
460
|
-
*
|
314
|
+
*Ignacio Chiazzo Cardarello*
|
461
315
|
|
462
|
-
|
316
|
+
* Use subquery for UPDATE with GROUP_BY and HAVING clauses.
|
463
317
|
|
464
|
-
|
318
|
+
Prior to this change, updates with GROUP_BY and HAVING were being ignored, generating a SQL like this:
|
465
319
|
|
466
|
-
|
320
|
+
```sql
|
321
|
+
UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
|
322
|
+
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
323
|
+
) [["flagged", "t"]]
|
324
|
+
```
|
467
325
|
|
468
|
-
|
326
|
+
After this change, GROUP_BY and HAVING clauses are used as a subquery in updates, like this:
|
469
327
|
|
470
|
-
|
328
|
+
```sql
|
329
|
+
UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
|
330
|
+
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
331
|
+
GROUP BY posts.id HAVING (count(comments.id) >= 2)
|
332
|
+
) [["flagged", "t"]]
|
333
|
+
```
|
471
334
|
|
472
|
-
*
|
335
|
+
*Ignacio Chiazzo Cardarello*
|
473
336
|
|
474
|
-
|
337
|
+
* Add support for setting the filename of the schema or structure dump in the database config.
|
475
338
|
|
476
|
-
|
339
|
+
Applications may now set their the filename or path of the schema / structure dump file in their database configuration.
|
477
340
|
|
478
|
-
|
341
|
+
```yaml
|
342
|
+
production:
|
343
|
+
primary:
|
344
|
+
database: my_db
|
345
|
+
schema_dump: my_schema_dump_filename.rb
|
346
|
+
animals:
|
347
|
+
database: animals_db
|
348
|
+
schema_dump: false
|
349
|
+
```
|
479
350
|
|
480
|
-
|
351
|
+
The filename set in `schema_dump` will be used by the application. If set to `false` the schema will not be dumped. The database tasks are responsible for adding the database directory to the filename. If a full path is provided, the Rails tasks will use that instead of `ActiveRecord::DatabaseTasks.db_dir`.
|
481
352
|
|
482
|
-
*
|
353
|
+
*Eileen M. Uchitelle*, *Ryan Kerr*
|
483
354
|
|
484
|
-
*
|
355
|
+
* Add `ActiveRecord::Base.prohibit_shard_swapping` to prevent attempts to change the shard within a block.
|
485
356
|
|
486
|
-
*
|
357
|
+
*John Crepezzi*, *Eileen M. Uchitelle*
|
487
358
|
|
488
|
-
*
|
359
|
+
* Filter unchanged attributes with default function from insert query when `partial_inserts` is disabled.
|
489
360
|
|
490
|
-
|
491
|
-
to throw an error saying :polymorphic would not be a valid option.
|
361
|
+
*Akshay Birajdar*, *Jacopo Beschi*
|
492
362
|
|
493
|
-
|
363
|
+
* Add support for FILTER clause (SQL:2003) to Arel.
|
494
364
|
|
495
|
-
|
365
|
+
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.
|
496
366
|
|
497
|
-
|
367
|
+
*Andrey Novikov*
|
498
368
|
|
499
|
-
|
500
|
-
and the index name should be specified explicitly. Now, the index name is inferred
|
501
|
-
automatically.
|
369
|
+
* Automatically set timestamps on record creation during bulk insert/upsert
|
502
370
|
|
503
|
-
|
504
|
-
add_index(:items, "to_tsvector('english', description)")
|
505
|
-
```
|
371
|
+
Prior to this change, only updates during an upsert operation (e.g. `upsert_all`) would touch timestamps (`updated_{at,on}`). Now, record creations also touch timestamp columns (`{created,updated}_{at,on}`).
|
506
372
|
|
507
|
-
|
373
|
+
This behaviour is controlled by the `<model>.record_timestamps` config, matching the behaviour of `create`, `update`, etc. It can also be overridden by using the `record_timestamps:` keyword argument.
|
508
374
|
|
375
|
+
Note that this means `upsert_all` on models with `record_timestamps = false` will no longer touch `updated_{at,on}` automatically.
|
509
376
|
|
510
|
-
|
377
|
+
*Sam Bostock*
|
511
378
|
|
512
|
-
*
|
379
|
+
* Don't require `role` when passing `shard` to `connected_to`.
|
513
380
|
|
514
|
-
|
381
|
+
`connected_to` can now be called with a `shard` only. Note that `role` is still inherited if `connected_to` calls are nested.
|
515
382
|
|
516
|
-
*
|
383
|
+
*Eileen M. Uchitelle*
|
517
384
|
|
518
|
-
*
|
385
|
+
* Add option to lazily load the schema cache on the connection.
|
519
386
|
|
520
|
-
|
387
|
+
Previously, the only way to load the schema cache in Active Record was through the Railtie on boot. This option provides the ability to load the schema cache on the connection after it's been established. Loading the cache lazily on the connection can be beneficial for Rails applications that use multiple databases because it will load the cache at the time the connection is established. Currently Railties doesn't have access to the connections before boot.
|
521
388
|
|
522
|
-
|
389
|
+
To use the cache, set `config.active_record.lazily_load_schema_cache = true` in your application configuration. In addition a `schema_cache_path` should be set in your database configuration if you don't want to use the default "db/schema_cache.yml" path.
|
523
390
|
|
524
|
-
|
391
|
+
*Eileen M. Uchitelle*
|
525
392
|
|
526
|
-
|
393
|
+
* Allow automatic `inverse_of` detection for associations with scopes.
|
527
394
|
|
528
|
-
|
395
|
+
Automatic `inverse_of` detection now works for associations with scopes. For
|
396
|
+
example, the `comments` association here now automatically detects
|
397
|
+
`inverse_of: :post`, so we don't need to pass that option:
|
529
398
|
|
530
399
|
```ruby
|
531
|
-
class
|
532
|
-
|
533
|
-
|
534
|
-
def initialize(author)
|
535
|
-
@author = author
|
536
|
-
end
|
400
|
+
class Post < ActiveRecord::Base
|
401
|
+
has_many :comments, -> { visible }
|
537
402
|
end
|
538
403
|
|
539
|
-
|
404
|
+
class Comment < ActiveRecord::Base
|
405
|
+
belongs_to :post
|
406
|
+
end
|
540
407
|
```
|
541
408
|
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
This API allows applications to connect to multiple databases at once without switching all of them or implementing a deeply nested stack.
|
547
|
-
|
548
|
-
Before:
|
549
|
-
|
550
|
-
AnimalsRecord.connected_to(role: :reading) do
|
551
|
-
MealsRecord.connected_to(role: :reading) do
|
552
|
-
Dog.first # read from animals replica
|
553
|
-
Dinner.first # read from meals replica
|
554
|
-
Person.first # read from primary writer
|
555
|
-
end
|
556
|
-
end
|
557
|
-
|
558
|
-
After:
|
559
|
-
|
560
|
-
ActiveRecord::Base.connected_to_many([AnimalsRecord, MealsRecord], role: :reading) do
|
561
|
-
Dog.first # read from animals replica
|
562
|
-
Dinner.first # read from meals replica
|
563
|
-
Person.first # read from primary writer
|
564
|
-
end
|
565
|
-
|
566
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
567
|
-
|
568
|
-
* Add option to raise or log for `ActiveRecord::StrictLoadingViolationError`.
|
569
|
-
|
570
|
-
Some applications may not want to raise an error in production if using `strict_loading`. This would allow an application to set strict loading to log for the production environment while still raising in development and test environments.
|
571
|
-
|
572
|
-
Set `config.active_record.action_on_strict_loading_violation` to `:log` errors instead of raising.
|
573
|
-
|
574
|
-
*Eileen M. Uchitelle*
|
575
|
-
|
576
|
-
* Allow the inverse of a `has_one` association that was previously autosaved to be loaded.
|
577
|
-
|
578
|
-
Fixes #34255.
|
579
|
-
|
580
|
-
*Steven Weber*
|
581
|
-
|
582
|
-
* Optimise the length of index names for polymorphic references by using the reference name rather than the type and id column names.
|
583
|
-
|
584
|
-
Because the default behaviour when adding an index with multiple columns is to use all column names in the index name, this could frequently lead to overly long index names for polymorphic references which would fail the migration if it exceeded the database limit.
|
585
|
-
|
586
|
-
This change reduces the chance of that happening by using the reference name, e.g. `index_my_table_on_my_reference`.
|
409
|
+
Note that the automatic detection still won't work if the inverse
|
410
|
+
association has a scope. In this example a scope on the `post` association
|
411
|
+
would still prevent Rails from finding the inverse for the `comments`
|
412
|
+
association.
|
587
413
|
|
588
|
-
|
414
|
+
This will be the default for new apps in Rails 7. To opt in:
|
589
415
|
|
590
|
-
|
416
|
+
```ruby
|
417
|
+
config.active_record.automatic_scope_inversing = true
|
418
|
+
```
|
591
419
|
|
592
|
-
*
|
593
|
-
no longer enforce case sensitive comparison by default.
|
420
|
+
*Daniel Colson*, *Chris Bloom*
|
594
421
|
|
595
|
-
|
422
|
+
* Accept optional transaction args to `ActiveRecord::Locking::Pessimistic#with_lock`
|
596
423
|
|
597
|
-
|
424
|
+
`#with_lock` now accepts transaction options like `requires_new:`,
|
425
|
+
`isolation:`, and `joinable:`
|
598
426
|
|
599
|
-
|
600
|
-
`table_name_length`
|
601
|
-
`columns_per_table`
|
602
|
-
`indexes_per_table`
|
603
|
-
`columns_per_multicolumn_index`
|
604
|
-
`sql_query_length`
|
605
|
-
`joins_per_query`
|
427
|
+
*John Mileham*
|
606
428
|
|
607
|
-
|
429
|
+
* Adds support for deferrable foreign key constraints in PostgreSQL.
|
608
430
|
|
609
|
-
|
431
|
+
By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases,
|
432
|
+
but becomes a major limitation when creating related records before the parent record is inserted into the database.
|
433
|
+
One example of this is looking up / creating a person via one or more unique alias.
|
610
434
|
|
611
|
-
|
612
|
-
|
613
|
-
|
435
|
+
```ruby
|
436
|
+
Person.transaction do
|
437
|
+
alias = Alias
|
438
|
+
.create_with(user_id: SecureRandom.uuid)
|
439
|
+
.create_or_find_by(name: "DHH")
|
440
|
+
|
441
|
+
person = Person
|
442
|
+
.create_with(name: "David Heinemeier Hansson")
|
443
|
+
.create_or_find_by(id: alias.user_id)
|
444
|
+
end
|
445
|
+
```
|
614
446
|
|
615
|
-
|
447
|
+
Using the default behavior, the transaction would fail when executing the first `INSERT` statement.
|
616
448
|
|
617
|
-
|
449
|
+
By passing the `:deferrable` option to the `add_foreign_key` statement in migrations, it's possible to defer this
|
450
|
+
check.
|
618
451
|
|
619
|
-
|
452
|
+
```ruby
|
453
|
+
add_foreign_key :aliases, :person, deferrable: true
|
454
|
+
```
|
620
455
|
|
621
|
-
|
456
|
+
Passing `deferrable: true` doesn't change the default behavior, but allows manually deferring the check using
|
457
|
+
`SET CONSTRAINTS ALL DEFERRED` within a transaction. This will cause the foreign keys to be checked after the
|
458
|
+
transaction.
|
622
459
|
|
623
|
-
|
460
|
+
It's also possible to adjust the default behavior from an immediate check (after the statement), to a deferred check
|
461
|
+
(after the transaction):
|
624
462
|
|
625
|
-
|
463
|
+
```ruby
|
464
|
+
add_foreign_key :aliases, :person, deferrable: :deferred
|
465
|
+
```
|
626
466
|
|
627
|
-
*
|
467
|
+
*Benedikt Deicke*
|
628
468
|
|
629
|
-
*
|
469
|
+
* Allow configuring Postgres password through the socket URL.
|
630
470
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
471
|
+
For example:
|
472
|
+
```ruby
|
473
|
+
ActiveRecord::DatabaseConfigurations::UrlConfig.new(
|
474
|
+
:production, :production, 'postgres:///?user=user&password=secret&dbname=app', {}
|
475
|
+
).configuration_hash
|
476
|
+
```
|
635
477
|
|
636
|
-
|
478
|
+
will now return,
|
637
479
|
|
638
|
-
|
639
|
-
|
640
|
-
|
480
|
+
```ruby
|
481
|
+
{ :user=>"user", :password=>"secret", :dbname=>"app", :adapter=>"postgresql" }
|
482
|
+
```
|
641
483
|
|
642
|
-
|
484
|
+
*Abeid Ahmed*
|
643
485
|
|
644
|
-
|
645
|
-
User.find_by(name: "David") # => #<User name: "David", ...>
|
646
|
-
end
|
486
|
+
* PostgreSQL: support custom enum types
|
647
487
|
|
648
|
-
|
488
|
+
In migrations, use `create_enum` to add a new enum type, and `t.enum` to add a column.
|
649
489
|
|
650
|
-
|
490
|
+
```ruby
|
491
|
+
def up
|
492
|
+
create_enum :mood, ["happy", "sad"]
|
651
493
|
|
652
|
-
|
653
|
-
|
654
|
-
|
494
|
+
change_table :cats do |t|
|
495
|
+
t.enum :current_mood, enum_type: "mood", default: "happy", null: false
|
496
|
+
end
|
497
|
+
end
|
498
|
+
```
|
655
499
|
|
656
|
-
|
500
|
+
Enums will be presented correctly in `schema.rb`. Note that this is only supported by
|
501
|
+
the PostgreSQL adapter.
|
657
502
|
|
658
|
-
|
659
|
-
# SELECT * FROM users WHERE name = 'John' AND name = 'David'
|
503
|
+
*Alex Ghiculescu*
|
660
504
|
|
661
|
-
|
505
|
+
* Avoid COMMENT statements in PostgreSQL structure dumps
|
662
506
|
|
663
|
-
|
664
|
-
|
507
|
+
COMMENT statements are now omitted from the output of `db:structure:dump` when using PostgreSQL >= 11.
|
508
|
+
This allows loading the dump without a pgsql superuser account.
|
665
509
|
|
666
|
-
|
510
|
+
Fixes #36816, #43107.
|
667
511
|
|
668
|
-
*
|
512
|
+
*Janosch Müller*
|
669
513
|
|
670
|
-
|
671
|
-
`each`
|
672
|
-
`first`
|
673
|
-
`values`
|
674
|
-
`[]=`
|
514
|
+
* Add support for generated columns in PostgreSQL adapter
|
675
515
|
|
676
|
-
|
516
|
+
Generated columns are supported since version 12.0 of PostgreSQL. This adds
|
517
|
+
support of those to the PostgreSQL adapter.
|
677
518
|
|
678
|
-
|
519
|
+
```ruby
|
520
|
+
create_table :users do |t|
|
521
|
+
t.string :name
|
522
|
+
t.virtual :name_upcased, type: :string, as: 'upper(name)', stored: true
|
523
|
+
end
|
524
|
+
```
|
679
525
|
|
680
|
-
|
526
|
+
*Michał Begejowicz*
|
681
527
|
|
682
|
-
User.where.not(name: "Jon", role: "admin")
|
683
|
-
# SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
|
684
528
|
|
685
|
-
|
529
|
+
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
686
530
|
|
687
|
-
|
688
|
-
# SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
|
531
|
+
* No changes.
|
689
532
|
|
690
|
-
*Rafael Mendonça França*
|
691
533
|
|
692
|
-
|
534
|
+
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
693
535
|
|
694
|
-
|
536
|
+
* Remove warning when overwriting existing scopes
|
695
537
|
|
696
|
-
|
538
|
+
Removes the following unnecessary warning message that appeared when overwriting existing scopes
|
697
539
|
|
698
|
-
|
540
|
+
```
|
541
|
+
Creating scope :my_scope_name. Overwriting existing method "MyClass.my_scope_name" when overwriting existing scopes
|
542
|
+
```
|
699
543
|
|
700
|
-
*
|
544
|
+
*Weston Ganger*
|
701
545
|
|
702
|
-
|
546
|
+
* Use full precision for `updated_at` in `insert_all`/`upsert_all`
|
703
547
|
|
704
|
-
|
705
|
-
|
548
|
+
`CURRENT_TIMESTAMP` provides differing precision depending on the database,
|
549
|
+
and not all databases support explicitly specifying additional precision.
|
706
550
|
|
707
|
-
|
551
|
+
Instead, we delegate to the new `connection.high_precision_current_timestamp`
|
552
|
+
for the SQL to produce a high precision timestamp on the current database.
|
708
553
|
|
709
|
-
|
554
|
+
Fixes #42992
|
710
555
|
|
711
|
-
|
556
|
+
*Sam Bostock*
|
712
557
|
|
713
|
-
|
558
|
+
* Add ssl support for postgresql database tasks
|
714
559
|
|
715
|
-
|
560
|
+
Add `PGSSLMODE`, `PGSSLCERT`, `PGSSLKEY` and `PGSSLROOTCERT` to pg_env from database config
|
561
|
+
when running postgresql database tasks.
|
716
562
|
|
717
|
-
```
|
718
|
-
|
719
|
-
User.first # reads from default replica
|
720
|
-
Dog.first # reads from default replica
|
563
|
+
```yaml
|
564
|
+
# config/database.yml
|
721
565
|
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
566
|
+
production:
|
567
|
+
sslmode: verify-full
|
568
|
+
sslcert: client.crt
|
569
|
+
sslkey: client.key
|
570
|
+
sslrootcert: ca.crt
|
571
|
+
```
|
726
572
|
|
727
|
-
|
728
|
-
Dog.first # reads from default replica
|
573
|
+
Environment variables
|
729
574
|
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
575
|
+
```
|
576
|
+
PGSSLMODE=verify-full
|
577
|
+
PGSSLCERT=client.crt
|
578
|
+
PGSSLKEY=client.key
|
579
|
+
PGSSLROOTCERT=ca.crt
|
735
580
|
```
|
736
581
|
|
737
|
-
|
582
|
+
Fixes #42994
|
738
583
|
|
739
|
-
*
|
584
|
+
*Michael Bayucot*
|
740
585
|
|
741
|
-
|
586
|
+
* Avoid scoping update callbacks in `ActiveRecord::Relation#update!`.
|
742
587
|
|
743
|
-
|
588
|
+
Making it consistent with how scoping is applied only to the query in `ActiveRecord::Relation#update`
|
589
|
+
and not also to the callbacks from the update itself.
|
744
590
|
|
745
|
-
|
591
|
+
*Dylan Thacker-Smith*
|
746
592
|
|
747
|
-
|
748
|
-
|
749
|
-
topic.values_at(:title, :author_name)
|
750
|
-
# => ["Budget", "Jason"]
|
751
|
-
```
|
593
|
+
* Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
|
594
|
+
using `String#constantize` instead of the model's `polymorphic_class_for`.
|
752
595
|
|
753
|
-
|
596
|
+
When updating a polymorphic association, the old `foreign_type` was not inferred correctly when:
|
597
|
+
1. `touch`ing the previously associated record
|
598
|
+
2. updating the previously associated record's `counter_cache`
|
754
599
|
|
755
|
-
*
|
600
|
+
*Jimmy Bourassa*
|
756
601
|
|
757
|
-
*
|
602
|
+
* Add config option for ignoring tables when dumping the schema cache.
|
758
603
|
|
759
|
-
|
604
|
+
Applications can now be configured to ignore certain tables when dumping the schema cache.
|
760
605
|
|
761
|
-
|
606
|
+
The configuration option can table an array of tables:
|
762
607
|
|
763
608
|
```ruby
|
764
|
-
|
765
|
-
validates_uniqueness_of :title, conditions: ->(article) {
|
766
|
-
published_at = article.published_at
|
767
|
-
where(published_at: published_at.beginning_of_year..published_at.end_of_year)
|
768
|
-
}
|
769
|
-
end
|
609
|
+
config.active_record.schema_cache_ignored_tables = ["ignored_table", "another_ignored_table"]
|
770
610
|
```
|
771
611
|
|
772
|
-
|
773
|
-
|
774
|
-
* `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
|
775
|
-
total number of rows affected, just like their non-batched counterparts.
|
612
|
+
Or a regex:
|
776
613
|
|
777
614
|
```ruby
|
778
|
-
|
779
|
-
Person.in_batches.delete_all # => 42
|
615
|
+
config.active_record.schema_cache_ignored_tables = [/^_/]
|
780
616
|
```
|
781
617
|
|
782
|
-
|
783
|
-
|
784
|
-
*Eugene Kenny*
|
618
|
+
*Eileen M. Uchitelle*
|
785
619
|
|
786
|
-
*
|
787
|
-
`ActiveSupport::Duration` when loading records from database and
|
788
|
-
serialization to ISO 8601 formatted duration string on save.
|
789
|
-
Add support to define a column in migrations and get it in a schema dump.
|
790
|
-
Optional column precision is supported.
|
620
|
+
* Make schema cache methods return consistent results.
|
791
621
|
|
792
|
-
|
622
|
+
Previously the schema cache methods `primary_keys`, `columns`, `columns_hash`, and `indexes`
|
623
|
+
would behave differently than one another when a table didn't exist and differently across
|
624
|
+
database adapters. This change unifies the behavior so each method behaves the same regardless
|
625
|
+
of adapter.
|
793
626
|
|
794
|
-
|
627
|
+
The behavior now is:
|
795
628
|
|
796
|
-
|
629
|
+
`columns`: (unchanged) raises a db error if the table does not exist.
|
630
|
+
`columns_hash`: (unchanged) raises a db error if the table does not exist.
|
631
|
+
`primary_keys`: (unchanged) returns `nil` if the table does not exist.
|
632
|
+
`indexes`: (changed for mysql2) returns `[]` if the table does not exist.
|
797
633
|
|
798
|
-
|
634
|
+
*Eileen M. Uchitelle*
|
799
635
|
|
800
|
-
|
636
|
+
* Reestablish connection to previous database after after running `db:schema:load:name`
|
801
637
|
|
802
|
-
|
803
|
-
t.string :name
|
804
|
-
t.interval :duration
|
805
|
-
end
|
638
|
+
After running `db:schema:load:name` the previous connection is restored.
|
806
639
|
|
807
|
-
|
808
|
-
attribute :duration, :interval
|
809
|
-
end
|
640
|
+
*Jacopo Beschi*
|
810
641
|
|
811
|
-
|
812
|
-
Event.last.duration # => 2 days
|
813
|
-
Event.last.duration.iso8601 # => "P2D"
|
814
|
-
Event.new(duration: 'P1DT12H3S').duration # => 1 day, 12 hours, and 3 seconds
|
815
|
-
Event.new(duration: '1 day') # Unknown value will be ignored and NULL will be written to database
|
642
|
+
* Add database config option `database_tasks`
|
816
643
|
|
817
|
-
|
644
|
+
If you would like to connect to an external database without any database
|
645
|
+
management tasks such as schema management, migrations, seeds, etc. you can set
|
646
|
+
the per database config option `database_tasks: false`
|
818
647
|
|
819
|
-
|
648
|
+
```yaml
|
649
|
+
# config/database.yml
|
820
650
|
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
651
|
+
production:
|
652
|
+
primary:
|
653
|
+
database: my_database
|
654
|
+
adapter: mysql2
|
655
|
+
animals:
|
656
|
+
database: my_animals_database
|
657
|
+
adapter: mysql2
|
658
|
+
database_tasks: false
|
825
659
|
```
|
826
660
|
|
827
|
-
|
828
|
-
|
829
|
-
*DHH*, *George Claghorn*, *Cory Gwin*, *Rafael Mendonça França*, *Adrianna Chang*
|
830
|
-
|
831
|
-
* Add `SKIP_TEST_DATABASE` environment variable to disable modifying the test database when `rails db:create` and `rails db:drop` are called.
|
832
|
-
|
833
|
-
*Jason Schweier*
|
834
|
-
|
835
|
-
* `connects_to` can only be called on `ActiveRecord::Base` or abstract classes.
|
836
|
-
|
837
|
-
Ensure that `connects_to` can only be called from `ActiveRecord::Base` or abstract classes. This protects the application from opening duplicate or too many connections.
|
838
|
-
|
839
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
840
|
-
|
841
|
-
* All connection adapters `execute` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
842
|
-
`ActiveRecord::StatementInvalid` when they encounter a connection error.
|
843
|
-
|
844
|
-
*Jean Boussier*
|
845
|
-
|
846
|
-
* `Mysql2Adapter#quote_string` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
847
|
-
`ActiveRecord::StatementInvalid` when it can't connect to the MySQL server.
|
848
|
-
|
849
|
-
*Jean Boussier*
|
661
|
+
*Weston Ganger*
|
850
662
|
|
851
|
-
*
|
663
|
+
* Fix `ActiveRecord::InternalMetadata` to not be broken by `config.active_record.record_timestamps = false`
|
852
664
|
|
853
|
-
|
665
|
+
Since the model always create the timestamp columns, it has to set them, otherwise it breaks
|
666
|
+
various DB management tasks.
|
854
667
|
|
855
|
-
|
668
|
+
Fixes #42983
|
856
669
|
|
857
|
-
|
670
|
+
* Add `ActiveRecord::QueryLogs`.
|
858
671
|
|
859
|
-
|
860
|
-
|
861
|
-
* Allow `where` references association names as joined table name aliases.
|
672
|
+
Configurable tags can be automatically added to all SQL queries generated by Active Record.
|
862
673
|
|
863
674
|
```ruby
|
864
|
-
|
865
|
-
|
866
|
-
|
675
|
+
# config/application.rb
|
676
|
+
module MyApp
|
677
|
+
class Application < Rails::Application
|
678
|
+
config.active_record.query_log_tags_enabled = true
|
679
|
+
end
|
867
680
|
end
|
868
|
-
|
869
|
-
# ... FROM comments LEFT OUTER JOIN comments children ON ... WHERE children.label = 1
|
870
|
-
Comment.includes(:children).where("children.label": "child")
|
871
681
|
```
|
872
682
|
|
873
|
-
|
874
|
-
|
875
|
-
* Support storing demodulized class name for polymorphic type.
|
876
|
-
|
877
|
-
Before Rails 6.1, storing demodulized class name is supported only for STI type
|
878
|
-
by `store_full_sti_class` class attribute.
|
879
|
-
|
880
|
-
Now `store_full_class_name` class attribute can handle both STI and polymorphic types.
|
881
|
-
|
882
|
-
*Ryuta Kamizono*
|
883
|
-
|
884
|
-
* Deprecate `rails db:structure:{load, dump}` tasks and extend
|
885
|
-
`rails db:schema:{load, dump}` tasks to work with either `:ruby` or `:sql` format,
|
886
|
-
depending on `config.active_record.schema_format` configuration value.
|
887
|
-
|
888
|
-
*fatkodima*
|
889
|
-
|
890
|
-
* Respect the `select` values for eager loading.
|
683
|
+
By default the application, controller and action details are added to the query tags:
|
891
684
|
|
892
685
|
```ruby
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
899
|
-
post.title # => "Welcome to the weblog"
|
900
|
-
post.body # => "Such a lovely day"
|
901
|
-
|
902
|
-
# Rails 6.1 (respect the `select` values)
|
903
|
-
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
904
|
-
post.title # => "WELCOME TO THE WEBLOG"
|
905
|
-
post.body # => ActiveModel::MissingAttributeError
|
686
|
+
class BooksController < ApplicationController
|
687
|
+
def index
|
688
|
+
@books = Book.all
|
689
|
+
end
|
690
|
+
end
|
906
691
|
```
|
907
692
|
|
908
|
-
*Ryuta Kamizono*
|
909
|
-
|
910
|
-
* Allow attribute's default to be configured but keeping its own type.
|
911
|
-
|
912
693
|
```ruby
|
913
|
-
|
914
|
-
|
915
|
-
end
|
916
|
-
|
917
|
-
# Rails 6.0
|
918
|
-
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
|
919
|
-
|
920
|
-
# Rails 6.1
|
921
|
-
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
|
694
|
+
GET /books
|
695
|
+
# SELECT * FROM books /*application:MyApp;controller:books;action:index*/
|
922
696
|
```
|
923
697
|
|
924
|
-
|
925
|
-
|
926
|
-
* Allow default to be configured for Enum.
|
698
|
+
Custom tags containing static values and Procs can be defined in the application configuration:
|
927
699
|
|
928
700
|
```ruby
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
701
|
+
config.active_record.query_log_tags = [
|
702
|
+
:application,
|
703
|
+
:controller,
|
704
|
+
:action,
|
705
|
+
{
|
706
|
+
custom_static: "foo",
|
707
|
+
custom_dynamic: -> { Time.now }
|
708
|
+
}
|
709
|
+
]
|
934
710
|
```
|
935
711
|
|
936
|
-
*
|
712
|
+
*Keeran Raj Hawoldar*, *Eileen M. Uchitelle*, *Kasper Timm Hansen*
|
937
713
|
|
938
|
-
*
|
714
|
+
* Added support for multiple databases to `rails db:setup` and `rails db:reset`.
|
939
715
|
|
940
|
-
*
|
716
|
+
*Ryan Hall*
|
941
717
|
|
942
|
-
*
|
943
|
-
allows you to specify that all string columns should be frozen unless
|
944
|
-
otherwise specified. This will reduce memory pressure for applications which
|
945
|
-
do not generally mutate string properties of Active Record objects.
|
718
|
+
* Add `ActiveRecord::Relation#structurally_compatible?`.
|
946
719
|
|
947
|
-
|
720
|
+
Adds a query method by which a user can tell if the relation that they're
|
721
|
+
about to use for `#or` or `#and` is structurally compatible with the
|
722
|
+
receiver.
|
948
723
|
|
949
|
-
*
|
724
|
+
*Kevin Newton*
|
950
725
|
|
951
|
-
|
726
|
+
* Add `ActiveRecord::QueryMethods#in_order_of`.
|
952
727
|
|
953
|
-
|
728
|
+
This allows you to specify an explicit order that you'd like records
|
729
|
+
returned in based on a SQL expression. By default, this will be accomplished
|
730
|
+
using a case statement, as in:
|
954
731
|
|
955
732
|
```ruby
|
956
|
-
|
957
|
-
mary_and_bob = Author.where(id: [mary, bob])
|
958
|
-
|
959
|
-
david_and_mary.merge(mary_and_bob) # => [mary, bob]
|
960
|
-
|
961
|
-
david_and_mary.and(mary_and_bob) # => [mary]
|
962
|
-
david_and_mary.or(mary_and_bob) # => [david, mary, bob]
|
733
|
+
Post.in_order_of(:id, [3, 5, 1])
|
963
734
|
```
|
964
735
|
|
965
|
-
|
966
|
-
|
967
|
-
* Merging conditions on the same column no longer maintain both conditions,
|
968
|
-
and will be consistently replaced by the latter condition in Rails 7.0.
|
969
|
-
To migrate to Rails 7.0's behavior, use `relation.merge(other, rewhere: true)`.
|
970
|
-
|
971
|
-
```ruby
|
972
|
-
# Rails 6.1 (IN clause is replaced by merger side equality condition)
|
973
|
-
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
736
|
+
will generate the SQL:
|
974
737
|
|
975
|
-
|
976
|
-
|
738
|
+
```sql
|
739
|
+
SELECT "posts".* FROM "posts" ORDER BY CASE "posts"."id" WHEN 3 THEN 1 WHEN 5 THEN 2 WHEN 1 THEN 3 ELSE 4 END ASC
|
740
|
+
```
|
977
741
|
|
978
|
-
|
979
|
-
|
742
|
+
However, because this functionality is built into MySQL in the form of the
|
743
|
+
`FIELD` function, that connection adapter will generate the following SQL
|
744
|
+
instead:
|
980
745
|
|
981
|
-
|
982
|
-
|
983
|
-
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
746
|
+
```sql
|
747
|
+
SELECT "posts".* FROM "posts" ORDER BY FIELD("posts"."id", 1, 5, 3) DESC
|
984
748
|
```
|
985
749
|
|
986
|
-
*
|
750
|
+
*Kevin Newton*
|
987
751
|
|
988
|
-
*
|
752
|
+
* Fix `eager_loading?` when ordering with `Symbol`.
|
989
753
|
|
990
|
-
|
754
|
+
`eager_loading?` is triggered correctly when using `order` with symbols.
|
991
755
|
|
992
|
-
|
756
|
+
```ruby
|
757
|
+
scope = Post.includes(:comments).order(:"comments.label")
|
758
|
+
=> true
|
759
|
+
```
|
993
760
|
|
994
|
-
|
995
|
-
`ActiveRecord::Persistence.upsert_all` was used with the name of an expression index, an error
|
996
|
-
was raised. Adding a guard around the formatting behavior for the `:unique_by` corrects this.
|
761
|
+
*Jacopo Beschi*
|
997
762
|
|
998
|
-
|
763
|
+
* Two change tracking methods are added for `belongs_to` associations.
|
999
764
|
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
t.index "lower(name)", unique: true
|
1004
|
-
end
|
765
|
+
The `association_changed?` method (assuming an association named `:association`) returns true
|
766
|
+
if a different associated object has been assigned and the foreign key will be updated in the
|
767
|
+
next save.
|
1005
768
|
|
1006
|
-
|
1007
|
-
|
769
|
+
The `association_previously_changed?` method returns true if the previous save updated the
|
770
|
+
association to reference a different associated object.
|
1008
771
|
|
1009
|
-
|
772
|
+
*George Claghorn*
|
1010
773
|
|
1011
|
-
|
774
|
+
* Add option to disable schema dump per-database.
|
1012
775
|
|
1013
|
-
|
776
|
+
Dumping the schema is on by default for all databases in an application. To turn it off for a
|
777
|
+
specific database, use the `schema_dump` option:
|
1014
778
|
|
1015
|
-
|
779
|
+
```yaml
|
780
|
+
# config/database.yml
|
1016
781
|
|
1017
|
-
|
1018
|
-
|
1019
|
-
remove_check_constraint :products, name: "price_check"
|
782
|
+
production:
|
783
|
+
schema_dump: false
|
1020
784
|
```
|
1021
785
|
|
1022
|
-
*
|
786
|
+
*Luis Vasconcellos*, *Eileen M. Uchitelle*
|
1023
787
|
|
1024
|
-
*
|
1025
|
-
to enable/disable strict_loading mode by default for a model. The configuration's value is
|
1026
|
-
inheritable by subclasses, but they can override that value and it will not impact parent class.
|
788
|
+
* Fix `eager_loading?` when ordering with `Hash` syntax.
|
1027
789
|
|
1028
|
-
|
790
|
+
`eager_loading?` is triggered correctly when using `order` with hash syntax
|
791
|
+
on an outer table.
|
1029
792
|
|
1030
793
|
```ruby
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
has_many :projects
|
1035
|
-
end
|
1036
|
-
|
1037
|
-
dev = Developer.first
|
1038
|
-
dev.projects.first
|
1039
|
-
# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
|
794
|
+
Post.includes(:comments).order({ "comments.label": :ASC }).eager_loading?
|
795
|
+
# => true
|
1040
796
|
```
|
1041
797
|
|
1042
|
-
*
|
1043
|
-
|
1044
|
-
* Deprecate passing an Active Record object to `quote`/`type_cast` directly.
|
798
|
+
*Jacopo Beschi*
|
1045
799
|
|
1046
|
-
|
800
|
+
* Move the forcing of clear text encoding to the `ActiveRecord::Encryption::Encryptor`.
|
1047
801
|
|
1048
|
-
|
802
|
+
Fixes #42699.
|
1049
803
|
|
1050
|
-
|
804
|
+
*J Smith*
|
1051
805
|
|
1052
|
-
|
1053
|
-
create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
1054
|
-
end
|
1055
|
-
```
|
806
|
+
* `partial_inserts` is now disabled by default in new apps.
|
1056
807
|
|
1057
|
-
|
808
|
+
This will be the default for new apps in Rails 7. To opt in:
|
1058
809
|
|
1059
810
|
```ruby
|
1060
|
-
|
1061
|
-
end
|
811
|
+
config.active_record.partial_inserts = true
|
1062
812
|
```
|
1063
813
|
|
1064
|
-
|
814
|
+
If a migration removes the default value of a column, this option
|
815
|
+
would cause old processes to no longer be able to create new records.
|
1065
816
|
|
1066
|
-
|
1067
|
-
|
817
|
+
If you need to remove a column, you should first use `ignored_columns`
|
818
|
+
to stop using it.
|
1068
819
|
|
1069
|
-
*
|
820
|
+
*Jean Boussier*
|
1070
821
|
|
1071
|
-
*
|
822
|
+
* Rails can now verify foreign keys after loading fixtures in tests.
|
1072
823
|
|
1073
|
-
|
824
|
+
This will be the default for new apps in Rails 7. To opt in:
|
1074
825
|
|
1075
826
|
```ruby
|
1076
|
-
|
1077
|
-
|
1078
|
-
# duplicated group fields, deprecated.
|
1079
|
-
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
|
1080
|
-
# => {
|
1081
|
-
# [1, 1] => 50,
|
1082
|
-
# [2, 2] => 60
|
1083
|
-
# }
|
1084
|
-
|
1085
|
-
# use `uniq!(:group)` to deduplicate group fields.
|
1086
|
-
accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
|
1087
|
-
# => {
|
1088
|
-
# 1 => 50,
|
1089
|
-
# 2 => 60
|
1090
|
-
# }
|
827
|
+
config.active_record.verify_foreign_keys_for_fixtures = true
|
1091
828
|
```
|
1092
829
|
|
1093
|
-
|
830
|
+
Tests will not run if there is a foreign key constraint violation in your fixture data.
|
1094
831
|
|
1095
|
-
|
832
|
+
The feature is supported by SQLite and PostgreSQL, other adapters can also add support for it.
|
1096
833
|
|
1097
|
-
|
834
|
+
*Alex Ghiculescu*
|
1098
835
|
|
1099
|
-
|
1100
|
-
accounts = Account.where(id: [1, 2]).annotate("david and mary")
|
836
|
+
* Clear cached `has_one` association after setting `belongs_to` association to `nil`.
|
1101
837
|
|
1102
|
-
|
1103
|
-
|
1104
|
-
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */ /* david and mary */
|
838
|
+
After setting a `belongs_to` relation to `nil` and updating an unrelated attribute on the owner,
|
839
|
+
the owner should still return `nil` on the `has_one` relation.
|
1105
840
|
|
1106
|
-
#
|
1107
|
-
accounts.merge(accounts.rewhere(id: 3)).uniq!(:annotate)
|
1108
|
-
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */
|
1109
|
-
```
|
841
|
+
Fixes #42597.
|
1110
842
|
|
1111
|
-
*
|
843
|
+
*Michiel de Mare*
|
1112
844
|
|
1113
|
-
*
|
845
|
+
* OpenSSL constants are now used for Digest computations.
|
1114
846
|
|
1115
|
-
|
1116
|
-
cache. This avoids raising an unnecessary `ActiveRecord::StaleObjectError`
|
1117
|
-
upon subsequent transactions by maintaining parity with the corresponding
|
1118
|
-
database record's `lock_version` column.
|
847
|
+
*Dirkjan Bussink*
|
1119
848
|
|
1120
|
-
|
849
|
+
* Adds support for `if_not_exists` to `add_foreign_key` and `if_exists` to `remove_foreign_key`.
|
1121
850
|
|
1122
|
-
|
851
|
+
Applications can set their migrations to ignore exceptions raised when adding a foreign key
|
852
|
+
that already exists or when removing a foreign key that does not exist.
|
1123
853
|
|
1124
|
-
|
854
|
+
Example Usage:
|
1125
855
|
|
1126
856
|
```ruby
|
1127
|
-
|
857
|
+
class AddAuthorsForeignKeyToArticles < ActiveRecord::Migration[7.0]
|
858
|
+
def change
|
859
|
+
add_foreign_key :articles, :authors, if_not_exists: true
|
860
|
+
end
|
861
|
+
end
|
862
|
+
```
|
1128
863
|
|
1129
|
-
|
1130
|
-
|
864
|
+
```ruby
|
865
|
+
class RemoveAuthorsForeignKeyFromArticles < ActiveRecord::Migration[7.0]
|
866
|
+
def change
|
867
|
+
remove_foreign_key :articles, :authors, if_exists: true
|
868
|
+
end
|
869
|
+
end
|
870
|
+
```
|
1131
871
|
|
1132
|
-
|
1133
|
-
david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
|
872
|
+
*Roberto Miranda*
|
1134
873
|
|
1135
|
-
|
1136
|
-
david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
|
1137
|
-
```
|
874
|
+
* Prevent polluting ENV during postgresql structure dump/load.
|
1138
875
|
|
1139
|
-
|
876
|
+
Some configuration parameters were provided to pg_dump / psql via
|
877
|
+
environment variables which persisted beyond the command being run, and may
|
878
|
+
have caused subsequent commands and connections to fail. Tasks running
|
879
|
+
across multiple postgresql databases like `rails db:test:prepare` may have
|
880
|
+
been affected.
|
1140
881
|
|
1141
|
-
*
|
1142
|
-
set to expire and scoped with a purpose. This is particularly useful for things like password reset
|
1143
|
-
or email verification, where you want the bearer of the signed id to be able to interact with the
|
1144
|
-
underlying record, but usually only within a certain time period.
|
882
|
+
*Samuel Cochran*
|
1145
883
|
|
1146
|
-
|
1147
|
-
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
|
884
|
+
* Set precision 6 by default for `datetime` columns.
|
1148
885
|
|
1149
|
-
|
886
|
+
By default, datetime columns will have microseconds precision instead of seconds precision.
|
1150
887
|
|
1151
|
-
|
1152
|
-
User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
|
888
|
+
*Roberto Miranda*
|
1153
889
|
|
1154
|
-
|
1155
|
-
User.find_signed signed_id, purpose: :password_reset # => User.first
|
890
|
+
* Allow preloading of associations with instance dependent scopes.
|
1156
891
|
|
1157
|
-
|
1158
|
-
```
|
892
|
+
*John Hawthorn*, *John Crepezzi*, *Adam Hess*, *Eileen M. Uchitelle*, *Dinah Shi*
|
1159
893
|
|
1160
|
-
|
894
|
+
* Do not try to rollback transactions that failed due to a `ActiveRecord::TransactionRollbackError`.
|
1161
895
|
|
1162
|
-
*
|
896
|
+
*Jamie McCarthy*
|
1163
897
|
|
1164
|
-
|
898
|
+
* Active Record Encryption will now encode values as UTF-8 when using deterministic
|
899
|
+
encryption. The encoding is part of the encrypted payload, so different encodings for
|
900
|
+
different values result in different ciphertexts. This can break unique constraints and
|
901
|
+
queries.
|
1165
902
|
|
1166
|
-
|
903
|
+
The new behavior is configurable via `active_record.encryption.forced_encoding_for_deterministic_encryption`
|
904
|
+
that is `Encoding::UTF_8` by default. It can be disabled by setting it to `nil`.
|
1167
905
|
|
1168
|
-
*
|
906
|
+
*Jorge Manrubia*
|
1169
907
|
|
1170
|
-
*
|
908
|
+
* The MySQL adapter now cast numbers and booleans bind parameters to string for safety reasons.
|
1171
909
|
|
1172
|
-
|
910
|
+
When comparing a string and a number in a query, MySQL converts the string to a number. So for
|
911
|
+
instance `"foo" = 0`, will implicitly cast `"foo"` to `0` and will evaluate to `TRUE` which can
|
912
|
+
lead to security vulnerabilities.
|
1173
913
|
|
1174
|
-
|
1175
|
-
|
1176
|
-
posts = posts.where("posts.hidden": false, "comments.hidden": false)
|
914
|
+
Active Record already protect against that vulnerability when it knows the type of the column
|
915
|
+
being compared, however until now it was still vulnerable when using bind parameters:
|
1177
916
|
|
1178
|
-
|
1179
|
-
|
917
|
+
```ruby
|
918
|
+
User.where("login_token = ?", 0).first
|
919
|
+
```
|
1180
920
|
|
1181
|
-
|
1182
|
-
posts.unscope(where: :hidden).count
|
1183
|
-
# => { false => 11, true => 1 }
|
921
|
+
Would perform:
|
1184
922
|
|
1185
|
-
|
1186
|
-
|
1187
|
-
# => { false => 11 }
|
923
|
+
```sql
|
924
|
+
SELECT * FROM `users` WHERE `login_token` = 0 LIMIT 1;
|
1188
925
|
```
|
1189
926
|
|
1190
|
-
|
927
|
+
Now it will perform:
|
1191
928
|
|
1192
|
-
|
929
|
+
```sql
|
930
|
+
SELECT * FROM `users` WHERE `login_token` = '0' LIMIT 1;
|
931
|
+
```
|
1193
932
|
|
1194
|
-
|
1195
|
-
steve = Person.find_by(name: "Steve")
|
1196
|
-
david = Author.find_by(name: "David")
|
933
|
+
*Jean Boussier*
|
1197
934
|
|
1198
|
-
|
935
|
+
* Fixture configurations (`_fixture`) are now strictly validated.
|
1199
936
|
|
1200
|
-
|
1201
|
-
|
937
|
+
If an error will be raised if that entry contains unknown keys while previously it
|
938
|
+
would silently have no effects.
|
1202
939
|
|
1203
|
-
|
1204
|
-
relation.rewhere(writer: david).to_a # => [david]
|
1205
|
-
```
|
940
|
+
*Jean Boussier*
|
1206
941
|
|
1207
|
-
|
942
|
+
* Add `ActiveRecord::Base.update!` that works like `ActiveRecord::Base.update` but raises exceptions.
|
1208
943
|
|
1209
|
-
|
944
|
+
This allows for the same behavior as the instance method `#update!` at a class level.
|
1210
945
|
|
1211
946
|
```ruby
|
1212
|
-
|
1213
|
-
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000 +0000">
|
947
|
+
Person.update!(:all, state: "confirmed")
|
1214
948
|
```
|
1215
949
|
|
1216
|
-
*
|
950
|
+
*Dorian Marié*
|
1217
951
|
|
1218
|
-
*
|
952
|
+
* Add `ActiveRecord::Base#attributes_for_database`.
|
1219
953
|
|
1220
|
-
|
954
|
+
Returns attributes with values for assignment to the database.
|
1221
955
|
|
1222
|
-
*
|
956
|
+
*Chris Salzberg*
|
1223
957
|
|
1224
|
-
|
958
|
+
* Use an empty query to check if the PostgreSQL connection is still active.
|
1225
959
|
|
1226
|
-
|
960
|
+
An empty query is faster than `SELECT 1`.
|
1227
961
|
|
1228
|
-
*
|
962
|
+
*Heinrich Lee Yu*
|
1229
963
|
|
1230
|
-
*
|
964
|
+
* Add `ActiveRecord::Base#previously_persisted?`.
|
1231
965
|
|
1232
|
-
|
966
|
+
Returns `true` if the object has been previously persisted but now it has been deleted.
|
1233
967
|
|
1234
|
-
*
|
968
|
+
* Deprecate `partial_writes` in favor of `partial_inserts` and `partial_updates`.
|
1235
969
|
|
1236
|
-
|
970
|
+
This allows to have a different behavior on update and create.
|
1237
971
|
|
1238
|
-
*
|
972
|
+
*Jean Boussier*
|
1239
973
|
|
1240
|
-
*
|
974
|
+
* Fix compatibility with `psych >= 4`.
|
1241
975
|
|
1242
|
-
|
976
|
+
Starting in Psych 4.0.0 `YAML.load` behaves like `YAML.safe_load`. To preserve compatibility,
|
977
|
+
Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
|
1243
978
|
|
1244
|
-
*
|
979
|
+
*Jean Boussier*
|
1245
980
|
|
1246
|
-
|
981
|
+
* `ActiveRecord::Base.logger` is now a `class_attribute`.
|
1247
982
|
|
1248
|
-
|
983
|
+
This means it can no longer be accessed directly through `@@logger`, and that setting `logger =`
|
984
|
+
on a subclass won't change the parent's logger.
|
1249
985
|
|
1250
|
-
*
|
986
|
+
*Jean Boussier*
|
1251
987
|
|
1252
|
-
|
1253
|
-
index won't be added.
|
988
|
+
* Add `.asc.nulls_first` for all databases. Unfortunately MySQL still doesn't like `nulls_last`.
|
1254
989
|
|
1255
|
-
|
990
|
+
*Keenan Brock*
|
1256
991
|
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
992
|
+
* Improve performance of `one?` and `many?` by limiting the generated count query to 2 results.
|
993
|
+
|
994
|
+
*Gonzalo Riestra*
|
995
|
+
|
996
|
+
* Don't check type when using `if_not_exists` on `add_column`.
|
997
|
+
|
998
|
+
Previously, if a migration called `add_column` with the `if_not_exists` option set to true
|
999
|
+
the `column_exists?` check would look for a column with the same name and type as the migration.
|
1000
|
+
|
1001
|
+
Recently it was discovered that the type passed to the migration is not always the same type
|
1002
|
+
as the column after migration. For example a column set to `:mediumblob` in the migration will
|
1003
|
+
be casted to `binary` when calling `column.type`. Since there is no straightforward way to cast
|
1004
|
+
the type to the database type without running the migration, we opted to drop the type check from
|
1005
|
+
`add_column`. This means that migrations adding a duplicate column with a different type will no
|
1006
|
+
longer raise an error.
|
1260
1007
|
|
1261
|
-
|
1262
|
-
created within that migration so that if table and its indexes exist then there is no
|
1263
|
-
attempt to create them again.
|
1008
|
+
*Eileen M. Uchitelle*
|
1264
1009
|
|
1265
|
-
|
1010
|
+
* Log a warning message when running SQLite in production.
|
1266
1011
|
|
1267
|
-
|
1012
|
+
Using SQLite in production ENV is generally discouraged. SQLite is also the default adapter
|
1013
|
+
in a new Rails application.
|
1014
|
+
For the above reasons log a warning message when running SQLite in production.
|
1268
1015
|
|
1269
|
-
|
1016
|
+
The warning can be disabled by setting `config.active_record.sqlite3_production_warning=false`.
|
1270
1017
|
|
1271
|
-
*
|
1018
|
+
*Jacopo Beschi*
|
1272
1019
|
|
1273
|
-
|
1020
|
+
* Add option to disable joins for `has_one` associations.
|
1274
1021
|
|
1275
|
-
|
1022
|
+
In a multiple database application, associations can't join across
|
1023
|
+
databases. When set, this option instructs Rails to generate 2 or
|
1024
|
+
more queries rather than generating joins for `has_one` associations.
|
1276
1025
|
|
1277
|
-
|
1026
|
+
Set the option on a has one through association:
|
1278
1027
|
|
1279
1028
|
```ruby
|
1280
|
-
Person
|
1281
|
-
|
1029
|
+
class Person
|
1030
|
+
has_one :dog
|
1031
|
+
has_one :veterinarian, through: :dog, disable_joins: true
|
1282
1032
|
end
|
1283
1033
|
```
|
1284
1034
|
|
1285
|
-
|
1035
|
+
Then instead of generating join SQL, two queries are used for `@person.veterinarian`:
|
1286
1036
|
|
1287
|
-
|
1037
|
+
```
|
1038
|
+
SELECT "dogs"."id" FROM "dogs" WHERE "dogs"."person_id" = ? [["person_id", 1]]
|
1039
|
+
SELECT "veterinarians".* FROM "veterinarians" WHERE "veterinarians"."dog_id" = ? [["dog_id", 1]]
|
1040
|
+
```
|
1288
1041
|
|
1289
|
-
|
1042
|
+
*Sarah Vessels*, *Eileen M. Uchitelle*
|
1290
1043
|
|
1291
|
-
|
1044
|
+
* `Arel::Visitors::Dot` now renders a complete set of properties when visiting
|
1045
|
+
`Arel::Nodes::SelectCore`, `SelectStatement`, `InsertStatement`, `UpdateStatement`, and
|
1046
|
+
`DeleteStatement`, which fixes #42026. Previously, some properties were omitted.
|
1292
1047
|
|
1293
|
-
*
|
1048
|
+
*Mike Dalessio*
|
1294
1049
|
|
1295
|
-
|
1050
|
+
* `Arel::Visitors::Dot` now supports `Arel::Nodes::Bin`, `Case`, `CurrentRow`, `Distinct`,
|
1051
|
+
`DistinctOn`, `Else`, `Except`, `InfixOperation`, `Intersect`, `Lock`, `NotRegexp`, `Quoted`,
|
1052
|
+
`Regexp`, `UnaryOperation`, `Union`, `UnionAll`, `When`, and `With`. Previously, these node
|
1053
|
+
types caused an exception to be raised by `Arel::Visitors::Dot#accept`.
|
1296
1054
|
|
1297
|
-
*
|
1055
|
+
*Mike Dalessio*
|
1298
1056
|
|
1299
|
-
* `
|
1057
|
+
* Optimize `remove_columns` to use a single SQL statement.
|
1300
1058
|
|
1301
|
-
|
1059
|
+
```ruby
|
1060
|
+
remove_columns :my_table, :col_one, :col_two
|
1061
|
+
```
|
1302
1062
|
|
1303
|
-
|
1063
|
+
Now results in the following SQL:
|
1304
1064
|
|
1305
|
-
|
1065
|
+
```sql
|
1066
|
+
ALTER TABLE "my_table" DROP COLUMN "col_one", DROP COLUMN "col_two"
|
1067
|
+
```
|
1306
1068
|
|
1307
|
-
*
|
1069
|
+
*Jon Dufresne*
|
1308
1070
|
|
1309
|
-
|
1071
|
+
* Ensure `has_one` autosave association callbacks get called once.
|
1310
1072
|
|
1311
|
-
|
1073
|
+
Change the `has_one` autosave callback to be non cyclic as well.
|
1074
|
+
By doing this the autosave callback are made more consistent for
|
1075
|
+
all 3 cases: `has_many`, `has_one`, and `belongs_to`.
|
1312
1076
|
|
1313
|
-
*
|
1077
|
+
*Petrik de Heus*
|
1314
1078
|
|
1315
|
-
*
|
1079
|
+
* Add option to disable joins for associations.
|
1316
1080
|
|
1317
|
-
|
1081
|
+
In a multiple database application, associations can't join across
|
1082
|
+
databases. When set, this option instructs Rails to generate 2 or
|
1083
|
+
more queries rather than generating joins for associations.
|
1318
1084
|
|
1319
|
-
|
1085
|
+
Set the option on a has many through association:
|
1320
1086
|
|
1321
|
-
|
1087
|
+
```ruby
|
1088
|
+
class Dog
|
1089
|
+
has_many :treats, through: :humans, disable_joins: true
|
1090
|
+
has_many :humans
|
1091
|
+
end
|
1092
|
+
```
|
1322
1093
|
|
1323
|
-
|
1094
|
+
Then instead of generating join SQL, two queries are used for `@dog.treats`:
|
1324
1095
|
|
1325
|
-
|
1096
|
+
```
|
1097
|
+
SELECT "humans"."id" FROM "humans" WHERE "humans"."dog_id" = ? [["dog_id", 1]]
|
1098
|
+
SELECT "treats".* FROM "treats" WHERE "treats"."human_id" IN (?, ?, ?) [["human_id", 1], ["human_id", 2], ["human_id", 3]]
|
1099
|
+
```
|
1326
1100
|
|
1327
|
-
*
|
1101
|
+
*Eileen M. Uchitelle*, *Aaron Patterson*, *Lee Quarella*
|
1328
1102
|
|
1329
|
-
|
1103
|
+
* Add setting for enumerating column names in SELECT statements.
|
1330
1104
|
|
1331
|
-
|
1105
|
+
Adding a column to a PostgreSQL database, for example, while the application is running can
|
1106
|
+
change the result of wildcard `SELECT *` queries, which invalidates the result
|
1107
|
+
of cached prepared statements and raises a `PreparedStatementCacheExpired` error.
|
1332
1108
|
|
1333
|
-
|
1109
|
+
When enabled, Active Record will avoid wildcards and always include column names
|
1110
|
+
in `SELECT` queries, which will return consistent results and avoid prepared
|
1111
|
+
statement errors.
|
1334
1112
|
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
primary_shard_one:
|
1341
|
-
database: my_database_shard_one
|
1113
|
+
Before:
|
1114
|
+
|
1115
|
+
```ruby
|
1116
|
+
Book.limit(5)
|
1117
|
+
# SELECT * FROM books LIMIT 5
|
1342
1118
|
```
|
1343
1119
|
|
1344
|
-
|
1120
|
+
After:
|
1345
1121
|
|
1346
1122
|
```ruby
|
1347
|
-
|
1348
|
-
|
1123
|
+
# config/application.rb
|
1124
|
+
module MyApp
|
1125
|
+
class Application < Rails::Application
|
1126
|
+
config.active_record.enumerate_columns_in_select_statements = true
|
1127
|
+
end
|
1128
|
+
end
|
1349
1129
|
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1130
|
+
# or, configure per-model
|
1131
|
+
class Book < ApplicationRecord
|
1132
|
+
self.enumerate_columns_in_select_statements = true
|
1133
|
+
end
|
1354
1134
|
```
|
1355
1135
|
|
1356
|
-
Swap between shards in your controller / model code:
|
1357
|
-
|
1358
1136
|
```ruby
|
1359
|
-
|
1360
|
-
|
1361
|
-
end
|
1137
|
+
Book.limit(5)
|
1138
|
+
# SELECT id, author_id, name, format, status, language, etc FROM books LIMIT 5
|
1362
1139
|
```
|
1363
1140
|
|
1364
|
-
|
1141
|
+
*Matt Duszynski*
|
1365
1142
|
|
1366
|
-
|
1143
|
+
* Allow passing SQL as `on_duplicate` value to `#upsert_all` to make it possible to use raw SQL to update columns on conflict:
|
1367
1144
|
|
1368
|
-
|
1145
|
+
```ruby
|
1146
|
+
Book.upsert_all(
|
1147
|
+
[{ id: 1, status: 1 }, { id: 2, status: 1 }],
|
1148
|
+
on_duplicate: Arel.sql("status = GREATEST(books.status, EXCLUDED.status)")
|
1149
|
+
)
|
1150
|
+
```
|
1369
1151
|
|
1370
|
-
|
1152
|
+
*Vladimir Dementyev*
|
1371
1153
|
|
1372
|
-
|
1154
|
+
* Allow passing SQL as `returning` statement to `#upsert_all`:
|
1373
1155
|
|
1374
1156
|
```ruby
|
1375
|
-
|
1376
|
-
|
1157
|
+
Article.insert_all(
|
1158
|
+
[
|
1159
|
+
{ title: "Article 1", slug: "article-1", published: false },
|
1160
|
+
{ title: "Article 2", slug: "article-2", published: false }
|
1161
|
+
],
|
1162
|
+
returning: Arel.sql("id, (xmax = '0') as inserted, name as new_name")
|
1163
|
+
)
|
1377
1164
|
```
|
1378
1165
|
|
1379
|
-
|
1166
|
+
*Vladimir Dementyev*
|
1380
1167
|
|
1381
|
-
|
1382
|
-
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary")
|
1383
|
-
db_config.name
|
1384
|
-
```
|
1168
|
+
* Deprecate `legacy_connection_handling`.
|
1385
1169
|
|
1386
1170
|
*Eileen M. Uchitelle*
|
1387
1171
|
|
1388
|
-
* Add
|
1172
|
+
* Add attribute encryption support.
|
1389
1173
|
|
1390
|
-
|
1391
|
-
|
1174
|
+
Encrypted attributes are declared at the model level. These
|
1175
|
+
are regular Active Record attributes backed by a column with
|
1176
|
+
the same name. The system will transparently encrypt these
|
1177
|
+
attributes before saving them into the database and will
|
1178
|
+
decrypt them when retrieving their values.
|
1392
1179
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
rails db:drop:animals
|
1400
|
-
rails db:migrate
|
1401
|
-
rails db:migrate:primary
|
1402
|
-
rails db:migrate:animals
|
1180
|
+
|
1181
|
+
```ruby
|
1182
|
+
class Person < ApplicationRecord
|
1183
|
+
encrypts :name
|
1184
|
+
encrypts :email_address, deterministic: true
|
1185
|
+
end
|
1403
1186
|
```
|
1404
1187
|
|
1405
|
-
|
1406
|
-
|
1188
|
+
You can learn more in the [Active Record Encryption
|
1189
|
+
guide](https://edgeguides.rubyonrails.org/active_record_encryption.html).
|
1407
1190
|
|
1408
|
-
|
1409
|
-
rails db:schema:dump
|
1410
|
-
rails db:schema:dump:primary
|
1411
|
-
rails db:schema:dump:animals
|
1412
|
-
rails db:schema:load
|
1413
|
-
rails db:schema:load:primary
|
1414
|
-
rails db:schema:load:animals
|
1415
|
-
rails db:structure:dump
|
1416
|
-
rails db:structure:dump:primary
|
1417
|
-
rails db:structure:dump:animals
|
1418
|
-
rails db:structure:load
|
1419
|
-
rails db:structure:load:primary
|
1420
|
-
rails db:structure:load:animals
|
1421
|
-
rails db:test:prepare
|
1422
|
-
rails db:test:prepare:primary
|
1423
|
-
rails db:test:prepare:animals
|
1424
|
-
```
|
1191
|
+
*Jorge Manrubia*
|
1425
1192
|
|
1426
|
-
|
1193
|
+
* Changed Arel predications `contains` and `overlaps` to use
|
1194
|
+
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
1427
1195
|
|
1428
|
-
*
|
1196
|
+
*Bradley Priest*
|
1429
1197
|
|
1430
|
-
|
1198
|
+
* Add mode argument to record level `strict_loading!`.
|
1431
1199
|
|
1432
|
-
|
1200
|
+
This argument can be used when enabling strict loading for a single record
|
1201
|
+
to specify that we only want to raise on n plus one queries.
|
1433
1202
|
|
1434
1203
|
```ruby
|
1435
|
-
|
1436
|
-
has_many :projects, strict_loading: true
|
1437
|
-
end
|
1204
|
+
developer.strict_loading!(mode: :n_plus_one_only)
|
1438
1205
|
|
1439
|
-
|
1440
|
-
|
1441
|
-
# => ActiveRecord::StrictLoadingViolationError: The projects association is marked as strict_loading and cannot be lazily loaded.
|
1206
|
+
developer.projects.to_a # Does not raise
|
1207
|
+
developer.projects.first.client # Raises StrictLoadingViolationError
|
1442
1208
|
```
|
1443
1209
|
|
1444
|
-
|
1210
|
+
Previously, enabling strict loading would cause any lazily loaded
|
1211
|
+
association to raise an error. Using `n_plus_one_only` mode allows us to
|
1212
|
+
lazily load belongs_to, has_many, and other associations that are fetched
|
1213
|
+
through a single query.
|
1445
1214
|
|
1446
|
-
*
|
1215
|
+
*Dinah Shi*
|
1447
1216
|
|
1448
|
-
|
1217
|
+
* Fix Float::INFINITY assignment to datetime column with postgresql adapter.
|
1449
1218
|
|
1450
|
-
|
1219
|
+
Before:
|
1451
1220
|
|
1452
1221
|
```ruby
|
1453
|
-
|
1454
|
-
|
1455
|
-
# => ActiveRecord::StrictLoadingViolationError: Developer is marked as strict_loading and AuditLog cannot be lazily loaded.
|
1456
|
-
```
|
1222
|
+
# With this config
|
1223
|
+
ActiveRecord::Base.time_zone_aware_attributes = true
|
1457
1224
|
|
1458
|
-
|
1225
|
+
# and the following schema:
|
1226
|
+
create_table "postgresql_infinities" do |t|
|
1227
|
+
t.datetime "datetime"
|
1228
|
+
end
|
1459
1229
|
|
1460
|
-
|
1230
|
+
# This test fails
|
1231
|
+
record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
|
1232
|
+
assert_equal Float::INFINITY, record.datetime # record.datetime gets nil
|
1233
|
+
```
|
1461
1234
|
|
1462
|
-
|
1235
|
+
After this commit, `record.datetime` gets `Float::INFINITY` as expected.
|
1463
1236
|
|
1464
|
-
*
|
1237
|
+
*Shunichi Ikegami*
|
1465
1238
|
|
1466
|
-
|
1239
|
+
* Type cast enum values by the original attribute type.
|
1467
1240
|
|
1468
|
-
|
1241
|
+
The notable thing about this change is that unknown labels will no longer match 0 on MySQL.
|
1469
1242
|
|
1470
1243
|
```ruby
|
1471
|
-
class
|
1472
|
-
|
1473
|
-
add_column :posts, :title, :string, if_not_exists: true
|
1474
|
-
end
|
1244
|
+
class Book < ActiveRecord::Base
|
1245
|
+
enum :status, { proposed: 0, written: 1, published: 2 }
|
1475
1246
|
end
|
1476
1247
|
```
|
1477
1248
|
|
1249
|
+
Before:
|
1250
|
+
|
1478
1251
|
```ruby
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1252
|
+
# SELECT `books`.* FROM `books` WHERE `books`.`status` = 'prohibited' LIMIT 1
|
1253
|
+
Book.find_by(status: :prohibited)
|
1254
|
+
# => #<Book id: 1, status: "proposed", ...> (for mysql2 adapter)
|
1255
|
+
# => ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: invalid input syntax for type integer: "prohibited" (for postgresql adapter)
|
1256
|
+
# => nil (for sqlite3 adapter)
|
1484
1257
|
```
|
1485
1258
|
|
1486
|
-
|
1487
|
-
|
1488
|
-
* Regexp-escape table name for MS SQL Server.
|
1489
|
-
|
1490
|
-
Add `Regexp.escape` to one method in ActiveRecord, so that table names with regular expression characters in them work as expected. Since MS SQL Server uses "[" and "]" to quote table and column names, and those characters are regular expression characters, methods like `pluck` and `select` fail in certain cases when used with the MS SQL Server adapter.
|
1491
|
-
|
1492
|
-
*Larry Reid*
|
1493
|
-
|
1494
|
-
* Store advisory locks on their own named connection.
|
1259
|
+
After:
|
1495
1260
|
|
1496
|
-
|
1261
|
+
```ruby
|
1262
|
+
# SELECT `books`.* FROM `books` WHERE `books`.`status` IS NULL LIMIT 1
|
1263
|
+
Book.find_by(status: :prohibited)
|
1264
|
+
# => nil (for all adapters)
|
1265
|
+
```
|
1497
1266
|
|
1498
|
-
|
1267
|
+
*Ryuta Kamizono*
|
1499
1268
|
|
1500
|
-
|
1269
|
+
* Fixtures for `has_many :through` associations now load timestamps on join tables.
|
1501
1270
|
|
1502
|
-
|
1271
|
+
Given this fixture:
|
1503
1272
|
|
1504
|
-
|
1273
|
+
```yml
|
1274
|
+
### monkeys.yml
|
1275
|
+
george:
|
1276
|
+
name: George the Monkey
|
1277
|
+
fruits: apple
|
1505
1278
|
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
database: blog_development
|
1510
|
-
pool: 5
|
1511
|
-
schema_cache_path: tmp/schema/main.yml
|
1279
|
+
### fruits.yml
|
1280
|
+
apple:
|
1281
|
+
name: apple
|
1512
1282
|
```
|
1513
1283
|
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1284
|
+
If the join table (`fruit_monkeys`) contains `created_at` or `updated_at` columns,
|
1285
|
+
these will now be populated when loading the fixture. Previously, fixture loading
|
1286
|
+
would crash if these columns were required, and leave them as null otherwise.
|
1517
1287
|
|
1518
|
-
|
1519
|
-
|
1520
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
1521
|
-
|
1522
|
-
* Deprecate `#default_hash` and it's alias `#[]` on database configurations.
|
1288
|
+
*Alex Ghiculescu*
|
1523
1289
|
|
1524
|
-
|
1290
|
+
* Allow applications to configure the thread pool for async queries.
|
1525
1291
|
|
1526
|
-
|
1292
|
+
Some applications may want one thread pool per database whereas others want to use
|
1293
|
+
a single global thread pool for all queries. By default, Rails will set `async_query_executor`
|
1294
|
+
to `nil` which will not initialize any executor. If `load_async` is called and no executor
|
1295
|
+
has been configured, the query will be executed in the foreground.
|
1527
1296
|
|
1528
|
-
|
1297
|
+
To create one thread pool for all database connections to use applications can set
|
1298
|
+
`config.active_record.async_query_executor` to `:global_thread_pool` and optionally define
|
1299
|
+
`config.active_record.global_executor_concurrency`. This defaults to 4. For applications that want
|
1300
|
+
to have a thread pool for each database connection, `config.active_record.async_query_executor` can
|
1301
|
+
be set to `:multi_thread_pool`. The configuration for each thread pool is set in the database
|
1302
|
+
configuration.
|
1529
1303
|
|
1530
|
-
*
|
1304
|
+
*Eileen M. Uchitelle*
|
1531
1305
|
|
1532
|
-
*
|
1306
|
+
* Allow new syntax for `enum` to avoid leading `_` from reserved options.
|
1533
1307
|
|
1534
1308
|
Before:
|
1535
1309
|
|
1536
1310
|
```ruby
|
1537
|
-
|
1311
|
+
class Book < ActiveRecord::Base
|
1312
|
+
enum status: [ :proposed, :written ], _prefix: true, _scopes: false
|
1313
|
+
enum cover: [ :hard, :soft ], _suffix: true, _default: :hard
|
1314
|
+
end
|
1538
1315
|
```
|
1539
1316
|
|
1540
1317
|
After:
|
1541
1318
|
|
1542
1319
|
```ruby
|
1543
|
-
|
1320
|
+
class Book < ActiveRecord::Base
|
1321
|
+
enum :status, [ :proposed, :written ], prefix: true, scopes: false
|
1322
|
+
enum :cover, [ :hard, :soft ], suffix: true, default: :hard
|
1323
|
+
end
|
1544
1324
|
```
|
1545
1325
|
|
1546
|
-
*
|
1547
|
-
|
1548
|
-
* Ensure `:reading` connections always raise if a write is attempted.
|
1549
|
-
|
1550
|
-
Now Rails will raise an `ActiveRecord::ReadOnlyError` if any connection on the reading handler attempts to make a write. If your reading role needs to write you should name the role something other than `:reading`.
|
1551
|
-
|
1552
|
-
*Eileen M. Uchitelle*
|
1553
|
-
|
1554
|
-
* Deprecate `"primary"` as the `connection_specification_name` for `ActiveRecord::Base`.
|
1555
|
-
|
1556
|
-
`"primary"` has been deprecated as the `connection_specification_name` for `ActiveRecord::Base` in favor of using `"ActiveRecord::Base"`. This change affects calls to `ActiveRecord::Base.connection_handler.retrieve_connection` and `ActiveRecord::Base.connection_handler.remove_connection`. If you're calling these methods with `"primary"`, please switch to `"ActiveRecord::Base"`.
|
1326
|
+
*Ryuta Kamizono*
|
1557
1327
|
|
1558
|
-
|
1328
|
+
* Add `ActiveRecord::Relation#load_async`.
|
1559
1329
|
|
1560
|
-
|
1561
|
-
support for casting floats using a database columns' precision value.
|
1330
|
+
This method schedules the query to be performed asynchronously from a thread pool.
|
1562
1331
|
|
1563
|
-
|
1332
|
+
If the result is accessed before a background thread had the opportunity to perform
|
1333
|
+
the query, it will be performed in the foreground.
|
1564
1334
|
|
1565
|
-
|
1566
|
-
|
1567
|
-
ActionController::ConditionalGet to ensure that when collection cache versioning
|
1568
|
-
is enabled, requests using ConditionalGet don't return the same ETag header
|
1569
|
-
after a collection is modified.
|
1335
|
+
This is useful for queries that can be performed long enough before their result will be
|
1336
|
+
needed, or for controllers which need to perform several independent queries.
|
1570
1337
|
|
1571
|
-
|
1338
|
+
```ruby
|
1339
|
+
def index
|
1340
|
+
@categories = Category.some_complex_scope.load_async
|
1341
|
+
@posts = Post.some_complex_scope.load_async
|
1342
|
+
end
|
1343
|
+
```
|
1572
1344
|
|
1573
|
-
|
1345
|
+
Active Record logs will also include timing info for the duration of how long
|
1346
|
+
the main thread had to wait to access the result. This timing is useful to know
|
1347
|
+
whether or not it's worth to load the query asynchronously.
|
1574
1348
|
|
1575
|
-
|
1576
|
-
|
1349
|
+
```
|
1350
|
+
DEBUG -- : Category Load (62.1ms) SELECT * FROM `categories` LIMIT 50
|
1351
|
+
DEBUG -- : ASYNC Post Load (64ms) (db time 126.1ms) SELECT * FROM `posts` LIMIT 100
|
1352
|
+
```
|
1577
1353
|
|
1578
|
-
|
1354
|
+
The duration in the first set of parens is how long the main thread was blocked
|
1355
|
+
waiting for the results, and the second set of parens with "db time" is how long
|
1356
|
+
the entire query took to execute.
|
1579
1357
|
|
1580
|
-
*
|
1358
|
+
*Jean Boussier*
|
1581
1359
|
|
1582
|
-
|
1360
|
+
* Implemented `ActiveRecord::Relation#excluding` method.
|
1583
1361
|
|
1584
|
-
|
1362
|
+
This method excludes the specified record (or collection of records) from
|
1363
|
+
the resulting relation:
|
1585
1364
|
|
1586
1365
|
```ruby
|
1587
|
-
|
1588
|
-
|
1366
|
+
Post.excluding(post)
|
1367
|
+
Post.excluding(post_one, post_two)
|
1589
1368
|
```
|
1590
1369
|
|
1591
|
-
|
1370
|
+
Also works on associations:
|
1592
1371
|
|
1593
1372
|
```ruby
|
1594
|
-
|
1595
|
-
|
1596
|
-
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.spec_name, config)
|
1373
|
+
post.comments.excluding(comment)
|
1374
|
+
post.comments.excluding(comment_one, comment_two)
|
1597
1375
|
```
|
1598
1376
|
|
1599
|
-
|
1600
|
-
|
1601
|
-
* Remove `:connection_id` from the `sql.active_record` notification.
|
1377
|
+
This is short-hand for `Post.where.not(id: post.id)` (for a single record)
|
1378
|
+
and `Post.where.not(id: [post_one.id, post_two.id])` (for a collection).
|
1602
1379
|
|
1603
|
-
*
|
1380
|
+
*Glen Crawford*
|
1604
1381
|
|
1605
|
-
*
|
1382
|
+
* Skip optimised #exist? query when #include? is called on a relation
|
1383
|
+
with a having clause.
|
1606
1384
|
|
1607
|
-
|
1385
|
+
Relations that have aliased select values AND a having clause that
|
1386
|
+
references an aliased select value would generate an error when
|
1387
|
+
#include? was called, due to an optimisation that would generate
|
1388
|
+
call #exists? on the relation instead, which effectively alters
|
1389
|
+
the select values of the query (and thus removes the aliased select
|
1390
|
+
values), but leaves the having clause intact. Because the having
|
1391
|
+
clause is then referencing an aliased column that is no longer
|
1392
|
+
present in the simplified query, an ActiveRecord::InvalidStatement
|
1393
|
+
error was raised.
|
1608
1394
|
|
1609
|
-
|
1395
|
+
A sample query affected by this problem:
|
1610
1396
|
|
1611
|
-
|
1612
|
-
|
1397
|
+
```ruby
|
1398
|
+
Author.select('COUNT(*) as total_posts', 'authors.*')
|
1399
|
+
.joins(:posts)
|
1400
|
+
.group(:id)
|
1401
|
+
.having('total_posts > 2')
|
1402
|
+
.include?(Author.first)
|
1403
|
+
```
|
1613
1404
|
|
1614
|
-
This change
|
1615
|
-
|
1405
|
+
This change adds an addition check to the condition that skips the
|
1406
|
+
simplified #exists? query, which simply checks for the presence of
|
1407
|
+
a having clause.
|
1616
1408
|
|
1617
|
-
|
1409
|
+
Fixes #41417.
|
1618
1410
|
|
1619
|
-
*
|
1411
|
+
*Michael Smart*
|
1620
1412
|
|
1621
|
-
|
1413
|
+
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
1414
|
+
without Rails knowledge (e.g., if app gets killed during long-running query or due to Rack::Timeout), app won't end
|
1415
|
+
up in perpetual crash state for being inconsistent with PostgreSQL.
|
1622
1416
|
|
1623
|
-
*
|
1417
|
+
*wbharding*, *Martin Tepper*
|
1624
1418
|
|
1625
|
-
|
1419
|
+
* Add ability to apply `scoping` to `all_queries`.
|
1626
1420
|
|
1627
|
-
|
1421
|
+
Some applications may want to use the `scoping` method but previously it only
|
1422
|
+
worked on certain types of queries. This change allows the `scoping` method to apply
|
1423
|
+
to all queries for a model in a block.
|
1628
1424
|
|
1629
|
-
|
1425
|
+
```ruby
|
1426
|
+
Post.where(blog_id: post.blog_id).scoping(all_queries: true) do
|
1427
|
+
post.update(title: "a post title") # adds `posts.blog_id = 1` to the query
|
1428
|
+
end
|
1429
|
+
```
|
1630
1430
|
|
1631
|
-
*Eileen M. Uchitelle
|
1431
|
+
*Eileen M. Uchitelle*
|
1632
1432
|
|
1633
|
-
*
|
1433
|
+
* `ActiveRecord::Calculations.calculate` called with `:average`
|
1434
|
+
(aliased as `ActiveRecord::Calculations.average`) will now use column-based
|
1435
|
+
type casting. This means that floating-point number columns will now be
|
1436
|
+
aggregated as `Float` and decimal columns will be aggregated as `BigDecimal`.
|
1634
1437
|
|
1635
|
-
|
1438
|
+
Integers are handled as a special case returning `BigDecimal` always
|
1439
|
+
(this was the case before already).
|
1636
1440
|
|
1637
|
-
|
1441
|
+
```ruby
|
1442
|
+
# With the following schema:
|
1443
|
+
create_table "measurements" do |t|
|
1444
|
+
t.float "temperature"
|
1445
|
+
end
|
1638
1446
|
|
1639
|
-
|
1447
|
+
# Before:
|
1448
|
+
Measurement.average(:temperature).class
|
1449
|
+
# => BigDecimal
|
1640
1450
|
|
1641
|
-
|
1451
|
+
# After:
|
1452
|
+
Measurement.average(:temperature).class
|
1453
|
+
# => Float
|
1454
|
+
```
|
1642
1455
|
|
1643
|
-
|
1456
|
+
Before this change, Rails just called `to_d` on average aggregates from the
|
1457
|
+
database adapter. This is not the case anymore. If you relied on that kind
|
1458
|
+
of magic, you now need to register your own `ActiveRecord::Type`
|
1459
|
+
(see `ActiveRecord::Attributes::ClassMethods` for documentation).
|
1644
1460
|
|
1645
|
-
*
|
1461
|
+
*Josua Schmid*
|
1646
1462
|
|
1647
|
-
|
1463
|
+
* PostgreSQL: introduce `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`.
|
1648
1464
|
|
1649
|
-
|
1465
|
+
This setting controls what native type Active Record should use when you call `datetime` in
|
1466
|
+
a migration or schema. It takes a symbol which must correspond to one of the configured
|
1467
|
+
`NATIVE_DATABASE_TYPES`. The default is `:timestamp`, meaning `t.datetime` in a migration
|
1468
|
+
will create a "timestamp without time zone" column. To use "timestamp with time zone",
|
1469
|
+
change this to `:timestamptz` in an initializer.
|
1650
1470
|
|
1651
|
-
|
1471
|
+
You should run `bin/rails db:migrate` to rebuild your schema.rb if you change this.
|
1652
1472
|
|
1653
|
-
*
|
1473
|
+
*Alex Ghiculescu*
|
1654
1474
|
|
1655
|
-
|
1475
|
+
* PostgreSQL: handle `timestamp with time zone` columns correctly in `schema.rb`.
|
1656
1476
|
|
1657
|
-
|
1477
|
+
Previously they dumped as `t.datetime :column_name`, now they dump as `t.timestamptz :column_name`,
|
1478
|
+
and are created as `timestamptz` columns when the schema is loaded.
|
1658
1479
|
|
1659
|
-
*
|
1480
|
+
*Alex Ghiculescu*
|
1660
1481
|
|
1661
|
-
*
|
1662
|
-
|
1482
|
+
* Removing trailing whitespace when matching columns in
|
1483
|
+
`ActiveRecord::Sanitization.disallow_raw_sql!`.
|
1663
1484
|
|
1664
|
-
|
1485
|
+
*Gannon McGibbon*, *Adrian Hirt*
|
1665
1486
|
|
1666
|
-
|
1667
|
-
has_secure_token :auth_token
|
1668
|
-
```
|
1487
|
+
* Expose a way for applications to set a `primary_abstract_class`.
|
1669
1488
|
|
1670
|
-
|
1489
|
+
Multiple database applications that use a primary abstract class that is not
|
1490
|
+
named `ApplicationRecord` can now set a specific class to be the `primary_abstract_class`.
|
1671
1491
|
|
1672
1492
|
```ruby
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1493
|
+
class PrimaryApplicationRecord
|
1494
|
+
self.primary_abstract_class
|
1495
|
+
end
|
1676
1496
|
```
|
1677
1497
|
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1498
|
+
When an application boots it automatically connects to the primary or first database in the
|
1499
|
+
database configuration file. In a multiple database application that then call `connects_to`
|
1500
|
+
needs to know that the default connection is the same as the `ApplicationRecord` connection.
|
1501
|
+
However, some applications have a differently named `ApplicationRecord`. This prevents Active
|
1502
|
+
Record from opening duplicate connections to the same database.
|
1681
1503
|
|
1682
|
-
*Eileen Uchitelle*, *John Crepezzi*
|
1504
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1683
1505
|
|
1684
|
-
*
|
1506
|
+
* Support hash config for `structure_dump_flags` and `structure_load_flags` flags.
|
1507
|
+
Now that Active Record supports multiple databases configuration,
|
1508
|
+
we need a way to pass specific flags for dump/load databases since
|
1509
|
+
the options are not the same for different adapters.
|
1510
|
+
We can use in the original way:
|
1685
1511
|
|
1686
|
-
|
1512
|
+
```ruby
|
1513
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-defaults', '--skip-add-drop-table']
|
1514
|
+
# or
|
1515
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table'
|
1516
|
+
```
|
1687
1517
|
|
1688
|
-
|
1518
|
+
And also use it passing a hash, with one or more keys, where the key
|
1519
|
+
is the adapter
|
1689
1520
|
|
1690
|
-
|
1521
|
+
```ruby
|
1522
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
|
1523
|
+
mysql2: ['--no-defaults', '--skip-add-drop-table'],
|
1524
|
+
postgres: '--no-tablespaces'
|
1525
|
+
}
|
1526
|
+
```
|
1691
1527
|
|
1692
|
-
|
1528
|
+
*Gustavo Gonzalez*
|
1693
1529
|
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1530
|
+
* Connection specification now passes the "url" key as a configuration for the
|
1531
|
+
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
1532
|
+
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
1533
|
+
are assumed to be adapter specification urls.
|
1698
1534
|
|
1699
|
-
|
1535
|
+
Fixes #41137.
|
1700
1536
|
|
1701
|
-
|
1537
|
+
*Jonathan Bracy*
|
1702
1538
|
|
1703
|
-
|
1539
|
+
* Allow to opt-out of `strict_loading` mode on a per-record base.
|
1704
1540
|
|
1705
|
-
|
1541
|
+
This is useful when strict loading is enabled application wide or on a
|
1542
|
+
model level.
|
1706
1543
|
|
1707
|
-
|
1544
|
+
```ruby
|
1545
|
+
class User < ApplicationRecord
|
1546
|
+
has_many :bookmarks
|
1547
|
+
has_many :articles, strict_loading: true
|
1548
|
+
end
|
1708
1549
|
|
1709
|
-
|
1550
|
+
user = User.first
|
1551
|
+
user.articles # => ActiveRecord::StrictLoadingViolationError
|
1552
|
+
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
1710
1553
|
|
1711
|
-
|
1554
|
+
user.strict_loading!(true) # => true
|
1555
|
+
user.bookmarks # => ActiveRecord::StrictLoadingViolationError
|
1712
1556
|
|
1713
|
-
|
1557
|
+
user.strict_loading!(false) # => false
|
1558
|
+
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
1559
|
+
user.articles.strict_loading!(false) # => #<ActiveRecord::Associations::CollectionProxy>
|
1560
|
+
```
|
1714
1561
|
|
1715
|
-
|
1562
|
+
*Ayrton De Craene*
|
1716
1563
|
|
1717
|
-
|
1564
|
+
* Add `FinderMethods#sole` and `#find_sole_by` to find and assert the
|
1565
|
+
presence of exactly one record.
|
1718
1566
|
|
1719
|
-
|
1567
|
+
Used when you need a single row, but also want to assert that there aren't
|
1568
|
+
multiple rows matching the condition; especially for when database
|
1569
|
+
constraints aren't enough or are impractical.
|
1720
1570
|
|
1721
|
-
|
1571
|
+
```ruby
|
1572
|
+
Product.where(["price = %?", price]).sole
|
1573
|
+
# => ActiveRecord::RecordNotFound (if no Product with given price)
|
1574
|
+
# => #<Product ...> (if one Product with given price)
|
1575
|
+
# => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
|
1722
1576
|
|
1723
|
-
|
1577
|
+
user.api_keys.find_sole_by(key: key)
|
1578
|
+
# as above
|
1579
|
+
```
|
1724
1580
|
|
1725
|
-
*
|
1581
|
+
*Asherah Connor*
|
1726
1582
|
|
1727
|
-
|
1583
|
+
* Makes `ActiveRecord::AttributeMethods::Query` respect the getter overrides defined in the model.
|
1728
1584
|
|
1729
|
-
|
1585
|
+
Before:
|
1730
1586
|
|
1731
|
-
|
1587
|
+
```ruby
|
1588
|
+
class User
|
1589
|
+
def admin
|
1590
|
+
false # Overriding the getter to always return false
|
1591
|
+
end
|
1592
|
+
end
|
1732
1593
|
|
1733
|
-
|
1594
|
+
user = User.first
|
1595
|
+
user.update(admin: true)
|
1734
1596
|
|
1735
|
-
|
1597
|
+
user.admin # false (as expected, due to the getter overwrite)
|
1598
|
+
user.admin? # true (not expected, returned the DB column value)
|
1599
|
+
```
|
1736
1600
|
|
1737
|
-
|
1601
|
+
After this commit, `user.admin?` above returns false, as expected.
|
1738
1602
|
|
1739
|
-
|
1603
|
+
Fixes #40771.
|
1740
1604
|
|
1741
|
-
*
|
1605
|
+
*Felipe*
|
1742
1606
|
|
1743
|
-
|
1607
|
+
* Allow delegated_type to be specified primary_key and foreign_key.
|
1744
1608
|
|
1745
|
-
|
1609
|
+
Since delegated_type assumes that the foreign_key ends with `_id`,
|
1610
|
+
`singular_id` defined by it does not work when the foreign_key does
|
1611
|
+
not end with `id`. This change fixes it by taking into account
|
1612
|
+
`primary_key` and `foreign_key` in the options.
|
1746
1613
|
|
1747
|
-
*
|
1614
|
+
*Ryota Egusa*
|
1748
1615
|
|
1749
|
-
*
|
1616
|
+
* Expose an `invert_where` method that will invert all scope conditions.
|
1750
1617
|
|
1751
|
-
|
1618
|
+
```ruby
|
1619
|
+
class User
|
1620
|
+
scope :active, -> { where(accepted: true, locked: false) }
|
1621
|
+
end
|
1752
1622
|
|
1753
|
-
|
1623
|
+
User.active
|
1624
|
+
# ... WHERE `accepted` = 1 AND `locked` = 0
|
1754
1625
|
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1626
|
+
User.active.invert_where
|
1627
|
+
# ... WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
1628
|
+
```
|
1758
1629
|
|
1759
|
-
*
|
1630
|
+
*Kevin Deisz*
|
1760
1631
|
|
1761
|
-
*
|
1632
|
+
* Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
|
1762
1633
|
|
1763
|
-
|
1634
|
+
Previously, passing `false` would trigger the option validation logic
|
1635
|
+
to throw an error saying :polymorphic would not be a valid option.
|
1764
1636
|
|
1765
|
-
*
|
1637
|
+
*glaszig*
|
1766
1638
|
|
1767
|
-
|
1639
|
+
* Remove deprecated `database` kwarg from `connected_to`.
|
1768
1640
|
|
1769
|
-
*
|
1641
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1770
1642
|
|
1771
|
-
|
1643
|
+
* Allow adding nonnamed expression indexes to be revertible.
|
1772
1644
|
|
1773
|
-
|
1645
|
+
Previously, the following code would raise an error, when executed while rolling back,
|
1646
|
+
and the index name should be specified explicitly. Now, the index name is inferred
|
1647
|
+
automatically.
|
1774
1648
|
|
1775
|
-
|
1649
|
+
```ruby
|
1650
|
+
add_index(:items, "to_tsvector('english', description)")
|
1651
|
+
```
|
1776
1652
|
|
1777
|
-
|
1653
|
+
Fixes #40732.
|
1778
1654
|
|
1779
|
-
|
1655
|
+
*fatkodima*
|
1780
1656
|
|
1781
|
-
|
1657
|
+
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
1782
1658
|
|
1783
|
-
|
1659
|
+
Fixes #39065.
|
1784
1660
|
|
1785
|
-
|
1661
|
+
*Alex Ghiculescu*
|
1786
1662
|
|
1787
|
-
|
1663
|
+
* Add option to run `default_scope` on all queries.
|
1788
1664
|
|
1789
|
-
|
1665
|
+
Previously, a `default_scope` would only run on select or insert queries. In some cases, like non-Rails tenant sharding solutions, it may be desirable to run `default_scope` on all queries in order to ensure queries are including a foreign key for the shard (i.e. `blog_id`).
|
1790
1666
|
|
1791
|
-
|
1667
|
+
Now applications can add an option to run on all queries including select, insert, delete, and update by adding an `all_queries` option to the default scope definition.
|
1792
1668
|
|
1793
|
-
|
1669
|
+
```ruby
|
1670
|
+
class Article < ApplicationRecord
|
1671
|
+
default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
|
1672
|
+
end
|
1673
|
+
```
|
1794
1674
|
|
1795
|
-
*
|
1675
|
+
*Eileen M. Uchitelle*
|
1796
1676
|
|
1797
|
-
*
|
1677
|
+
* Add `where.associated` to check for the presence of an association.
|
1798
1678
|
|
1799
|
-
|
1679
|
+
```ruby
|
1680
|
+
# Before:
|
1681
|
+
account.users.joins(:contact).where.not(contact_id: nil)
|
1800
1682
|
|
1801
|
-
|
1683
|
+
# After:
|
1684
|
+
account.users.where.associated(:contact)
|
1685
|
+
```
|
1802
1686
|
|
1803
|
-
|
1687
|
+
Also mirrors `where.missing`.
|
1804
1688
|
|
1805
|
-
*
|
1689
|
+
*Kasper Timm Hansen*
|
1806
1690
|
|
1807
|
-
* Allow
|
1691
|
+
* Allow constructors (`build_association` and `create_association`) on
|
1692
|
+
`has_one :through` associations.
|
1808
1693
|
|
1809
|
-
*
|
1694
|
+
*Santiago Perez Perret*
|
1810
1695
|
|
1811
1696
|
|
1812
|
-
Please check [6-
|
1697
|
+
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activerecord/CHANGELOG.md) for previous changes.
|