activerecord 7.0.8.7 → 7.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +631 -1944
- data/MIT-LICENSE +1 -1
- data/README.rdoc +29 -29
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +35 -12
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +23 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +22 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +26 -14
- data/lib/active_record/associations/collection_proxy.rb +29 -11
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +21 -14
- data/lib/active_record/associations/has_many_through_association.rb +17 -7
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +33 -8
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +7 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +354 -485
- data/lib/active_record/attribute_assignment.rb +0 -4
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +53 -35
- data/lib/active_record/attribute_methods/primary_key.rb +45 -25
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +8 -7
- data/lib/active_record/attribute_methods/serialization.rb +131 -32
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +148 -33
- data/lib/active_record/attributes.rb +64 -50
- data/lib/active_record/autosave_association.rb +69 -37
- data/lib/active_record/base.rb +9 -5
- data/lib/active_record/callbacks.rb +11 -25
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +323 -88
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +217 -63
- data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +307 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +510 -111
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +278 -125
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
- data/lib/active_record/connection_adapters/mysql/quoting.rb +53 -54
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
- data/lib/active_record/connection_adapters/pool_config.rb +20 -10
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +370 -63
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +367 -201
- data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +50 -8
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -110
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +124 -1
- data/lib/active_record/connection_handling.rb +96 -104
- data/lib/active_record/core.rb +251 -176
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +26 -5
- data/lib/active_record/database_configurations/hash_config.rb +52 -34
- data/lib/active_record/database_configurations/url_config.rb +37 -12
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +39 -10
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +45 -21
- data/lib/active_record/encryption/encrypted_attribute_type.rb +47 -12
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +6 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +129 -28
- data/lib/active_record/errors.rb +151 -31
- data/lib/active_record/explain.rb +21 -12
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +167 -97
- data/lib/active_record/future_result.rb +47 -8
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +34 -18
- data/lib/active_record/insert_all.rb +72 -22
- data/lib/active_record/integration.rb +11 -8
- data/lib/active_record/internal_metadata.rb +124 -20
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +18 -22
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +106 -8
- data/lib/active_record/migration/compatibility.rb +147 -5
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +234 -117
- data/lib/active_record/model_schema.rb +90 -102
- data/lib/active_record/nested_attributes.rb +48 -11
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +168 -339
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -25
- data/lib/active_record/query_logs.rb +92 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +33 -8
- data/lib/active_record/railtie.rb +129 -85
- data/lib/active_record/railties/controller_runtime.rb +22 -7
- data/lib/active_record/railties/databases.rake +145 -154
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +267 -69
- data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +250 -93
- data/lib/active_record/relation/delegation.rb +30 -19
- data/lib/active_record/relation/finder_methods.rb +93 -18
- data/lib/active_record/relation/merger.rb +6 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +18 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +28 -16
- data/lib/active_record/relation/query_attribute.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +576 -107
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +5 -4
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +580 -90
- data/lib/active_record/result.rb +49 -48
- data/lib/active_record/runtime_registry.rb +63 -1
- data/lib/active_record/sanitization.rb +70 -25
- data/lib/active_record/schema.rb +8 -7
- data/lib/active_record/schema_dumper.rb +63 -14
- data/lib/active_record/schema_migration.rb +75 -24
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +3 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +27 -6
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +190 -118
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_fixtures.rb +170 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +31 -17
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +12 -7
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +106 -24
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +61 -11
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +247 -33
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +115 -5
- data/lib/arel/nodes/sql_literal.rb +13 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +6 -2
- data/lib/arel/predications.rb +3 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/table.rb +9 -5
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +17 -5
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +112 -34
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +21 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +54 -12
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
data/CHANGELOG.md
CHANGED
@@ -1,2411 +1,1098 @@
|
|
1
|
-
## Rails 7.
|
1
|
+
## Rails 7.2.2.1 (December 10, 2024) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails 7.
|
7
|
-
|
8
|
-
* No changes.
|
9
|
-
|
10
|
-
|
11
|
-
## Rails 7.0.8.5 (October 15, 2024) ##
|
12
|
-
|
13
|
-
* No changes.
|
14
|
-
|
15
|
-
|
16
|
-
## Rails 7.0.8.4 (June 04, 2024) ##
|
17
|
-
|
18
|
-
* No changes.
|
6
|
+
## Rails 7.2.2 (October 30, 2024) ##
|
19
7
|
|
8
|
+
* Fix support for `query_cache: false` in `database.yml`.
|
20
9
|
|
21
|
-
|
10
|
+
`query_cache: false` would no longer entirely disable the Active Record query cache.
|
22
11
|
|
23
|
-
*
|
12
|
+
*zzak*
|
24
13
|
|
14
|
+
* Set `.attributes_for_inspect` to `:all` by default.
|
25
15
|
|
26
|
-
|
16
|
+
For new applications it is set to `[:id]` in config/environment/production.rb.
|
27
17
|
|
28
|
-
|
18
|
+
In the console all the attributes are always shown.
|
29
19
|
|
20
|
+
*Andrew Novoselac*
|
30
21
|
|
31
|
-
|
22
|
+
* `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
|
32
23
|
|
33
|
-
*
|
24
|
+
*Kazuma Watanabe*
|
34
25
|
|
26
|
+
* Fix marshalling of unsaved associated records in 7.1 format.
|
35
27
|
|
36
|
-
|
28
|
+
The 7.1 format would only marshal associated records if the association was loaded.
|
29
|
+
But associations that would only contain unsaved records would be skipped.
|
37
30
|
|
38
|
-
*
|
39
|
-
using 7.0+ Migrations and SQLite.
|
31
|
+
*Jean Boussier*
|
40
32
|
|
41
|
-
|
33
|
+
* Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
|
42
34
|
|
43
|
-
*
|
35
|
+
*David Stosik*
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
|
37
|
+
* Allow to save records with polymorphic join tables that have `inverse_of`
|
38
|
+
specified.
|
48
39
|
|
49
|
-
|
40
|
+
*Markus Doits*
|
50
41
|
|
51
|
-
|
52
|
-
```ruby
|
53
|
-
Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
|
54
|
-
```
|
42
|
+
* Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
|
55
43
|
|
56
|
-
|
44
|
+
*Joshua Young*
|
57
45
|
|
58
|
-
|
46
|
+
* Fix `dependent: :destroy` for bi-directional has one through association.
|
59
47
|
|
60
|
-
|
48
|
+
Fixes #50948.
|
61
49
|
|
62
50
|
```ruby
|
63
|
-
class
|
64
|
-
|
51
|
+
class Left < ActiveRecord::Base
|
52
|
+
has_one :middle, dependent: :destroy
|
53
|
+
has_one :right, through: :middle
|
65
54
|
end
|
66
55
|
|
67
|
-
|
68
|
-
|
69
|
-
belongs_to :
|
70
|
-
|
71
|
-
validate :request_type, presence: true
|
56
|
+
class Middle < ActiveRecord::Base
|
57
|
+
belongs_to :left, dependent: :destroy
|
58
|
+
belongs_to :right, dependent: :destroy
|
72
59
|
end
|
73
60
|
|
74
|
-
class
|
75
|
-
|
61
|
+
class Right < ActiveRecord::Base
|
62
|
+
has_one :middle, dependent: :destroy
|
63
|
+
has_one :left, through: :middle
|
76
64
|
end
|
77
65
|
```
|
66
|
+
In the above example `left.destroy` wouldn't destroy its associated `Right`
|
67
|
+
record.
|
78
68
|
|
79
|
-
|
80
|
-
|
81
|
-
```
|
82
|
-
table_metadata.rb:22:in `has_column?': undefined method `key?' for nil:NilClass (NoMethodError)
|
83
|
-
```
|
69
|
+
*Andy Stewart*
|
84
70
|
|
85
|
-
|
71
|
+
* Properly handle lazily pinned connection pools.
|
86
72
|
|
87
|
-
|
73
|
+
Fixes #53147.
|
88
74
|
|
89
|
-
|
75
|
+
When using transactional fixtures with system tests to similar tools
|
76
|
+
such as capybara, it could happen that a connection end up pinned by the
|
77
|
+
server thread rather than the test thread, causing
|
78
|
+
`"Cannot expire connection, it is owned by a different thread"` errors.
|
90
79
|
|
91
|
-
*
|
80
|
+
*Jean Boussier*
|
92
81
|
|
93
|
-
|
82
|
+
* Fix `ActiveRecord::Base.with` to accept more than two sub queries.
|
94
83
|
|
95
|
-
|
84
|
+
Fixes #53110.
|
96
85
|
|
97
|
-
|
86
|
+
```ruby
|
87
|
+
User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
|
88
|
+
undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
|
89
|
+
```
|
98
90
|
|
91
|
+
The above now works as expected.
|
99
92
|
|
100
|
-
|
93
|
+
*fatkodima*
|
101
94
|
|
102
|
-
*
|
95
|
+
* Properly release pinned connections with non joinable connections.
|
103
96
|
|
97
|
+
Fixes #52973
|
104
98
|
|
105
|
-
|
99
|
+
When running system tests with transactional fixtures on, it could happen that
|
100
|
+
the connection leased by the Puma thread wouldn't be properly released back to the pool,
|
101
|
+
causing "Cannot expire connection, it is owned by a different thread" errors in later tests.
|
106
102
|
|
107
|
-
*
|
103
|
+
*Jean Boussier*
|
108
104
|
|
109
|
-
|
105
|
+
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
110
106
|
|
111
|
-
|
107
|
+
Fixes #52742
|
112
108
|
|
113
|
-
*
|
109
|
+
*Ryota Kitazawa*, *Takayuki Nagatomi*
|
114
110
|
|
115
|
-
* Fix
|
111
|
+
* Fix an issue where `.left_outer_joins` used with multiple associations that have
|
112
|
+
the same child association but different parents does not join all parents.
|
116
113
|
|
117
|
-
|
114
|
+
Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
|
118
115
|
|
119
|
-
|
116
|
+
Now it will correctly join both parents.
|
120
117
|
|
121
|
-
|
118
|
+
Fixes #41498.
|
122
119
|
|
123
|
-
*
|
124
|
-
behavior of `Enumerable#in_order_of`.
|
120
|
+
*Garrett Blehm*
|
125
121
|
|
126
|
-
|
127
|
-
with `nil` titles, the same as `Post.all.to_a.in_order_of(:title, [nil, "foo"])`.
|
122
|
+
* Ensure `ActiveRecord::Encryption.config` is always ready before access.
|
128
123
|
|
129
|
-
|
124
|
+
Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
|
125
|
+
was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
|
126
|
+
`ActiveRecord::Base` was loaded would give incorrect results.
|
130
127
|
|
131
|
-
|
128
|
+
`ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
|
129
|
+
soon as needed.
|
132
130
|
|
133
|
-
|
134
|
-
|
131
|
+
When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
|
132
|
+
`ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
|
133
|
+
before any use of `ActiveRecord::Base`.
|
135
134
|
|
136
|
-
*
|
135
|
+
*Maxime Réty*
|
137
136
|
|
138
|
-
*
|
137
|
+
* Add `TimeZoneConverter#==` method, so objects will be properly compared by
|
138
|
+
their type, scale, limit & precision.
|
139
139
|
|
140
|
-
|
141
|
-
Now, any UPDATE or DELETE to a record is considered a change, and will result in `#previously_new_record?`
|
142
|
-
returning false.
|
140
|
+
Address #52699.
|
143
141
|
|
144
|
-
*
|
142
|
+
*Ruy Rocha*
|
145
143
|
|
146
|
-
* Revert breaking changes to `has_one` relationship deleting the old record before the new one is validated.
|
147
144
|
|
148
|
-
|
145
|
+
## Rails 7.2.1.2 (October 23, 2024) ##
|
149
146
|
|
150
|
-
*
|
147
|
+
* No changes.
|
151
148
|
|
152
|
-
As of `7.0.5`, query arguments were deep duped to avoid mutations impacting
|
153
|
-
the query cache, but this had the adverse effect to clearing the primary key when
|
154
|
-
the query argument contained an `ActiveRecord::Base` instance.
|
155
149
|
|
156
|
-
|
150
|
+
## Rails 7.2.1.1 (October 15, 2024) ##
|
157
151
|
|
158
|
-
|
152
|
+
* No changes.
|
159
153
|
|
160
154
|
|
161
|
-
## Rails 7.
|
155
|
+
## Rails 7.2.1 (August 22, 2024) ##
|
162
156
|
|
163
|
-
* Fix
|
157
|
+
* Fix detection for `enum` columns with parallelized tests and PostgreSQL.
|
164
158
|
|
165
|
-
*
|
159
|
+
*Rafael Mendonça França*
|
166
160
|
|
167
|
-
*
|
161
|
+
* Allow to eager load nested nil associations.
|
168
162
|
|
169
|
-
*
|
163
|
+
*fatkodima*
|
170
164
|
|
171
|
-
*
|
165
|
+
* Fix swallowing ignore order warning when batching using `BatchEnumerator`.
|
172
166
|
|
173
167
|
*fatkodima*
|
174
168
|
|
175
|
-
* Fix
|
169
|
+
* Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
|
176
170
|
|
177
171
|
*Jean Boussier*
|
178
172
|
|
179
|
-
*
|
180
|
-
|
181
|
-
Before:
|
182
|
-
```ruby
|
183
|
-
Treasure.where(price_estimates: PriceEstimate.all)
|
184
|
-
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
|
185
|
-
```
|
173
|
+
* Restore inferred association class with the same modularized name.
|
186
174
|
|
187
|
-
|
188
|
-
```ruby
|
189
|
-
Treasure.where(price_estimates: PriceEstimate.all)
|
190
|
-
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
|
191
|
-
```
|
175
|
+
*Justin Ko*
|
192
176
|
|
193
|
-
|
177
|
+
* Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
|
194
178
|
|
195
|
-
*
|
179
|
+
*Jean Boussier*
|
196
180
|
|
197
|
-
|
181
|
+
* Check invalid `enum` options for the new syntax.
|
198
182
|
|
199
|
-
|
183
|
+
The options using `_` prefix in the old syntax are invalid in the new syntax.
|
200
184
|
|
201
|
-
*
|
185
|
+
*Rafael Mendonça França*
|
202
186
|
|
203
|
-
*
|
187
|
+
* Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
|
188
|
+
actual cast type.
|
204
189
|
|
205
|
-
*
|
190
|
+
*Vasiliy Ermolovich*
|
206
191
|
|
207
|
-
*
|
192
|
+
* Fix `create_table` with `:auto_increment` option for MySQL adapter.
|
208
193
|
|
209
194
|
*fatkodima*
|
210
195
|
|
211
|
-
* Fix `Enumerable#in_order_of` to only flatten first level to preserve nesting.
|
212
196
|
|
213
|
-
|
197
|
+
## Rails 7.2.0 (August 09, 2024) ##
|
214
198
|
|
199
|
+
* Handle commas in Sqlite3 default function definitions.
|
215
200
|
|
216
|
-
|
201
|
+
*Stephen Margheim*
|
217
202
|
|
218
|
-
*
|
203
|
+
* Fixes `validates_associated` raising an exception when configured with a
|
204
|
+
singular association and having `index_nested_attribute_errors` enabled.
|
219
205
|
|
220
|
-
|
206
|
+
*Martin Spickermann*
|
221
207
|
|
222
|
-
*
|
208
|
+
* The constant `ActiveRecord::ImmutableRelation` has been deprecated because
|
209
|
+
we want to reserve that name for a stronger sense of "immutable relation".
|
210
|
+
Please use `ActiveRecord::UnmodifiableRelation` instead.
|
223
211
|
|
224
|
-
*
|
212
|
+
*Xavier Noria*
|
225
213
|
|
226
|
-
*
|
214
|
+
* Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
|
215
|
+
`DatabaseConfig`.
|
227
216
|
|
228
|
-
*
|
217
|
+
*Hartley McGuire*
|
218
|
+
|
219
|
+
* Fixed a memory performance issue in Active Record attribute methods definition.
|
229
220
|
|
230
|
-
*
|
221
|
+
*Jean Boussier*
|
231
222
|
|
232
|
-
|
223
|
+
* Define the new Active Support notification event `start_transaction.active_record`.
|
233
224
|
|
234
|
-
|
225
|
+
This event is fired when database transactions or savepoints start, and
|
226
|
+
complements `transaction.active_record`, which is emitted when they finish.
|
235
227
|
|
236
|
-
|
228
|
+
The payload has the transaction (`:transaction`) and the connection (`:connection`).
|
237
229
|
|
238
|
-
*
|
230
|
+
*Xavier Noria*
|
239
231
|
|
240
|
-
|
232
|
+
* Fix an issue where the IDs reader method did not return expected results
|
233
|
+
for preloaded associations in models using composite primary keys.
|
241
234
|
|
242
|
-
*
|
235
|
+
*Jay Ang*
|
243
236
|
|
244
|
-
|
237
|
+
* The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
|
245
238
|
|
246
|
-
*
|
239
|
+
*Xavier Noria*
|
247
240
|
|
248
|
-
|
241
|
+
* The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
|
249
242
|
|
250
|
-
*
|
243
|
+
*Xavier Noria*
|
251
244
|
|
252
|
-
|
245
|
+
* Define `ActiveRecord::Transaction#uuid`, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.
|
253
246
|
|
254
|
-
*
|
247
|
+
*Xavier Noria*
|
255
248
|
|
256
|
-
|
249
|
+
* Fix inference of association model on nested models with the same demodularized name.
|
257
250
|
|
258
|
-
|
251
|
+
E.g. with the following setup:
|
259
252
|
|
260
|
-
|
253
|
+
```ruby
|
254
|
+
class Nested::Post < ApplicationRecord
|
255
|
+
has_one :post, through: :other
|
256
|
+
end
|
257
|
+
```
|
261
258
|
|
262
|
-
|
259
|
+
Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
|
263
260
|
|
264
261
|
*Joshua Young*
|
265
262
|
|
266
|
-
*
|
263
|
+
* PostgreSQL `Cidr#change?` detects the address prefix change.
|
267
264
|
|
268
|
-
*
|
265
|
+
*Taketo Takashima*
|
269
266
|
|
270
|
-
*
|
267
|
+
* Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
|
271
268
|
|
272
|
-
|
269
|
+
Previously, it always returned `nil`.
|
273
270
|
|
274
|
-
*
|
271
|
+
*fatkodima*
|
275
272
|
|
276
|
-
|
273
|
+
* Support `touch_all` in batches.
|
277
274
|
|
278
|
-
|
275
|
+
```ruby
|
276
|
+
Post.in_batches.touch_all
|
277
|
+
```
|
279
278
|
|
280
279
|
*fatkodima*
|
281
280
|
|
282
|
-
*
|
281
|
+
* Add support for `:if_not_exists` and `:force` options to `create_schema`.
|
283
282
|
|
284
283
|
*fatkodima*
|
285
284
|
|
286
|
-
* Fix
|
285
|
+
* Fix `index_errors` having incorrect index in association validation errors.
|
287
286
|
|
288
|
-
*
|
287
|
+
*lulalala*
|
289
288
|
|
290
|
-
*
|
289
|
+
* Add `index_errors: :nested_attributes_order` mode.
|
291
290
|
|
292
|
-
|
291
|
+
This indexes the association validation errors based on the order received by nested attributes setter, and respects the `reject_if` configuration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.
|
293
292
|
|
294
|
-
*
|
293
|
+
*lulalala*
|
295
294
|
|
296
|
-
|
295
|
+
* Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
|
297
296
|
|
298
|
-
*
|
297
|
+
*Joé Dupuis*
|
299
298
|
|
300
|
-
|
301
|
-
default precision as regular datetime columns, resulting in the following
|
302
|
-
being erroneously equivalent:
|
299
|
+
* Association option `query_constraints` is deprecated in favor of `foreign_key`.
|
303
300
|
|
304
|
-
|
305
|
-
t.virtual :name, type: datetime, precision: nil, as: "expression"
|
301
|
+
*Nikita Vasilevsky*
|
306
302
|
|
307
|
-
|
308
|
-
datetime column default precisions match.
|
303
|
+
* Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
|
309
304
|
|
310
|
-
|
305
|
+
This cuts ~10s from the test run of HEY when run by 24 processes against the 178 tables, since ~4,000 table truncates can then be skipped.
|
311
306
|
|
312
|
-
*
|
307
|
+
*DHH*
|
313
308
|
|
314
|
-
|
309
|
+
* Added support for recursive common table expressions.
|
315
310
|
|
311
|
+
```ruby
|
312
|
+
Post.with_recursive(
|
313
|
+
post_and_replies: [
|
314
|
+
Post.where(id: 42),
|
315
|
+
Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
|
316
|
+
]
|
317
|
+
)
|
318
|
+
```
|
316
319
|
|
317
|
-
|
320
|
+
Generates the following SQL:
|
318
321
|
|
319
|
-
|
322
|
+
```sql
|
323
|
+
WITH RECURSIVE "post_and_replies" AS (
|
324
|
+
(SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
|
325
|
+
UNION ALL
|
326
|
+
(SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
|
327
|
+
)
|
328
|
+
SELECT "posts".* FROM "posts"
|
329
|
+
```
|
320
330
|
|
331
|
+
*ClearlyClaire*
|
321
332
|
|
322
|
-
|
333
|
+
* `validate_constraint` can be called in a `change_table` block.
|
323
334
|
|
324
|
-
|
335
|
+
ex:
|
336
|
+
```ruby
|
337
|
+
change_table :products do |t|
|
338
|
+
t.check_constraint "price > discounted_price", name: "price_check", validate: false
|
339
|
+
t.validate_check_constraint "price_check"
|
340
|
+
end
|
341
|
+
```
|
325
342
|
|
343
|
+
*Cody Cutrer*
|
326
344
|
|
327
|
-
|
345
|
+
* `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
|
328
346
|
|
329
|
-
|
347
|
+
Ex:
|
348
|
+
```ruby
|
349
|
+
ActiveRecord::Base.connection
|
350
|
+
.select_value("select '2024-01-01'::date").class #=> Date
|
351
|
+
```
|
330
352
|
|
331
|
-
|
332
|
-
attempting sanitization. That sanitization could be bypassed with
|
333
|
-
carefully crafted input.
|
353
|
+
*Joé Dupuis*
|
334
354
|
|
335
|
-
|
336
|
-
occurrences of "/*" or "*/" with "/ *" or "* /". It also performs a
|
337
|
-
first pass to remove one surrounding comment to avoid compatibility
|
338
|
-
issues for users relying on the existing removal.
|
355
|
+
* Strict loading using `:n_plus_one_only` does not eagerly load child associations.
|
339
356
|
|
340
|
-
|
341
|
-
|
357
|
+
With this change, child associations are no longer eagerly loaded, to
|
358
|
+
match intended behavior and to prevent non-deterministic order issues caused
|
359
|
+
by calling methods like `first` or `last`. As `first` and `last` don't cause
|
360
|
+
an N+1 by themselves, calling child associations will no longer raise.
|
361
|
+
Fixes #49473.
|
342
362
|
|
343
|
-
|
363
|
+
Before:
|
344
364
|
|
345
|
-
|
365
|
+
```ruby
|
366
|
+
person = Person.find(1)
|
367
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
368
|
+
person.posts.first
|
369
|
+
# SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
|
370
|
+
person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
|
371
|
+
```
|
346
372
|
|
347
|
-
|
348
|
-
PostgreSQL will treat the column type as numeric. Comparing
|
349
|
-
integer values against numeric values can result in a slow
|
350
|
-
sequential scan.
|
373
|
+
After:
|
351
374
|
|
352
|
-
|
353
|
-
|
375
|
+
```ruby
|
376
|
+
person = Person.find(1)
|
377
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
378
|
+
person.posts.first # this is 1+1, not N+1
|
379
|
+
# SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
|
380
|
+
person.posts.first.firm # no longer raises
|
381
|
+
```
|
354
382
|
|
355
|
-
|
383
|
+
*Reid Lynch*
|
356
384
|
|
385
|
+
* Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
|
357
386
|
|
358
|
-
|
387
|
+
*Mike Dalessio*
|
359
388
|
|
360
|
-
*
|
389
|
+
* Allow `ActiveRecord::Base#pluck` to accept hash values.
|
361
390
|
|
362
|
-
|
391
|
+
```ruby
|
392
|
+
# Before
|
393
|
+
Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
|
363
394
|
|
364
|
-
|
395
|
+
# After
|
396
|
+
Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
|
397
|
+
```
|
365
398
|
|
366
|
-
|
367
|
-
which is wasteful and cause problem with YAML safe_load.
|
399
|
+
*fatkodima*
|
368
400
|
|
369
|
-
|
401
|
+
* Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
|
370
402
|
|
371
|
-
*
|
403
|
+
*Kevin McPhillips*
|
372
404
|
|
373
|
-
|
405
|
+
* `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
|
374
406
|
|
375
|
-
|
407
|
+
This allows to register callbacks on it.
|
376
408
|
|
377
409
|
```ruby
|
378
|
-
|
410
|
+
Article.transaction do |transaction|
|
411
|
+
article.update(published: true)
|
412
|
+
transaction.after_commit do
|
413
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
414
|
+
end
|
415
|
+
end
|
379
416
|
```
|
380
417
|
|
381
|
-
*
|
418
|
+
*Jean Boussier*
|
419
|
+
|
420
|
+
* Add `ActiveRecord::Base.current_transaction`.
|
382
421
|
|
383
|
-
|
422
|
+
Returns the current transaction, to allow registering callbacks on it.
|
384
423
|
|
385
424
|
```ruby
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
ActiveRecord::Base.time_zone_aware_types += [:tsrange]
|
390
|
-
# In the code times are properly converted to app time zone
|
391
|
-
Shop.create!(open_hours: [Time.current..8.hour.from_now])
|
425
|
+
Article.current_transaction.after_commit do
|
426
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
427
|
+
end
|
392
428
|
```
|
393
429
|
|
394
|
-
*
|
395
|
-
|
396
|
-
* Resolve issue where a relation cache_version could be left stale.
|
430
|
+
*Jean Boussier*
|
397
431
|
|
398
|
-
|
399
|
-
ivar. This led to a confusing situation where despite having the correct data the relation
|
400
|
-
still reported a stale cache_version.
|
432
|
+
* Add `ActiveRecord.after_all_transactions_commit` callback.
|
401
433
|
|
402
|
-
|
434
|
+
Useful for code that may run either inside or outside a transaction and needs
|
435
|
+
to perform work after the state changes have been properly persisted.
|
403
436
|
|
404
437
|
```ruby
|
405
|
-
|
406
|
-
|
438
|
+
def publish_article(article)
|
439
|
+
article.update(published: true)
|
440
|
+
ActiveRecord.after_all_transactions_commit do
|
441
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
442
|
+
end
|
443
|
+
end
|
444
|
+
```
|
407
445
|
|
408
|
-
|
446
|
+
In the above example, the block is either executed immediately if called outside
|
447
|
+
of a transaction, or called after the open transaction is committed.
|
409
448
|
|
410
|
-
|
411
|
-
developers.reset
|
412
|
-
developers.cache_version # Returns the current correct cache_version
|
413
|
-
```
|
449
|
+
If the transaction is rolled back, the block isn't called.
|
414
450
|
|
415
|
-
|
451
|
+
*Jean Boussier*
|
416
452
|
|
417
|
-
|
453
|
+
* Add the ability to ignore counter cache columns until they are backfilled.
|
418
454
|
|
419
|
-
|
455
|
+
Starting to use counter caches on existing large tables can be troublesome, because the column
|
456
|
+
values must be backfilled separately of the column addition (to not lock the table for too long)
|
457
|
+
and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
|
458
|
+
counter caches internally, can produce incorrect results). People usually use database triggers
|
459
|
+
or callbacks on child associations while backfilling before introducing a counter cache
|
460
|
+
configuration to the association.
|
420
461
|
|
421
|
-
|
422
|
-
a query but never use it.
|
462
|
+
Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
|
423
463
|
|
424
464
|
```ruby
|
425
|
-
|
426
|
-
|
465
|
+
class Comment < ApplicationRecord
|
466
|
+
belongs_to :post, counter_cache: { active: false }
|
467
|
+
end
|
427
468
|
```
|
428
469
|
|
429
|
-
|
430
|
-
|
470
|
+
While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
|
471
|
+
but get the results directly from the database. After the counter cache column is backfilled, simply
|
472
|
+
remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
|
473
|
+
mentioned methods.
|
431
474
|
|
432
|
-
*
|
433
|
-
|
434
|
-
* Fix eager loading for models without primary keys.
|
475
|
+
*fatkodima*
|
435
476
|
|
436
|
-
|
477
|
+
* Retry known idempotent SELECT queries on connection-related exceptions.
|
437
478
|
|
438
|
-
|
479
|
+
SELECT queries we construct by walking the Arel tree and / or with known model attributes
|
480
|
+
are idempotent and can safely be retried in the case of a connection error. Previously,
|
481
|
+
adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
|
482
|
+
when encountering a connection error mid-request.
|
439
483
|
|
440
|
-
|
441
|
-
way to dump a schema to both SQL and Ruby formats. You can now do this with
|
442
|
-
an environment variable. For example:
|
484
|
+
*Adrianna Chang*
|
443
485
|
|
444
|
-
|
445
|
-
SCHEMA_FORMAT=sql rake db:schema:dump
|
446
|
-
```
|
486
|
+
* Allow association's `foreign_key` to be composite.
|
447
487
|
|
448
|
-
|
488
|
+
`query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
|
489
|
+
Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
|
449
490
|
|
450
|
-
*
|
491
|
+
*Nikita Vasilevsky*
|
451
492
|
|
452
|
-
|
493
|
+
* Allow association's `primary_key` to be composite.
|
453
494
|
|
495
|
+
Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
|
496
|
+
Now it's possible to explicitly set it as composite on the association.
|
454
497
|
|
455
|
-
|
498
|
+
*Nikita Vasilevsky*
|
456
499
|
|
457
|
-
*
|
500
|
+
* Add `config.active_record.permanent_connection_checkout` setting.
|
458
501
|
|
459
|
-
|
460
|
-
follows:
|
502
|
+
Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
|
461
503
|
|
462
|
-
|
504
|
+
`ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
|
505
|
+
the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
|
506
|
+
is available connections.
|
463
507
|
|
464
|
-
|
465
|
-
|
466
|
-
the possible escalation vulnerability in place. Setting this option to true
|
467
|
-
is *not* recommended, but can aid in upgrading.
|
508
|
+
This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
|
509
|
+
migrate it to use `ActiveRecord::Base.with_connection` instead.
|
468
510
|
|
469
|
-
|
511
|
+
The default behavior remains unchanged, and there is currently no plans to change the default.
|
470
512
|
|
471
|
-
|
472
|
-
by default. This option allows you to specify classes deemed "safe" in your
|
473
|
-
application. For example, if your application uses Symbol and Time in
|
474
|
-
serialized data, you can add Symbol and Time to the allowed list as follows:
|
513
|
+
*Jean Boussier*
|
475
514
|
|
476
|
-
|
477
|
-
config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
|
478
|
-
```
|
515
|
+
* Add dirties option to uncached.
|
479
516
|
|
480
|
-
|
517
|
+
This adds a `dirties` option to `ActiveRecord::Base.uncached` and
|
518
|
+
`ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
|
481
519
|
|
520
|
+
When set to `true` (the default), writes will clear all query caches belonging to the current thread.
|
521
|
+
When set to `false`, writes to the affected connection pool will not clear any query cache.
|
482
522
|
|
483
|
-
|
523
|
+
This is needed by Solid Cache so that cache writes do not clear query caches.
|
484
524
|
|
485
|
-
*
|
486
|
-
methods in class objects that referenced reloadable constants. See
|
487
|
-
[#44125](https://github.com/rails/rails/issues/44125) for details.
|
525
|
+
*Donal McBreen*
|
488
526
|
|
489
|
-
|
527
|
+
* Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
|
490
528
|
|
491
|
-
|
529
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
530
|
+
connection will be held for the duration of the request or job.
|
492
531
|
|
493
|
-
|
494
|
-
|
495
|
-
added as string content when saving new records.
|
532
|
+
This deprecation is a soft deprecation, no warnings will be issued and there is no
|
533
|
+
current plan to remove the method.
|
496
534
|
|
497
|
-
*
|
535
|
+
*Jean Boussier*
|
498
536
|
|
499
|
-
*
|
537
|
+
* Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
|
500
538
|
|
501
|
-
|
539
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
540
|
+
connection will be held for the duration of the request or job.
|
502
541
|
|
503
|
-
*
|
542
|
+
*Jean Boussier*
|
504
543
|
|
505
|
-
|
506
|
-
comments in your structure dump, you can use:
|
544
|
+
* Expose a generic fixture accessor for fixture names that may conflict with Minitest.
|
507
545
|
|
508
546
|
```ruby
|
509
|
-
|
547
|
+
assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
548
|
+
assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
|
510
549
|
```
|
511
550
|
|
512
|
-
*
|
551
|
+
*Jean Boussier*
|
513
552
|
|
514
|
-
*
|
553
|
+
* Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
|
554
|
+
incorrect error message.
|
515
555
|
|
516
|
-
|
517
|
-
parameter, instead of just `name`. This prevents unintended filtering of parameters
|
518
|
-
with a matching name in other models.
|
556
|
+
This has been fixed to raise with a more appropriate error message.
|
519
557
|
|
520
|
-
*
|
558
|
+
*Joshua Young*
|
521
559
|
|
522
|
-
* Fix
|
560
|
+
* Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
|
523
561
|
|
524
|
-
|
562
|
+
This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
|
563
|
+
an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
|
525
564
|
|
526
|
-
*
|
565
|
+
*Joshua Young*
|
527
566
|
|
528
|
-
|
567
|
+
* Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
|
529
568
|
|
530
|
-
|
569
|
+
*Rafael Mendonça França*
|
531
570
|
|
532
|
-
*
|
571
|
+
* Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
|
533
572
|
|
573
|
+
*Rafael Mendonça França*
|
534
574
|
|
535
|
-
|
575
|
+
* Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
|
536
576
|
|
537
|
-
*
|
577
|
+
*Rafael Mendonça França*
|
538
578
|
|
579
|
+
* Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
|
539
580
|
|
540
|
-
|
581
|
+
*Rafael Mendonça França*
|
541
582
|
|
542
|
-
*
|
583
|
+
* Remove deprecated support to quote `ActiveSupport::Duration`.
|
543
584
|
|
585
|
+
*Rafael Mendonça França*
|
544
586
|
|
545
|
-
|
587
|
+
* Remove deprecated `#quote_bound_value`.
|
546
588
|
|
547
|
-
*
|
589
|
+
*Rafael Mendonça França*
|
548
590
|
|
591
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
|
549
592
|
|
550
|
-
|
593
|
+
*Rafael Mendonça França*
|
551
594
|
|
552
|
-
*
|
595
|
+
* Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
|
596
|
+
`#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
|
597
|
+
for the current role when the `role` argument isn't provided.
|
553
598
|
|
554
|
-
*
|
599
|
+
*Rafael Mendonça França*
|
555
600
|
|
556
|
-
*
|
601
|
+
* Remove deprecated `#all_connection_pools`.
|
557
602
|
|
558
|
-
*
|
603
|
+
*Rafael Mendonça França*
|
559
604
|
|
560
|
-
*
|
605
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
|
561
606
|
|
562
607
|
*Rafael Mendonça França*
|
563
608
|
|
564
|
-
*
|
609
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
|
565
610
|
|
566
|
-
*
|
611
|
+
*Rafael Mendonça França*
|
567
612
|
|
568
|
-
*
|
613
|
+
* Remove deprecated `#all_foreign_keys_valid?` from database adapters.
|
569
614
|
|
570
|
-
|
571
|
-
with a default precision of 6. This means that users upgrading to Rails 7.0 from 6.1,
|
572
|
-
when loading the database schema, would get the new precision value, which would not match
|
573
|
-
the production schema.
|
615
|
+
*Rafael Mendonça França*
|
574
616
|
|
575
|
-
|
576
|
-
version and will look like this:
|
617
|
+
* Remove deprecated support to passing coder and class as second argument to `serialize`.
|
577
618
|
|
578
|
-
|
579
|
-
ActiveRecord::Schema[7.0].define
|
580
|
-
```
|
619
|
+
*Rafael Mendonça França*
|
581
620
|
|
582
|
-
|
583
|
-
set the current schema version to 6.1.
|
621
|
+
* Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
|
584
622
|
|
585
623
|
*Rafael Mendonça França*
|
586
624
|
|
587
|
-
*
|
625
|
+
* Remove deprecated `TestFixtures.fixture_path`.
|
588
626
|
|
589
|
-
*
|
627
|
+
*Rafael Mendonça França*
|
590
628
|
|
591
|
-
*
|
592
|
-
when bulk-inserting fixtures that exceed `max_allowed_packet` configuration.
|
629
|
+
* Remove deprecated behavior to support referring to a singular association by its plural name.
|
593
630
|
|
594
|
-
*
|
631
|
+
*Rafael Mendonça França*
|
595
632
|
|
596
|
-
*
|
633
|
+
* Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
|
597
634
|
|
598
|
-
*
|
635
|
+
*Rafael Mendonça França*
|
599
636
|
|
600
|
-
*
|
637
|
+
* Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
|
638
|
+
`ActiveRecord::MigrationContext`.
|
601
639
|
|
602
|
-
*
|
640
|
+
*Rafael Mendonça França*
|
603
641
|
|
604
|
-
*
|
642
|
+
* Remove deprecated `ActiveRecord::Migration.check_pending!` method.
|
605
643
|
|
606
|
-
*
|
644
|
+
*Rafael Mendonça França*
|
607
645
|
|
608
|
-
*
|
646
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
|
609
647
|
|
610
|
-
|
648
|
+
*Rafael Mendonça França*
|
611
649
|
|
612
|
-
|
650
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
|
613
651
|
|
614
|
-
*
|
652
|
+
*Rafael Mendonça França*
|
615
653
|
|
616
|
-
|
654
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
|
617
655
|
|
656
|
+
*Rafael Mendonça França*
|
618
657
|
|
619
|
-
|
658
|
+
* Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
|
620
659
|
|
660
|
+
*Rafael Mendonça França*
|
621
661
|
|
622
|
-
*
|
662
|
+
* Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
|
623
663
|
|
624
|
-
|
664
|
+
*Rafael Mendonça França*
|
625
665
|
|
626
|
-
|
666
|
+
* Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
|
627
667
|
|
628
|
-
*
|
668
|
+
*Rafael Mendonça França*
|
629
669
|
|
630
|
-
|
670
|
+
* Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
|
631
671
|
|
632
|
-
|
633
|
-
add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
|
634
|
-
```
|
672
|
+
*Rafael Mendonça França*
|
635
673
|
|
636
|
-
|
674
|
+
* Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
|
637
675
|
|
638
|
-
*
|
676
|
+
*Rafael Mendonça França*
|
639
677
|
|
640
|
-
*
|
678
|
+
* Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
|
641
679
|
|
642
|
-
*
|
680
|
+
*Rafael Mendonça França*
|
643
681
|
|
644
|
-
*
|
682
|
+
* Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
|
645
683
|
|
646
|
-
*
|
684
|
+
*Rafael Mendonça França*
|
647
685
|
|
648
|
-
*
|
686
|
+
* Remove deprecated support to call `alias_attribute` with non-existent attribute names.
|
649
687
|
|
650
|
-
*
|
688
|
+
*Rafael Mendonça França*
|
651
689
|
|
652
|
-
*
|
690
|
+
* Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
|
653
691
|
|
654
|
-
|
692
|
+
*Rafael Mendonça França*
|
655
693
|
|
656
|
-
|
694
|
+
* Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
|
657
695
|
|
658
|
-
|
696
|
+
Serialize data to the MessagePack format, for efficient storage in binary columns.
|
659
697
|
|
660
|
-
|
698
|
+
The binary encoding requires around 30% less space than the base64 encoding
|
699
|
+
used by the default serializer.
|
661
700
|
|
662
|
-
*
|
701
|
+
*Donal McBreen*
|
663
702
|
|
664
|
-
|
703
|
+
* Add support for encrypting binary columns.
|
665
704
|
|
666
|
-
|
705
|
+
Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
|
667
706
|
|
668
|
-
|
707
|
+
Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
|
708
|
+
incidentally worked for MySQL and SQLite, but not PostgreSQL.
|
669
709
|
|
670
|
-
*
|
710
|
+
*Donal McBreen*
|
671
711
|
|
672
|
-
|
673
|
-
bigint instead of integer for the SQLite Adapter.
|
712
|
+
* Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
|
674
713
|
|
675
|
-
*
|
714
|
+
*Rafael Mendonça França*
|
676
715
|
|
677
|
-
*
|
716
|
+
* Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
|
678
717
|
|
679
|
-
|
718
|
+
The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
|
719
|
+
will yield that same connection.
|
680
720
|
|
681
|
-
|
721
|
+
This is useful to perform a few database operations without causing a connection to be leased for the
|
722
|
+
entire duration of the request or job.
|
682
723
|
|
683
|
-
|
684
|
-
Post.in_order_of(:id, []).to_a
|
685
|
-
```
|
724
|
+
*Jean Boussier*
|
686
725
|
|
687
|
-
|
688
|
-
|
726
|
+
* Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
|
727
|
+
notification includes `:row_count` field.
|
689
728
|
|
690
|
-
*
|
729
|
+
*Jason Nochlin*
|
730
|
+
|
731
|
+
* The fix ensures that the association is joined using the appropriate join type
|
732
|
+
(either inner join or left outer join) based on the existing joins in the scope.
|
691
733
|
|
692
|
-
|
734
|
+
This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
|
693
735
|
|
694
|
-
|
736
|
+
Example:
|
695
737
|
|
696
|
-
* Fix quoting of column aliases generated by calculation methods.
|
697
738
|
|
698
|
-
Since the alias is derived from the table name, we can't assume the result
|
699
|
-
is a valid identifier.
|
700
739
|
|
701
740
|
```ruby
|
702
|
-
|
703
|
-
|
704
|
-
end
|
705
|
-
Test.group(:id).count
|
706
|
-
# syntax error at or near "1" (ActiveRecord::StatementInvalid)
|
707
|
-
# LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
|
741
|
+
# `associated` will use `LEFT JOIN` instead of using `JOIN`
|
742
|
+
Post.left_joins(:author).where.associated(:author)
|
708
743
|
```
|
709
744
|
|
710
|
-
*
|
745
|
+
*Saleh Alhaddad*
|
711
746
|
|
747
|
+
* Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
|
748
|
+
of Active Record models, when an application is eager loaded. As a result, encrypted attributes
|
749
|
+
could be misconfigured in some cases.
|
712
750
|
|
713
|
-
|
751
|
+
*Maxime Réty*
|
714
752
|
|
715
|
-
*
|
753
|
+
* Deprecate defining an `enum` with keyword arguments.
|
716
754
|
|
717
755
|
```ruby
|
718
|
-
|
719
|
-
|
756
|
+
class Function > ApplicationRecord
|
757
|
+
# BAD
|
758
|
+
enum color: [:red, :blue],
|
759
|
+
type: [:instance, :class]
|
720
760
|
|
721
|
-
|
722
|
-
|
761
|
+
# GOOD
|
762
|
+
enum :color, [:red, :blue]
|
763
|
+
enum :type, [:instance, :class]
|
764
|
+
end
|
765
|
+
```
|
723
766
|
|
724
|
-
|
725
|
-
not be able to handle it, but will either succeed or failed in a more correct way.
|
767
|
+
*Hartley McGuire*
|
726
768
|
|
727
|
-
|
769
|
+
* Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
|
728
770
|
|
729
|
-
|
771
|
+
When set, validates that the timestamp prefix for a migration is no more than a day ahead of
|
772
|
+
the timestamp associated with the current time. This is designed to prevent migrations prefixes
|
773
|
+
from being hand-edited to future timestamps, which impacts migration generation and other
|
774
|
+
migration commands.
|
730
775
|
|
731
|
-
|
776
|
+
*Adrianna Chang*
|
732
777
|
|
733
|
-
|
778
|
+
* Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
|
734
779
|
|
780
|
+
As well as `disconnect!` and `verify!`.
|
735
781
|
|
736
|
-
|
782
|
+
This generally isn't a big problem as connections must not be shared between
|
783
|
+
threads, but is required when running transactional tests or system tests
|
784
|
+
and could lead to a SEGV.
|
737
785
|
|
738
|
-
*
|
786
|
+
*Jean Boussier*
|
739
787
|
|
788
|
+
* Support `:source_location` tag option for query log tags.
|
740
789
|
|
741
|
-
|
790
|
+
```ruby
|
791
|
+
config.active_record.query_log_tags << :source_location
|
792
|
+
```
|
742
793
|
|
743
|
-
|
794
|
+
Calculating the caller location is a costly operation and should be used primarily in development
|
795
|
+
(note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
|
796
|
+
or occasionally on production for debugging purposes.
|
744
797
|
|
798
|
+
*fatkodima*
|
745
799
|
|
746
|
-
|
800
|
+
* Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
|
747
801
|
|
748
|
-
|
802
|
+
Allow compression to be disabled by setting `compress: false`
|
749
803
|
|
750
|
-
|
804
|
+
```ruby
|
805
|
+
class User
|
806
|
+
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
|
807
|
+
end
|
808
|
+
```
|
751
809
|
|
752
|
-
*
|
810
|
+
*Donal McBreen*
|
753
811
|
|
754
|
-
|
812
|
+
* Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
|
755
813
|
|
756
|
-
|
814
|
+
A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
|
757
815
|
|
758
816
|
*Rafael Mendonça França*
|
759
817
|
|
760
|
-
*
|
761
|
-
|
762
|
-
*Rafael Mendonça França*
|
818
|
+
* Add `row_count` field to `sql.active_record` notification.
|
763
819
|
|
764
|
-
|
820
|
+
This field returns the amount of rows returned by the query that emitted the notification.
|
765
821
|
|
766
|
-
|
767
|
-
Single Table Inheritance. This affects enums defined in subclasses, previously
|
768
|
-
the value of these fields was not parsed and remained `nil`
|
822
|
+
This metric is useful in cases where one wants to detect queries with big result sets.
|
769
823
|
|
770
|
-
*
|
824
|
+
*Marvin Bitterlich*
|
771
825
|
|
772
|
-
*
|
826
|
+
* Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
|
773
827
|
|
774
|
-
|
828
|
+
Previously, this would only raise on collection associations and produce a generic error on singular associations.
|
775
829
|
|
776
|
-
|
830
|
+
Now, it will raise on both collection and singular associations.
|
777
831
|
|
778
|
-
|
832
|
+
*Joshua Young*
|
779
833
|
|
780
|
-
|
834
|
+
* Fix single quote escapes on default generated MySQL columns.
|
781
835
|
|
782
|
-
|
783
|
-
class Book < ApplicationRecord
|
784
|
-
enum status: [:proposed, :written, :published]
|
785
|
-
end
|
836
|
+
MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
|
786
837
|
|
787
|
-
|
788
|
-
```
|
838
|
+
Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
|
789
839
|
|
790
|
-
|
840
|
+
This would result in issues when importing the schema on a fresh instance of a MySQL database.
|
791
841
|
|
792
|
-
|
842
|
+
Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
|
793
843
|
|
794
|
-
*
|
844
|
+
*Yash Kapadia*
|
795
845
|
|
796
|
-
*
|
846
|
+
* Fix Migrations with versions older than 7.1 validating options given to
|
847
|
+
`add_reference` and `t.references`.
|
797
848
|
|
798
|
-
|
849
|
+
*Hartley McGuire*
|
799
850
|
|
800
|
-
|
801
|
-
Commodity.upsert_all(
|
802
|
-
[
|
803
|
-
{ id: 2, name: "Copper", price: 4.84 },
|
804
|
-
{ id: 4, name: "Gold", price: 1380.87 },
|
805
|
-
{ id: 6, name: "Aluminium", price: 0.35 }
|
806
|
-
],
|
807
|
-
update_only: [:price] # Only prices will be updated
|
808
|
-
)
|
809
|
-
```
|
851
|
+
* Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
|
810
852
|
|
811
|
-
*
|
853
|
+
*JP Rosevear*
|
812
854
|
|
813
|
-
*
|
855
|
+
* Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
|
814
856
|
|
815
|
-
|
857
|
+
This wouldn't always work previously because boolean values would be interpreted as strings.
|
816
858
|
|
817
|
-
|
859
|
+
e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
|
860
|
+
cache.
|
818
861
|
|
819
|
-
*
|
862
|
+
*Mike Coutermarsh*, *Jean Boussier*
|
820
863
|
|
821
|
-
*
|
864
|
+
* Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
|
822
865
|
|
823
|
-
|
866
|
+
It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
|
867
|
+
but with support for `after_commit` and `after_rollback` callback options.
|
824
868
|
|
825
|
-
*
|
869
|
+
*Joshua Young*
|
826
870
|
|
827
|
-
|
871
|
+
* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
|
828
872
|
|
829
|
-
|
873
|
+
Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
|
830
874
|
|
831
|
-
|
875
|
+
Now, the encryptor lets the configured `message_serializer` decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize `ActiveRecord::Encryption::Message` objects using a type other than `String`.
|
832
876
|
|
833
|
-
|
877
|
+
The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
|
834
878
|
|
835
|
-
|
879
|
+
*Maxime Réty*
|
836
880
|
|
837
|
-
|
881
|
+
* Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
|
838
882
|
|
839
|
-
|
840
|
-
# Before:
|
841
|
-
Foo Load (0.2ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "hello"], ["LIMIT", 1]]
|
883
|
+
*Maxime Réty*
|
842
884
|
|
843
|
-
|
844
|
-
|
845
|
-
|
885
|
+
* The object returned by `explain` now responds to `pluck`, `first`,
|
886
|
+
`last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
|
887
|
+
new methods run `EXPLAIN` on the corresponding queries:
|
846
888
|
|
847
|
-
|
889
|
+
```ruby
|
890
|
+
User.all.explain.count
|
891
|
+
# EXPLAIN SELECT COUNT(*) FROM `users`
|
892
|
+
# ...
|
848
893
|
|
849
|
-
|
894
|
+
User.all.explain.maximum(:id)
|
895
|
+
# EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
|
896
|
+
# ...
|
897
|
+
```
|
850
898
|
|
851
|
-
*
|
899
|
+
*Petrik de Heus*
|
852
900
|
|
853
|
-
*
|
901
|
+
* Fixes an issue where `validates_associated` `:on` option wasn't respected
|
902
|
+
when validating associated records.
|
854
903
|
|
855
|
-
*
|
904
|
+
*Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
|
856
905
|
|
857
|
-
*
|
906
|
+
* Allow overriding SQLite defaults from `database.yml`.
|
858
907
|
|
859
|
-
|
908
|
+
Any PRAGMA configuration set under the `pragmas` key in the configuration
|
909
|
+
file takes precedence over Rails' defaults, and additional PRAGMAs can be
|
910
|
+
set as well.
|
860
911
|
|
861
|
-
|
912
|
+
```yaml
|
913
|
+
database: storage/development.sqlite3
|
914
|
+
timeout: 5000
|
915
|
+
pragmas:
|
916
|
+
journal_mode: off
|
917
|
+
temp_store: memory
|
918
|
+
```
|
862
919
|
|
863
|
-
*
|
920
|
+
*Stephen Margheim*
|
864
921
|
|
865
|
-
* Remove
|
922
|
+
* Remove warning message when running SQLite in production, but leave it unconfigured.
|
866
923
|
|
867
|
-
|
924
|
+
There are valid use cases for running SQLite in production. However, it must be done
|
925
|
+
with care, so instead of a warning most users won't see anyway, it's preferable to
|
926
|
+
leave the configuration commented out to force them to think about having the database
|
927
|
+
on a persistent volume etc.
|
868
928
|
|
869
|
-
*
|
929
|
+
*Jacopo Beschi*, *Jean Boussier*
|
870
930
|
|
871
|
-
|
931
|
+
* Add support for generated columns to the SQLite3 adapter.
|
872
932
|
|
873
|
-
|
874
|
-
|
933
|
+
Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
|
934
|
+
This adds support for those to the SQLite3 adapter.
|
875
935
|
|
876
936
|
```ruby
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
# Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
|
884
|
-
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
885
|
-
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
937
|
+
create_table :users do |t|
|
938
|
+
t.string :name
|
939
|
+
t.virtual :name_upper, type: :string, as: 'UPPER(name)'
|
940
|
+
t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
|
941
|
+
end
|
942
|
+
```
|
886
943
|
|
887
|
-
*
|
944
|
+
*Stephen Margheim*
|
888
945
|
|
889
|
-
*
|
946
|
+
* TrilogyAdapter: ignore `host` if `socket` parameter is set.
|
890
947
|
|
891
|
-
|
948
|
+
This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
|
892
949
|
|
893
|
-
|
950
|
+
```
|
951
|
+
DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
|
952
|
+
```
|
894
953
|
|
895
|
-
*
|
896
|
-
* `db:structure:dump`
|
897
|
-
* `db:structure:load`
|
898
|
-
* `db:structure:load_if_sql`
|
899
|
-
* `db:structure:dump:#{name}`
|
900
|
-
* `db:structure:load:#{name}`
|
901
|
-
* `db:test:load_structure`
|
902
|
-
* `db:test:load_structure:#{name}`
|
954
|
+
*Jean Boussier*
|
903
955
|
|
904
|
-
|
956
|
+
* Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
|
957
|
+
`assert_no_queries_match` assertions public.
|
905
958
|
|
906
|
-
|
959
|
+
To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
|
960
|
+
`assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
|
961
|
+
`assert_no_queries_match` are used. These assertions can now be used in applications as well.
|
907
962
|
|
908
|
-
|
963
|
+
```ruby
|
964
|
+
class ArticleTest < ActiveSupport::TestCase
|
965
|
+
test "queries are made" do
|
966
|
+
assert_queries_count(1) { Article.first }
|
967
|
+
end
|
909
968
|
|
910
|
-
|
969
|
+
test "creates a foreign key" do
|
970
|
+
assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
|
971
|
+
@connection.add_foreign_key(:comments, :posts)
|
972
|
+
end
|
973
|
+
end
|
974
|
+
end
|
975
|
+
```
|
911
976
|
|
912
|
-
|
977
|
+
*Petrik de Heus*, *fatkodima*
|
913
978
|
|
914
|
-
|
915
|
-
to be committed, so in order to avoid this mistake, the transaction block is rolled back.
|
979
|
+
* Fix `has_secure_token` calls the setter method on initialize.
|
916
980
|
|
917
|
-
*
|
981
|
+
*Abeid Ahmed*
|
918
982
|
|
919
|
-
*
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
```ruby
|
924
|
-
config.active_record.shard_resolver = ->(request) {
|
925
|
-
subdomain = request.subdomain
|
926
|
-
tenant = Tenant.find_by_subdomain!(subdomain)
|
927
|
-
tenant.shard
|
928
|
-
}
|
929
|
-
```
|
930
|
-
|
931
|
-
See guides for more details.
|
932
|
-
|
933
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
934
|
-
|
935
|
-
* Remove deprecated support to pass a column to `type_cast`.
|
936
|
-
|
937
|
-
*Rafael Mendonça França*
|
938
|
-
|
939
|
-
* Remove deprecated support to type cast to database values `ActiveRecord::Base` objects.
|
940
|
-
|
941
|
-
*Rafael Mendonça França*
|
942
|
-
|
943
|
-
* Remove deprecated support to quote `ActiveRecord::Base` objects.
|
944
|
-
|
945
|
-
*Rafael Mendonça França*
|
946
|
-
|
947
|
-
* Remove deprecacated support to resolve connection using `"primary"` as connection specification name.
|
948
|
-
|
949
|
-
*Rafael Mendonça França*
|
950
|
-
|
951
|
-
* Remove deprecation warning when using `:interval` column is used in PostgreSQL database.
|
952
|
-
|
953
|
-
Now, interval columns will return `ActiveSupport::Duration` objects instead of strings.
|
954
|
-
|
955
|
-
To keep the old behavior, you can add this line to your model:
|
956
|
-
|
957
|
-
```ruby
|
958
|
-
attribute :column, :string
|
959
|
-
```
|
960
|
-
|
961
|
-
*Rafael Mendonça França*
|
962
|
-
|
963
|
-
* Remove deprecated support to YAML load `ActiveRecord::Base` instance in the Rails 4.2 and 4.1 formats.
|
964
|
-
|
965
|
-
*Rafael Mendonça França*
|
966
|
-
|
967
|
-
* Remove deprecated option `:spec_name` in the `configs_for` method.
|
968
|
-
|
969
|
-
*Rafael Mendonça França*
|
970
|
-
|
971
|
-
* Remove deprecated `ActiveRecord::Base.allow_unsafe_raw_sql`.
|
972
|
-
|
973
|
-
*Rafael Mendonça França*
|
974
|
-
|
975
|
-
* Fix regression bug that caused ignoring additional conditions for preloading has_many-through relations.
|
976
|
-
|
977
|
-
Fixes #43132
|
978
|
-
|
979
|
-
*Alexander Pauly*
|
980
|
-
|
981
|
-
* Fix `has_many` inversing recursion on models with recursive associations.
|
982
|
-
|
983
|
-
*Gannon McGibbon*
|
984
|
-
|
985
|
-
* Add `accepts_nested_attributes_for` support for `delegated_type`
|
986
|
-
|
987
|
-
```ruby
|
988
|
-
class Entry < ApplicationRecord
|
989
|
-
delegated_type :entryable, types: %w[ Message Comment ]
|
990
|
-
accepts_nested_attributes_for :entryable
|
991
|
-
end
|
992
|
-
|
993
|
-
entry = Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
|
994
|
-
# => #<Entry:0x00>
|
995
|
-
# id: 1
|
996
|
-
# entryable_id: 1,
|
997
|
-
# entryable_type: 'Message'
|
998
|
-
# ...>
|
999
|
-
|
1000
|
-
entry.entryable
|
1001
|
-
# => #<Message:0x01>
|
1002
|
-
# id: 1
|
1003
|
-
# content: 'Hello world'
|
1004
|
-
# ...>
|
1005
|
-
```
|
1006
|
-
|
1007
|
-
Previously it would raise an error:
|
1008
|
-
|
1009
|
-
```ruby
|
1010
|
-
Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
|
1011
|
-
# ArgumentError: Cannot build association `entryable'. Are you trying to build a polymorphic one-to-one association?
|
1012
|
-
```
|
1013
|
-
|
1014
|
-
*Sjors Baltus*
|
1015
|
-
|
1016
|
-
* Use subquery for DELETE with GROUP_BY and HAVING clauses.
|
1017
|
-
|
1018
|
-
Prior to this change, deletes with GROUP_BY and HAVING were returning an error.
|
1019
|
-
|
1020
|
-
After this change, GROUP_BY and HAVING are valid clauses in DELETE queries, generating the following query:
|
1021
|
-
|
1022
|
-
```sql
|
1023
|
-
DELETE FROM "posts" WHERE "posts"."id" IN (
|
1024
|
-
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."id" HAVING (count(comments.id) >= 2))
|
1025
|
-
) [["flagged", "t"]]
|
1026
|
-
```
|
1027
|
-
|
1028
|
-
*Ignacio Chiazzo Cardarello*
|
1029
|
-
|
1030
|
-
* Use subquery for UPDATE with GROUP_BY and HAVING clauses.
|
1031
|
-
|
1032
|
-
Prior to this change, updates with GROUP_BY and HAVING were being ignored, generating a SQL like this:
|
1033
|
-
|
1034
|
-
```sql
|
1035
|
-
UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
|
1036
|
-
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
1037
|
-
) [["flagged", "t"]]
|
1038
|
-
```
|
1039
|
-
|
1040
|
-
After this change, GROUP_BY and HAVING clauses are used as a subquery in updates, like this:
|
1041
|
-
|
1042
|
-
```sql
|
1043
|
-
UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
|
1044
|
-
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
1045
|
-
GROUP BY posts.id HAVING (count(comments.id) >= 2)
|
1046
|
-
) [["flagged", "t"]]
|
1047
|
-
```
|
1048
|
-
|
1049
|
-
*Ignacio Chiazzo Cardarello*
|
1050
|
-
|
1051
|
-
* Add support for setting the filename of the schema or structure dump in the database config.
|
1052
|
-
|
1053
|
-
Applications may now set their the filename or path of the schema / structure dump file in their database configuration.
|
1054
|
-
|
1055
|
-
```yaml
|
1056
|
-
production:
|
1057
|
-
primary:
|
1058
|
-
database: my_db
|
1059
|
-
schema_dump: my_schema_dump_filename.rb
|
1060
|
-
animals:
|
1061
|
-
database: animals_db
|
1062
|
-
schema_dump: false
|
1063
|
-
```
|
1064
|
-
|
1065
|
-
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`.
|
1066
|
-
|
1067
|
-
*Eileen M. Uchitelle*, *Ryan Kerr*
|
1068
|
-
|
1069
|
-
* Add `ActiveRecord::Base.prohibit_shard_swapping` to prevent attempts to change the shard within a block.
|
1070
|
-
|
1071
|
-
*John Crepezzi*, *Eileen M. Uchitelle*
|
1072
|
-
|
1073
|
-
* Filter unchanged attributes with default function from insert query when `partial_inserts` is disabled.
|
1074
|
-
|
1075
|
-
*Akshay Birajdar*, *Jacopo Beschi*
|
1076
|
-
|
1077
|
-
* Add support for FILTER clause (SQL:2003) to Arel.
|
1078
|
-
|
1079
|
-
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.
|
1080
|
-
|
1081
|
-
*Andrey Novikov*
|
1082
|
-
|
1083
|
-
* Automatically set timestamps on record creation during bulk insert/upsert
|
1084
|
-
|
1085
|
-
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}`).
|
1086
|
-
|
1087
|
-
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.
|
1088
|
-
|
1089
|
-
Note that this means `upsert_all` on models with `record_timestamps = false` will no longer touch `updated_{at,on}` automatically.
|
1090
|
-
|
1091
|
-
*Sam Bostock*
|
1092
|
-
|
1093
|
-
* Don't require `role` when passing `shard` to `connected_to`.
|
1094
|
-
|
1095
|
-
`connected_to` can now be called with a `shard` only. Note that `role` is still inherited if `connected_to` calls are nested.
|
1096
|
-
|
1097
|
-
*Eileen M. Uchitelle*
|
1098
|
-
|
1099
|
-
* Add option to lazily load the schema cache on the connection.
|
1100
|
-
|
1101
|
-
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.
|
1102
|
-
|
1103
|
-
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.
|
1104
|
-
|
1105
|
-
*Eileen M. Uchitelle*
|
1106
|
-
|
1107
|
-
* Allow automatic `inverse_of` detection for associations with scopes.
|
1108
|
-
|
1109
|
-
Automatic `inverse_of` detection now works for associations with scopes. For
|
1110
|
-
example, the `comments` association here now automatically detects
|
1111
|
-
`inverse_of: :post`, so we don't need to pass that option:
|
1112
|
-
|
1113
|
-
```ruby
|
1114
|
-
class Post < ActiveRecord::Base
|
1115
|
-
has_many :comments, -> { visible }
|
1116
|
-
end
|
1117
|
-
|
1118
|
-
class Comment < ActiveRecord::Base
|
1119
|
-
belongs_to :post
|
1120
|
-
end
|
1121
|
-
```
|
1122
|
-
|
1123
|
-
Note that the automatic detection still won't work if the inverse
|
1124
|
-
association has a scope. In this example a scope on the `post` association
|
1125
|
-
would still prevent Rails from finding the inverse for the `comments`
|
1126
|
-
association.
|
1127
|
-
|
1128
|
-
This will be the default for new apps in Rails 7. To opt in:
|
1129
|
-
|
1130
|
-
```ruby
|
1131
|
-
config.active_record.automatic_scope_inversing = true
|
1132
|
-
```
|
1133
|
-
|
1134
|
-
*Daniel Colson*, *Chris Bloom*
|
1135
|
-
|
1136
|
-
* Accept optional transaction args to `ActiveRecord::Locking::Pessimistic#with_lock`
|
1137
|
-
|
1138
|
-
`#with_lock` now accepts transaction options like `requires_new:`,
|
1139
|
-
`isolation:`, and `joinable:`
|
1140
|
-
|
1141
|
-
*John Mileham*
|
1142
|
-
|
1143
|
-
* Adds support for deferrable foreign key constraints in PostgreSQL.
|
1144
|
-
|
1145
|
-
By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases,
|
1146
|
-
but becomes a major limitation when creating related records before the parent record is inserted into the database.
|
1147
|
-
One example of this is looking up / creating a person via one or more unique alias.
|
1148
|
-
|
1149
|
-
```ruby
|
1150
|
-
Person.transaction do
|
1151
|
-
alias = Alias
|
1152
|
-
.create_with(user_id: SecureRandom.uuid)
|
1153
|
-
.create_or_find_by(name: "DHH")
|
1154
|
-
|
1155
|
-
person = Person
|
1156
|
-
.create_with(name: "David Heinemeier Hansson")
|
1157
|
-
.create_or_find_by(id: alias.user_id)
|
1158
|
-
end
|
1159
|
-
```
|
1160
|
-
|
1161
|
-
Using the default behavior, the transaction would fail when executing the first `INSERT` statement.
|
1162
|
-
|
1163
|
-
By passing the `:deferrable` option to the `add_foreign_key` statement in migrations, it's possible to defer this
|
1164
|
-
check.
|
1165
|
-
|
1166
|
-
```ruby
|
1167
|
-
add_foreign_key :aliases, :person, deferrable: true
|
1168
|
-
```
|
1169
|
-
|
1170
|
-
Passing `deferrable: true` doesn't change the default behavior, but allows manually deferring the check using
|
1171
|
-
`SET CONSTRAINTS ALL DEFERRED` within a transaction. This will cause the foreign keys to be checked after the
|
1172
|
-
transaction.
|
1173
|
-
|
1174
|
-
It's also possible to adjust the default behavior from an immediate check (after the statement), to a deferred check
|
1175
|
-
(after the transaction):
|
1176
|
-
|
1177
|
-
```ruby
|
1178
|
-
add_foreign_key :aliases, :person, deferrable: :deferred
|
1179
|
-
```
|
1180
|
-
|
1181
|
-
*Benedikt Deicke*
|
1182
|
-
|
1183
|
-
* Allow configuring Postgres password through the socket URL.
|
1184
|
-
|
1185
|
-
For example:
|
1186
|
-
```ruby
|
1187
|
-
ActiveRecord::DatabaseConfigurations::UrlConfig.new(
|
1188
|
-
:production, :production, 'postgres:///?user=user&password=secret&dbname=app', {}
|
1189
|
-
).configuration_hash
|
1190
|
-
```
|
1191
|
-
|
1192
|
-
will now return,
|
1193
|
-
|
1194
|
-
```ruby
|
1195
|
-
{ :user=>"user", :password=>"secret", :dbname=>"app", :adapter=>"postgresql" }
|
1196
|
-
```
|
1197
|
-
|
1198
|
-
*Abeid Ahmed*
|
1199
|
-
|
1200
|
-
* PostgreSQL: support custom enum types
|
1201
|
-
|
1202
|
-
In migrations, use `create_enum` to add a new enum type, and `t.enum` to add a column.
|
1203
|
-
|
1204
|
-
```ruby
|
1205
|
-
def up
|
1206
|
-
create_enum :mood, ["happy", "sad"]
|
1207
|
-
|
1208
|
-
change_table :cats do |t|
|
1209
|
-
t.enum :current_mood, enum_type: "mood", default: "happy", null: false
|
1210
|
-
end
|
1211
|
-
end
|
1212
|
-
```
|
1213
|
-
|
1214
|
-
Enums will be presented correctly in `schema.rb`. Note that this is only supported by
|
1215
|
-
the PostgreSQL adapter.
|
1216
|
-
|
1217
|
-
*Alex Ghiculescu*
|
1218
|
-
|
1219
|
-
* Avoid COMMENT statements in PostgreSQL structure dumps
|
1220
|
-
|
1221
|
-
COMMENT statements are now omitted from the output of `db:structure:dump` when using PostgreSQL >= 11.
|
1222
|
-
This allows loading the dump without a pgsql superuser account.
|
1223
|
-
|
1224
|
-
Fixes #36816, #43107.
|
1225
|
-
|
1226
|
-
*Janosch Müller*
|
1227
|
-
|
1228
|
-
* Add support for generated columns in PostgreSQL adapter
|
1229
|
-
|
1230
|
-
Generated columns are supported since version 12.0 of PostgreSQL. This adds
|
1231
|
-
support of those to the PostgreSQL adapter.
|
1232
|
-
|
1233
|
-
```ruby
|
1234
|
-
create_table :users do |t|
|
1235
|
-
t.string :name
|
1236
|
-
t.virtual :name_upcased, type: :string, as: 'upper(name)', stored: true
|
1237
|
-
end
|
1238
|
-
```
|
1239
|
-
|
1240
|
-
*Michał Begejowicz*
|
1241
|
-
|
1242
|
-
|
1243
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
1244
|
-
|
1245
|
-
* No changes.
|
1246
|
-
|
1247
|
-
|
1248
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
1249
|
-
|
1250
|
-
* Remove warning when overwriting existing scopes
|
1251
|
-
|
1252
|
-
Removes the following unnecessary warning message that appeared when overwriting existing scopes
|
1253
|
-
|
1254
|
-
```
|
1255
|
-
Creating scope :my_scope_name. Overwriting existing method "MyClass.my_scope_name" when overwriting existing scopes
|
1256
|
-
```
|
1257
|
-
|
1258
|
-
*Weston Ganger*
|
1259
|
-
|
1260
|
-
* Use full precision for `updated_at` in `insert_all`/`upsert_all`
|
1261
|
-
|
1262
|
-
`CURRENT_TIMESTAMP` provides differing precision depending on the database,
|
1263
|
-
and not all databases support explicitly specifying additional precision.
|
1264
|
-
|
1265
|
-
Instead, we delegate to the new `connection.high_precision_current_timestamp`
|
1266
|
-
for the SQL to produce a high precision timestamp on the current database.
|
1267
|
-
|
1268
|
-
Fixes #42992
|
1269
|
-
|
1270
|
-
*Sam Bostock*
|
1271
|
-
|
1272
|
-
* Add ssl support for postgresql database tasks
|
1273
|
-
|
1274
|
-
Add `PGSSLMODE`, `PGSSLCERT`, `PGSSLKEY` and `PGSSLROOTCERT` to pg_env from database config
|
1275
|
-
when running postgresql database tasks.
|
1276
|
-
|
1277
|
-
```yaml
|
1278
|
-
# config/database.yml
|
1279
|
-
|
1280
|
-
production:
|
1281
|
-
sslmode: verify-full
|
1282
|
-
sslcert: client.crt
|
1283
|
-
sslkey: client.key
|
1284
|
-
sslrootcert: ca.crt
|
1285
|
-
```
|
1286
|
-
|
1287
|
-
Environment variables
|
1288
|
-
|
1289
|
-
```
|
1290
|
-
PGSSLMODE=verify-full
|
1291
|
-
PGSSLCERT=client.crt
|
1292
|
-
PGSSLKEY=client.key
|
1293
|
-
PGSSLROOTCERT=ca.crt
|
1294
|
-
```
|
1295
|
-
|
1296
|
-
Fixes #42994
|
1297
|
-
|
1298
|
-
*Michael Bayucot*
|
1299
|
-
|
1300
|
-
* Avoid scoping update callbacks in `ActiveRecord::Relation#update!`.
|
1301
|
-
|
1302
|
-
Making it consistent with how scoping is applied only to the query in `ActiveRecord::Relation#update`
|
1303
|
-
and not also to the callbacks from the update itself.
|
1304
|
-
|
1305
|
-
*Dylan Thacker-Smith*
|
1306
|
-
|
1307
|
-
* Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
|
1308
|
-
using `String#constantize` instead of the model's `polymorphic_class_for`.
|
1309
|
-
|
1310
|
-
When updating a polymorphic association, the old `foreign_type` was not inferred correctly when:
|
1311
|
-
1. `touch`ing the previously associated record
|
1312
|
-
2. updating the previously associated record's `counter_cache`
|
1313
|
-
|
1314
|
-
*Jimmy Bourassa*
|
1315
|
-
|
1316
|
-
* Add config option for ignoring tables when dumping the schema cache.
|
1317
|
-
|
1318
|
-
Applications can now be configured to ignore certain tables when dumping the schema cache.
|
1319
|
-
|
1320
|
-
The configuration option can table an array of tables:
|
1321
|
-
|
1322
|
-
```ruby
|
1323
|
-
config.active_record.schema_cache_ignored_tables = ["ignored_table", "another_ignored_table"]
|
1324
|
-
```
|
1325
|
-
|
1326
|
-
Or a regex:
|
1327
|
-
|
1328
|
-
```ruby
|
1329
|
-
config.active_record.schema_cache_ignored_tables = [/^_/]
|
1330
|
-
```
|
1331
|
-
|
1332
|
-
*Eileen M. Uchitelle*
|
1333
|
-
|
1334
|
-
* Make schema cache methods return consistent results.
|
1335
|
-
|
1336
|
-
Previously the schema cache methods `primary_keys`, `columns`, `columns_hash`, and `indexes`
|
1337
|
-
would behave differently than one another when a table didn't exist and differently across
|
1338
|
-
database adapters. This change unifies the behavior so each method behaves the same regardless
|
1339
|
-
of adapter.
|
1340
|
-
|
1341
|
-
The behavior now is:
|
1342
|
-
|
1343
|
-
`columns`: (unchanged) raises a db error if the table does not exist.
|
1344
|
-
`columns_hash`: (unchanged) raises a db error if the table does not exist.
|
1345
|
-
`primary_keys`: (unchanged) returns `nil` if the table does not exist.
|
1346
|
-
`indexes`: (changed for mysql2) returns `[]` if the table does not exist.
|
1347
|
-
|
1348
|
-
*Eileen M. Uchitelle*
|
1349
|
-
|
1350
|
-
* Reestablish connection to previous database after after running `db:schema:load:name`
|
1351
|
-
|
1352
|
-
After running `db:schema:load:name` the previous connection is restored.
|
1353
|
-
|
1354
|
-
*Jacopo Beschi*
|
1355
|
-
|
1356
|
-
* Add database config option `database_tasks`
|
1357
|
-
|
1358
|
-
If you would like to connect to an external database without any database
|
1359
|
-
management tasks such as schema management, migrations, seeds, etc. you can set
|
1360
|
-
the per database config option `database_tasks: false`
|
1361
|
-
|
1362
|
-
```yaml
|
1363
|
-
# config/database.yml
|
1364
|
-
|
1365
|
-
production:
|
1366
|
-
primary:
|
1367
|
-
database: my_database
|
1368
|
-
adapter: mysql2
|
1369
|
-
animals:
|
1370
|
-
database: my_animals_database
|
1371
|
-
adapter: mysql2
|
1372
|
-
database_tasks: false
|
1373
|
-
```
|
1374
|
-
|
1375
|
-
*Weston Ganger*
|
1376
|
-
|
1377
|
-
* Fix `ActiveRecord::InternalMetadata` to not be broken by `config.active_record.record_timestamps = false`
|
1378
|
-
|
1379
|
-
Since the model always create the timestamp columns, it has to set them, otherwise it breaks
|
1380
|
-
various DB management tasks.
|
1381
|
-
|
1382
|
-
Fixes #42983
|
1383
|
-
|
1384
|
-
* Add `ActiveRecord::QueryLogs`.
|
1385
|
-
|
1386
|
-
Configurable tags can be automatically added to all SQL queries generated by Active Record.
|
1387
|
-
|
1388
|
-
```ruby
|
1389
|
-
# config/application.rb
|
1390
|
-
module MyApp
|
1391
|
-
class Application < Rails::Application
|
1392
|
-
config.active_record.query_log_tags_enabled = true
|
1393
|
-
end
|
1394
|
-
end
|
1395
|
-
```
|
1396
|
-
|
1397
|
-
By default the application, controller and action details are added to the query tags:
|
1398
|
-
|
1399
|
-
```ruby
|
1400
|
-
class BooksController < ApplicationController
|
1401
|
-
def index
|
1402
|
-
@books = Book.all
|
1403
|
-
end
|
1404
|
-
end
|
1405
|
-
```
|
1406
|
-
|
1407
|
-
```ruby
|
1408
|
-
GET /books
|
1409
|
-
# SELECT * FROM books /*application:MyApp;controller:books;action:index*/
|
1410
|
-
```
|
1411
|
-
|
1412
|
-
Custom tags containing static values and Procs can be defined in the application configuration:
|
1413
|
-
|
1414
|
-
```ruby
|
1415
|
-
config.active_record.query_log_tags = [
|
1416
|
-
:application,
|
1417
|
-
:controller,
|
1418
|
-
:action,
|
1419
|
-
{
|
1420
|
-
custom_static: "foo",
|
1421
|
-
custom_dynamic: -> { Time.now }
|
1422
|
-
}
|
1423
|
-
]
|
1424
|
-
```
|
1425
|
-
|
1426
|
-
*Keeran Raj Hawoldar*, *Eileen M. Uchitelle*, *Kasper Timm Hansen*
|
1427
|
-
|
1428
|
-
* Added support for multiple databases to `rails db:setup` and `rails db:reset`.
|
1429
|
-
|
1430
|
-
*Ryan Hall*
|
1431
|
-
|
1432
|
-
* Add `ActiveRecord::Relation#structurally_compatible?`.
|
1433
|
-
|
1434
|
-
Adds a query method by which a user can tell if the relation that they're
|
1435
|
-
about to use for `#or` or `#and` is structurally compatible with the
|
1436
|
-
receiver.
|
1437
|
-
|
1438
|
-
*Kevin Newton*
|
1439
|
-
|
1440
|
-
* Add `ActiveRecord::QueryMethods#in_order_of`.
|
1441
|
-
|
1442
|
-
This allows you to specify an explicit order that you'd like records
|
1443
|
-
returned in based on a SQL expression. By default, this will be accomplished
|
1444
|
-
using a case statement, as in:
|
1445
|
-
|
1446
|
-
```ruby
|
1447
|
-
Post.in_order_of(:id, [3, 5, 1])
|
1448
|
-
```
|
1449
|
-
|
1450
|
-
will generate the SQL:
|
1451
|
-
|
1452
|
-
```sql
|
1453
|
-
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
|
1454
|
-
```
|
1455
|
-
|
1456
|
-
However, because this functionality is built into MySQL in the form of the
|
1457
|
-
`FIELD` function, that connection adapter will generate the following SQL
|
1458
|
-
instead:
|
1459
|
-
|
1460
|
-
```sql
|
1461
|
-
SELECT "posts".* FROM "posts" ORDER BY FIELD("posts"."id", 1, 5, 3) DESC
|
1462
|
-
```
|
1463
|
-
|
1464
|
-
*Kevin Newton*
|
1465
|
-
|
1466
|
-
* Fix `eager_loading?` when ordering with `Symbol`.
|
1467
|
-
|
1468
|
-
`eager_loading?` is triggered correctly when using `order` with symbols.
|
1469
|
-
|
1470
|
-
```ruby
|
1471
|
-
scope = Post.includes(:comments).order(:"comments.label")
|
1472
|
-
=> true
|
1473
|
-
```
|
1474
|
-
|
1475
|
-
*Jacopo Beschi*
|
1476
|
-
|
1477
|
-
* Two change tracking methods are added for `belongs_to` associations.
|
1478
|
-
|
1479
|
-
The `association_changed?` method (assuming an association named `:association`) returns true
|
1480
|
-
if a different associated object has been assigned and the foreign key will be updated in the
|
1481
|
-
next save.
|
1482
|
-
|
1483
|
-
The `association_previously_changed?` method returns true if the previous save updated the
|
1484
|
-
association to reference a different associated object.
|
1485
|
-
|
1486
|
-
*George Claghorn*
|
1487
|
-
|
1488
|
-
* Add option to disable schema dump per-database.
|
1489
|
-
|
1490
|
-
Dumping the schema is on by default for all databases in an application. To turn it off for a
|
1491
|
-
specific database, use the `schema_dump` option:
|
1492
|
-
|
1493
|
-
```yaml
|
1494
|
-
# config/database.yml
|
1495
|
-
|
1496
|
-
production:
|
1497
|
-
schema_dump: false
|
1498
|
-
```
|
1499
|
-
|
1500
|
-
*Luis Vasconcellos*, *Eileen M. Uchitelle*
|
1501
|
-
|
1502
|
-
* Fix `eager_loading?` when ordering with `Hash` syntax.
|
1503
|
-
|
1504
|
-
`eager_loading?` is triggered correctly when using `order` with hash syntax
|
1505
|
-
on an outer table.
|
1506
|
-
|
1507
|
-
```ruby
|
1508
|
-
Post.includes(:comments).order({ "comments.label": :ASC }).eager_loading?
|
1509
|
-
# => true
|
1510
|
-
```
|
1511
|
-
|
1512
|
-
*Jacopo Beschi*
|
1513
|
-
|
1514
|
-
* Move the forcing of clear text encoding to the `ActiveRecord::Encryption::Encryptor`.
|
1515
|
-
|
1516
|
-
Fixes #42699.
|
1517
|
-
|
1518
|
-
*J Smith*
|
1519
|
-
|
1520
|
-
* `partial_inserts` is now disabled by default in new apps.
|
1521
|
-
|
1522
|
-
This will be the default for new apps in Rails 7. To opt in:
|
1523
|
-
|
1524
|
-
```ruby
|
1525
|
-
config.active_record.partial_inserts = true
|
1526
|
-
```
|
1527
|
-
|
1528
|
-
If a migration removes the default value of a column, this option
|
1529
|
-
would cause old processes to no longer be able to create new records.
|
1530
|
-
|
1531
|
-
If you need to remove a column, you should first use `ignored_columns`
|
1532
|
-
to stop using it.
|
1533
|
-
|
1534
|
-
*Jean Boussier*
|
1535
|
-
|
1536
|
-
* Rails can now verify foreign keys after loading fixtures in tests.
|
1537
|
-
|
1538
|
-
This will be the default for new apps in Rails 7. To opt in:
|
1539
|
-
|
1540
|
-
```ruby
|
1541
|
-
config.active_record.verify_foreign_keys_for_fixtures = true
|
1542
|
-
```
|
1543
|
-
|
1544
|
-
Tests will not run if there is a foreign key constraint violation in your fixture data.
|
1545
|
-
|
1546
|
-
The feature is supported by SQLite and PostgreSQL, other adapters can also add support for it.
|
1547
|
-
|
1548
|
-
*Alex Ghiculescu*
|
1549
|
-
|
1550
|
-
* Clear cached `has_one` association after setting `belongs_to` association to `nil`.
|
1551
|
-
|
1552
|
-
After setting a `belongs_to` relation to `nil` and updating an unrelated attribute on the owner,
|
1553
|
-
the owner should still return `nil` on the `has_one` relation.
|
1554
|
-
|
1555
|
-
Fixes #42597.
|
1556
|
-
|
1557
|
-
*Michiel de Mare*
|
1558
|
-
|
1559
|
-
* OpenSSL constants are now used for Digest computations.
|
1560
|
-
|
1561
|
-
*Dirkjan Bussink*
|
1562
|
-
|
1563
|
-
* Adds support for `if_not_exists` to `add_foreign_key` and `if_exists` to `remove_foreign_key`.
|
1564
|
-
|
1565
|
-
Applications can set their migrations to ignore exceptions raised when adding a foreign key
|
1566
|
-
that already exists or when removing a foreign key that does not exist.
|
1567
|
-
|
1568
|
-
Example Usage:
|
1569
|
-
|
1570
|
-
```ruby
|
1571
|
-
class AddAuthorsForeignKeyToArticles < ActiveRecord::Migration[7.0]
|
1572
|
-
def change
|
1573
|
-
add_foreign_key :articles, :authors, if_not_exists: true
|
1574
|
-
end
|
1575
|
-
end
|
1576
|
-
```
|
1577
|
-
|
1578
|
-
```ruby
|
1579
|
-
class RemoveAuthorsForeignKeyFromArticles < ActiveRecord::Migration[7.0]
|
1580
|
-
def change
|
1581
|
-
remove_foreign_key :articles, :authors, if_exists: true
|
1582
|
-
end
|
1583
|
-
end
|
1584
|
-
```
|
1585
|
-
|
1586
|
-
*Roberto Miranda*
|
1587
|
-
|
1588
|
-
* Prevent polluting ENV during postgresql structure dump/load.
|
1589
|
-
|
1590
|
-
Some configuration parameters were provided to pg_dump / psql via
|
1591
|
-
environment variables which persisted beyond the command being run, and may
|
1592
|
-
have caused subsequent commands and connections to fail. Tasks running
|
1593
|
-
across multiple postgresql databases like `rails db:test:prepare` may have
|
1594
|
-
been affected.
|
1595
|
-
|
1596
|
-
*Samuel Cochran*
|
1597
|
-
|
1598
|
-
* Set precision 6 by default for `datetime` columns.
|
1599
|
-
|
1600
|
-
By default, datetime columns will have microseconds precision instead of seconds precision.
|
1601
|
-
|
1602
|
-
*Roberto Miranda*
|
1603
|
-
|
1604
|
-
* Allow preloading of associations with instance dependent scopes.
|
1605
|
-
|
1606
|
-
*John Hawthorn*, *John Crepezzi*, *Adam Hess*, *Eileen M. Uchitelle*, *Dinah Shi*
|
1607
|
-
|
1608
|
-
* Do not try to rollback transactions that failed due to a `ActiveRecord::TransactionRollbackError`.
|
1609
|
-
|
1610
|
-
*Jamie McCarthy*
|
1611
|
-
|
1612
|
-
* Active Record Encryption will now encode values as UTF-8 when using deterministic
|
1613
|
-
encryption. The encoding is part of the encrypted payload, so different encodings for
|
1614
|
-
different values result in different ciphertexts. This can break unique constraints and
|
1615
|
-
queries.
|
1616
|
-
|
1617
|
-
The new behavior is configurable via `active_record.encryption.forced_encoding_for_deterministic_encryption`
|
1618
|
-
that is `Encoding::UTF_8` by default. It can be disabled by setting it to `nil`.
|
1619
|
-
|
1620
|
-
*Jorge Manrubia*
|
1621
|
-
|
1622
|
-
* The MySQL adapter now cast numbers and booleans bind parameters to string for safety reasons.
|
1623
|
-
|
1624
|
-
When comparing a string and a number in a query, MySQL converts the string to a number. So for
|
1625
|
-
instance `"foo" = 0`, will implicitly cast `"foo"` to `0` and will evaluate to `TRUE` which can
|
1626
|
-
lead to security vulnerabilities.
|
1627
|
-
|
1628
|
-
Active Record already protect against that vulnerability when it knows the type of the column
|
1629
|
-
being compared, however until now it was still vulnerable when using bind parameters:
|
1630
|
-
|
1631
|
-
```ruby
|
1632
|
-
User.where("login_token = ?", 0).first
|
1633
|
-
```
|
1634
|
-
|
1635
|
-
Would perform:
|
1636
|
-
|
1637
|
-
```sql
|
1638
|
-
SELECT * FROM `users` WHERE `login_token` = 0 LIMIT 1;
|
1639
|
-
```
|
1640
|
-
|
1641
|
-
Now it will perform:
|
1642
|
-
|
1643
|
-
```sql
|
1644
|
-
SELECT * FROM `users` WHERE `login_token` = '0' LIMIT 1;
|
1645
|
-
```
|
1646
|
-
|
1647
|
-
*Jean Boussier*
|
1648
|
-
|
1649
|
-
* Fixture configurations (`_fixture`) are now strictly validated.
|
1650
|
-
|
1651
|
-
If an error will be raised if that entry contains unknown keys while previously it
|
1652
|
-
would silently have no effects.
|
1653
|
-
|
1654
|
-
*Jean Boussier*
|
1655
|
-
|
1656
|
-
* Add `ActiveRecord::Base.update!` that works like `ActiveRecord::Base.update` but raises exceptions.
|
1657
|
-
|
1658
|
-
This allows for the same behavior as the instance method `#update!` at a class level.
|
1659
|
-
|
1660
|
-
```ruby
|
1661
|
-
Person.update!(:all, state: "confirmed")
|
1662
|
-
```
|
1663
|
-
|
1664
|
-
*Dorian Marié*
|
1665
|
-
|
1666
|
-
* Add `ActiveRecord::Base#attributes_for_database`.
|
1667
|
-
|
1668
|
-
Returns attributes with values for assignment to the database.
|
1669
|
-
|
1670
|
-
*Chris Salzberg*
|
1671
|
-
|
1672
|
-
* Use an empty query to check if the PostgreSQL connection is still active.
|
1673
|
-
|
1674
|
-
An empty query is faster than `SELECT 1`.
|
1675
|
-
|
1676
|
-
*Heinrich Lee Yu*
|
1677
|
-
|
1678
|
-
* Add `ActiveRecord::Base#previously_persisted?`.
|
1679
|
-
|
1680
|
-
Returns `true` if the object has been previously persisted but now it has been deleted.
|
1681
|
-
|
1682
|
-
* Deprecate `partial_writes` in favor of `partial_inserts` and `partial_updates`.
|
1683
|
-
|
1684
|
-
This allows to have a different behavior on update and create.
|
1685
|
-
|
1686
|
-
*Jean Boussier*
|
1687
|
-
|
1688
|
-
* Fix compatibility with `psych >= 4`.
|
1689
|
-
|
1690
|
-
Starting in Psych 4.0.0 `YAML.load` behaves like `YAML.safe_load`. To preserve compatibility,
|
1691
|
-
Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
|
1692
|
-
|
1693
|
-
*Jean Boussier*
|
1694
|
-
|
1695
|
-
* `ActiveRecord::Base.logger` is now a `class_attribute`.
|
1696
|
-
|
1697
|
-
This means it can no longer be accessed directly through `@@logger`, and that setting `logger =`
|
1698
|
-
on a subclass won't change the parent's logger.
|
1699
|
-
|
1700
|
-
*Jean Boussier*
|
1701
|
-
|
1702
|
-
* Add `.asc.nulls_first` for all databases. Unfortunately MySQL still doesn't like `nulls_last`.
|
1703
|
-
|
1704
|
-
*Keenan Brock*
|
1705
|
-
|
1706
|
-
* Improve performance of `one?` and `many?` by limiting the generated count query to 2 results.
|
1707
|
-
|
1708
|
-
*Gonzalo Riestra*
|
1709
|
-
|
1710
|
-
* Don't check type when using `if_not_exists` on `add_column`.
|
1711
|
-
|
1712
|
-
Previously, if a migration called `add_column` with the `if_not_exists` option set to true
|
1713
|
-
the `column_exists?` check would look for a column with the same name and type as the migration.
|
1714
|
-
|
1715
|
-
Recently it was discovered that the type passed to the migration is not always the same type
|
1716
|
-
as the column after migration. For example a column set to `:mediumblob` in the migration will
|
1717
|
-
be casted to `binary` when calling `column.type`. Since there is no straightforward way to cast
|
1718
|
-
the type to the database type without running the migration, we opted to drop the type check from
|
1719
|
-
`add_column`. This means that migrations adding a duplicate column with a different type will no
|
1720
|
-
longer raise an error.
|
1721
|
-
|
1722
|
-
*Eileen M. Uchitelle*
|
1723
|
-
|
1724
|
-
* Log a warning message when running SQLite in production.
|
1725
|
-
|
1726
|
-
Using SQLite in production ENV is generally discouraged. SQLite is also the default adapter
|
1727
|
-
in a new Rails application.
|
1728
|
-
For the above reasons log a warning message when running SQLite in production.
|
1729
|
-
|
1730
|
-
The warning can be disabled by setting `config.active_record.sqlite3_production_warning=false`.
|
1731
|
-
|
1732
|
-
*Jacopo Beschi*
|
1733
|
-
|
1734
|
-
* Add option to disable joins for `has_one` associations.
|
1735
|
-
|
1736
|
-
In a multiple database application, associations can't join across
|
1737
|
-
databases. When set, this option instructs Rails to generate 2 or
|
1738
|
-
more queries rather than generating joins for `has_one` associations.
|
1739
|
-
|
1740
|
-
Set the option on a has one through association:
|
1741
|
-
|
1742
|
-
```ruby
|
1743
|
-
class Person
|
1744
|
-
has_one :dog
|
1745
|
-
has_one :veterinarian, through: :dog, disable_joins: true
|
1746
|
-
end
|
1747
|
-
```
|
1748
|
-
|
1749
|
-
Then instead of generating join SQL, two queries are used for `@person.veterinarian`:
|
1750
|
-
|
1751
|
-
```
|
1752
|
-
SELECT "dogs"."id" FROM "dogs" WHERE "dogs"."person_id" = ? [["person_id", 1]]
|
1753
|
-
SELECT "veterinarians".* FROM "veterinarians" WHERE "veterinarians"."dog_id" = ? [["dog_id", 1]]
|
1754
|
-
```
|
1755
|
-
|
1756
|
-
*Sarah Vessels*, *Eileen M. Uchitelle*
|
1757
|
-
|
1758
|
-
* `Arel::Visitors::Dot` now renders a complete set of properties when visiting
|
1759
|
-
`Arel::Nodes::SelectCore`, `SelectStatement`, `InsertStatement`, `UpdateStatement`, and
|
1760
|
-
`DeleteStatement`, which fixes #42026. Previously, some properties were omitted.
|
1761
|
-
|
1762
|
-
*Mike Dalessio*
|
1763
|
-
|
1764
|
-
* `Arel::Visitors::Dot` now supports `Arel::Nodes::Bin`, `Case`, `CurrentRow`, `Distinct`,
|
1765
|
-
`DistinctOn`, `Else`, `Except`, `InfixOperation`, `Intersect`, `Lock`, `NotRegexp`, `Quoted`,
|
1766
|
-
`Regexp`, `UnaryOperation`, `Union`, `UnionAll`, `When`, and `With`. Previously, these node
|
1767
|
-
types caused an exception to be raised by `Arel::Visitors::Dot#accept`.
|
1768
|
-
|
1769
|
-
*Mike Dalessio*
|
1770
|
-
|
1771
|
-
* Optimize `remove_columns` to use a single SQL statement.
|
1772
|
-
|
1773
|
-
```ruby
|
1774
|
-
remove_columns :my_table, :col_one, :col_two
|
1775
|
-
```
|
1776
|
-
|
1777
|
-
Now results in the following SQL:
|
1778
|
-
|
1779
|
-
```sql
|
1780
|
-
ALTER TABLE "my_table" DROP COLUMN "col_one", DROP COLUMN "col_two"
|
1781
|
-
```
|
1782
|
-
|
1783
|
-
*Jon Dufresne*
|
1784
|
-
|
1785
|
-
* Ensure `has_one` autosave association callbacks get called once.
|
1786
|
-
|
1787
|
-
Change the `has_one` autosave callback to be non cyclic as well.
|
1788
|
-
By doing this the autosave callback are made more consistent for
|
1789
|
-
all 3 cases: `has_many`, `has_one`, and `belongs_to`.
|
1790
|
-
|
1791
|
-
*Petrik de Heus*
|
1792
|
-
|
1793
|
-
* Add option to disable joins for associations.
|
1794
|
-
|
1795
|
-
In a multiple database application, associations can't join across
|
1796
|
-
databases. When set, this option instructs Rails to generate 2 or
|
1797
|
-
more queries rather than generating joins for associations.
|
1798
|
-
|
1799
|
-
Set the option on a has many through association:
|
1800
|
-
|
1801
|
-
```ruby
|
1802
|
-
class Dog
|
1803
|
-
has_many :treats, through: :humans, disable_joins: true
|
1804
|
-
has_many :humans
|
1805
|
-
end
|
1806
|
-
```
|
1807
|
-
|
1808
|
-
Then instead of generating join SQL, two queries are used for `@dog.treats`:
|
1809
|
-
|
1810
|
-
```
|
1811
|
-
SELECT "humans"."id" FROM "humans" WHERE "humans"."dog_id" = ? [["dog_id", 1]]
|
1812
|
-
SELECT "treats".* FROM "treats" WHERE "treats"."human_id" IN (?, ?, ?) [["human_id", 1], ["human_id", 2], ["human_id", 3]]
|
1813
|
-
```
|
1814
|
-
|
1815
|
-
*Eileen M. Uchitelle*, *Aaron Patterson*, *Lee Quarella*
|
1816
|
-
|
1817
|
-
* Add setting for enumerating column names in SELECT statements.
|
1818
|
-
|
1819
|
-
Adding a column to a PostgreSQL database, for example, while the application is running can
|
1820
|
-
change the result of wildcard `SELECT *` queries, which invalidates the result
|
1821
|
-
of cached prepared statements and raises a `PreparedStatementCacheExpired` error.
|
1822
|
-
|
1823
|
-
When enabled, Active Record will avoid wildcards and always include column names
|
1824
|
-
in `SELECT` queries, which will return consistent results and avoid prepared
|
1825
|
-
statement errors.
|
1826
|
-
|
1827
|
-
Before:
|
1828
|
-
|
1829
|
-
```ruby
|
1830
|
-
Book.limit(5)
|
1831
|
-
# SELECT * FROM books LIMIT 5
|
1832
|
-
```
|
1833
|
-
|
1834
|
-
After:
|
1835
|
-
|
1836
|
-
```ruby
|
1837
|
-
# config/application.rb
|
1838
|
-
module MyApp
|
1839
|
-
class Application < Rails::Application
|
1840
|
-
config.active_record.enumerate_columns_in_select_statements = true
|
1841
|
-
end
|
1842
|
-
end
|
1843
|
-
|
1844
|
-
# or, configure per-model
|
1845
|
-
class Book < ApplicationRecord
|
1846
|
-
self.enumerate_columns_in_select_statements = true
|
1847
|
-
end
|
1848
|
-
```
|
1849
|
-
|
1850
|
-
```ruby
|
1851
|
-
Book.limit(5)
|
1852
|
-
# SELECT id, author_id, name, format, status, language, etc FROM books LIMIT 5
|
1853
|
-
```
|
1854
|
-
|
1855
|
-
*Matt Duszynski*
|
1856
|
-
|
1857
|
-
* Allow passing SQL as `on_duplicate` value to `#upsert_all` to make it possible to use raw SQL to update columns on conflict:
|
1858
|
-
|
1859
|
-
```ruby
|
1860
|
-
Book.upsert_all(
|
1861
|
-
[{ id: 1, status: 1 }, { id: 2, status: 1 }],
|
1862
|
-
on_duplicate: Arel.sql("status = GREATEST(books.status, EXCLUDED.status)")
|
1863
|
-
)
|
1864
|
-
```
|
1865
|
-
|
1866
|
-
*Vladimir Dementyev*
|
1867
|
-
|
1868
|
-
* Allow passing SQL as `returning` statement to `#upsert_all`:
|
1869
|
-
|
1870
|
-
```ruby
|
1871
|
-
Article.insert_all(
|
1872
|
-
[
|
1873
|
-
{ title: "Article 1", slug: "article-1", published: false },
|
1874
|
-
{ title: "Article 2", slug: "article-2", published: false }
|
1875
|
-
],
|
1876
|
-
returning: Arel.sql("id, (xmax = '0') as inserted, name as new_name")
|
1877
|
-
)
|
1878
|
-
```
|
1879
|
-
|
1880
|
-
*Vladimir Dementyev*
|
1881
|
-
|
1882
|
-
* Deprecate `legacy_connection_handling`.
|
1883
|
-
|
1884
|
-
*Eileen M. Uchitelle*
|
1885
|
-
|
1886
|
-
* Add attribute encryption support.
|
1887
|
-
|
1888
|
-
Encrypted attributes are declared at the model level. These
|
1889
|
-
are regular Active Record attributes backed by a column with
|
1890
|
-
the same name. The system will transparently encrypt these
|
1891
|
-
attributes before saving them into the database and will
|
1892
|
-
decrypt them when retrieving their values.
|
1893
|
-
|
1894
|
-
|
1895
|
-
```ruby
|
1896
|
-
class Person < ApplicationRecord
|
1897
|
-
encrypts :name
|
1898
|
-
encrypts :email_address, deterministic: true
|
1899
|
-
end
|
1900
|
-
```
|
1901
|
-
|
1902
|
-
You can learn more in the [Active Record Encryption
|
1903
|
-
guide](https://edgeguides.rubyonrails.org/active_record_encryption.html).
|
1904
|
-
|
1905
|
-
*Jorge Manrubia*
|
1906
|
-
|
1907
|
-
* Changed Arel predications `contains` and `overlaps` to use
|
1908
|
-
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
1909
|
-
|
1910
|
-
*Bradley Priest*
|
1911
|
-
|
1912
|
-
* Add mode argument to record level `strict_loading!`.
|
1913
|
-
|
1914
|
-
This argument can be used when enabling strict loading for a single record
|
1915
|
-
to specify that we only want to raise on n plus one queries.
|
1916
|
-
|
1917
|
-
```ruby
|
1918
|
-
developer.strict_loading!(mode: :n_plus_one_only)
|
1919
|
-
|
1920
|
-
developer.projects.to_a # Does not raise
|
1921
|
-
developer.projects.first.client # Raises StrictLoadingViolationError
|
1922
|
-
```
|
1923
|
-
|
1924
|
-
Previously, enabling strict loading would cause any lazily loaded
|
1925
|
-
association to raise an error. Using `n_plus_one_only` mode allows us to
|
1926
|
-
lazily load belongs_to, has_many, and other associations that are fetched
|
1927
|
-
through a single query.
|
1928
|
-
|
1929
|
-
*Dinah Shi*
|
1930
|
-
|
1931
|
-
* Fix Float::INFINITY assignment to datetime column with postgresql adapter.
|
1932
|
-
|
1933
|
-
Before:
|
1934
|
-
|
1935
|
-
```ruby
|
1936
|
-
# With this config
|
1937
|
-
ActiveRecord::Base.time_zone_aware_attributes = true
|
1938
|
-
|
1939
|
-
# and the following schema:
|
1940
|
-
create_table "postgresql_infinities" do |t|
|
1941
|
-
t.datetime "datetime"
|
1942
|
-
end
|
1943
|
-
|
1944
|
-
# This test fails
|
1945
|
-
record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
|
1946
|
-
assert_equal Float::INFINITY, record.datetime # record.datetime gets nil
|
1947
|
-
```
|
1948
|
-
|
1949
|
-
After this commit, `record.datetime` gets `Float::INFINITY` as expected.
|
1950
|
-
|
1951
|
-
*Shunichi Ikegami*
|
1952
|
-
|
1953
|
-
* Type cast enum values by the original attribute type.
|
1954
|
-
|
1955
|
-
The notable thing about this change is that unknown labels will no longer match 0 on MySQL.
|
1956
|
-
|
1957
|
-
```ruby
|
1958
|
-
class Book < ActiveRecord::Base
|
1959
|
-
enum :status, { proposed: 0, written: 1, published: 2 }
|
1960
|
-
end
|
1961
|
-
```
|
1962
|
-
|
1963
|
-
Before:
|
1964
|
-
|
1965
|
-
```ruby
|
1966
|
-
# SELECT `books`.* FROM `books` WHERE `books`.`status` = 'prohibited' LIMIT 1
|
1967
|
-
Book.find_by(status: :prohibited)
|
1968
|
-
# => #<Book id: 1, status: "proposed", ...> (for mysql2 adapter)
|
1969
|
-
# => ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: invalid input syntax for type integer: "prohibited" (for postgresql adapter)
|
1970
|
-
# => nil (for sqlite3 adapter)
|
1971
|
-
```
|
1972
|
-
|
1973
|
-
After:
|
1974
|
-
|
1975
|
-
```ruby
|
1976
|
-
# SELECT `books`.* FROM `books` WHERE `books`.`status` IS NULL LIMIT 1
|
1977
|
-
Book.find_by(status: :prohibited)
|
1978
|
-
# => nil (for all adapters)
|
1979
|
-
```
|
1980
|
-
|
1981
|
-
*Ryuta Kamizono*
|
1982
|
-
|
1983
|
-
* Fixtures for `has_many :through` associations now load timestamps on join tables.
|
1984
|
-
|
1985
|
-
Given this fixture:
|
1986
|
-
|
1987
|
-
```yml
|
1988
|
-
### monkeys.yml
|
1989
|
-
george:
|
1990
|
-
name: George the Monkey
|
1991
|
-
fruits: apple
|
1992
|
-
|
1993
|
-
### fruits.yml
|
1994
|
-
apple:
|
1995
|
-
name: apple
|
1996
|
-
```
|
1997
|
-
|
1998
|
-
If the join table (`fruit_monkeys`) contains `created_at` or `updated_at` columns,
|
1999
|
-
these will now be populated when loading the fixture. Previously, fixture loading
|
2000
|
-
would crash if these columns were required, and leave them as null otherwise.
|
2001
|
-
|
2002
|
-
*Alex Ghiculescu*
|
2003
|
-
|
2004
|
-
* Allow applications to configure the thread pool for async queries.
|
2005
|
-
|
2006
|
-
Some applications may want one thread pool per database whereas others want to use
|
2007
|
-
a single global thread pool for all queries. By default, Rails will set `async_query_executor`
|
2008
|
-
to `nil` which will not initialize any executor. If `load_async` is called and no executor
|
2009
|
-
has been configured, the query will be executed in the foreground.
|
2010
|
-
|
2011
|
-
To create one thread pool for all database connections to use applications can set
|
2012
|
-
`config.active_record.async_query_executor` to `:global_thread_pool` and optionally define
|
2013
|
-
`config.active_record.global_executor_concurrency`. This defaults to 4. For applications that want
|
2014
|
-
to have a thread pool for each database connection, `config.active_record.async_query_executor` can
|
2015
|
-
be set to `:multi_thread_pool`. The configuration for each thread pool is set in the database
|
2016
|
-
configuration.
|
2017
|
-
|
2018
|
-
*Eileen M. Uchitelle*
|
2019
|
-
|
2020
|
-
* Allow new syntax for `enum` to avoid leading `_` from reserved options.
|
2021
|
-
|
2022
|
-
Before:
|
2023
|
-
|
2024
|
-
```ruby
|
2025
|
-
class Book < ActiveRecord::Base
|
2026
|
-
enum status: [ :proposed, :written ], _prefix: true, _scopes: false
|
2027
|
-
enum cover: [ :hard, :soft ], _suffix: true, _default: :hard
|
2028
|
-
end
|
2029
|
-
```
|
2030
|
-
|
2031
|
-
After:
|
2032
|
-
|
2033
|
-
```ruby
|
2034
|
-
class Book < ActiveRecord::Base
|
2035
|
-
enum :status, [ :proposed, :written ], prefix: true, scopes: false
|
2036
|
-
enum :cover, [ :hard, :soft ], suffix: true, default: :hard
|
2037
|
-
end
|
2038
|
-
```
|
2039
|
-
|
2040
|
-
*Ryuta Kamizono*
|
2041
|
-
|
2042
|
-
* Add `ActiveRecord::Relation#load_async`.
|
2043
|
-
|
2044
|
-
This method schedules the query to be performed asynchronously from a thread pool.
|
2045
|
-
|
2046
|
-
If the result is accessed before a background thread had the opportunity to perform
|
2047
|
-
the query, it will be performed in the foreground.
|
2048
|
-
|
2049
|
-
This is useful for queries that can be performed long enough before their result will be
|
2050
|
-
needed, or for controllers which need to perform several independent queries.
|
2051
|
-
|
2052
|
-
```ruby
|
2053
|
-
def index
|
2054
|
-
@categories = Category.some_complex_scope.load_async
|
2055
|
-
@posts = Post.some_complex_scope.load_async
|
2056
|
-
end
|
2057
|
-
```
|
2058
|
-
|
2059
|
-
Active Record logs will also include timing info for the duration of how long
|
2060
|
-
the main thread had to wait to access the result. This timing is useful to know
|
2061
|
-
whether or not it's worth to load the query asynchronously.
|
2062
|
-
|
2063
|
-
```
|
2064
|
-
DEBUG -- : Category Load (62.1ms) SELECT * FROM `categories` LIMIT 50
|
2065
|
-
DEBUG -- : ASYNC Post Load (64ms) (db time 126.1ms) SELECT * FROM `posts` LIMIT 100
|
2066
|
-
```
|
2067
|
-
|
2068
|
-
The duration in the first set of parens is how long the main thread was blocked
|
2069
|
-
waiting for the results, and the second set of parens with "db time" is how long
|
2070
|
-
the entire query took to execute.
|
2071
|
-
|
2072
|
-
*Jean Boussier*
|
2073
|
-
|
2074
|
-
* Implemented `ActiveRecord::Relation#excluding` method.
|
2075
|
-
|
2076
|
-
This method excludes the specified record (or collection of records) from
|
2077
|
-
the resulting relation:
|
2078
|
-
|
2079
|
-
```ruby
|
2080
|
-
Post.excluding(post)
|
2081
|
-
Post.excluding(post_one, post_two)
|
2082
|
-
```
|
2083
|
-
|
2084
|
-
Also works on associations:
|
2085
|
-
|
2086
|
-
```ruby
|
2087
|
-
post.comments.excluding(comment)
|
2088
|
-
post.comments.excluding(comment_one, comment_two)
|
2089
|
-
```
|
2090
|
-
|
2091
|
-
This is short-hand for `Post.where.not(id: post.id)` (for a single record)
|
2092
|
-
and `Post.where.not(id: [post_one.id, post_two.id])` (for a collection).
|
2093
|
-
|
2094
|
-
*Glen Crawford*
|
2095
|
-
|
2096
|
-
* Skip optimised #exist? query when #include? is called on a relation
|
2097
|
-
with a having clause.
|
2098
|
-
|
2099
|
-
Relations that have aliased select values AND a having clause that
|
2100
|
-
references an aliased select value would generate an error when
|
2101
|
-
#include? was called, due to an optimisation that would generate
|
2102
|
-
call #exists? on the relation instead, which effectively alters
|
2103
|
-
the select values of the query (and thus removes the aliased select
|
2104
|
-
values), but leaves the having clause intact. Because the having
|
2105
|
-
clause is then referencing an aliased column that is no longer
|
2106
|
-
present in the simplified query, an ActiveRecord::InvalidStatement
|
2107
|
-
error was raised.
|
2108
|
-
|
2109
|
-
A sample query affected by this problem:
|
2110
|
-
|
2111
|
-
```ruby
|
2112
|
-
Author.select('COUNT(*) as total_posts', 'authors.*')
|
2113
|
-
.joins(:posts)
|
2114
|
-
.group(:id)
|
2115
|
-
.having('total_posts > 2')
|
2116
|
-
.include?(Author.first)
|
2117
|
-
```
|
2118
|
-
|
2119
|
-
This change adds an addition check to the condition that skips the
|
2120
|
-
simplified #exists? query, which simply checks for the presence of
|
2121
|
-
a having clause.
|
2122
|
-
|
2123
|
-
Fixes #41417.
|
2124
|
-
|
2125
|
-
*Michael Smart*
|
2126
|
-
|
2127
|
-
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
2128
|
-
without Rails knowledge (e.g., if app gets killed during long-running query or due to Rack::Timeout), app won't end
|
2129
|
-
up in perpetual crash state for being inconsistent with PostgreSQL.
|
2130
|
-
|
2131
|
-
*wbharding*, *Martin Tepper*
|
2132
|
-
|
2133
|
-
* Add ability to apply `scoping` to `all_queries`.
|
2134
|
-
|
2135
|
-
Some applications may want to use the `scoping` method but previously it only
|
2136
|
-
worked on certain types of queries. This change allows the `scoping` method to apply
|
2137
|
-
to all queries for a model in a block.
|
2138
|
-
|
2139
|
-
```ruby
|
2140
|
-
Post.where(blog_id: post.blog_id).scoping(all_queries: true) do
|
2141
|
-
post.update(title: "a post title") # adds `posts.blog_id = 1` to the query
|
2142
|
-
end
|
2143
|
-
```
|
2144
|
-
|
2145
|
-
*Eileen M. Uchitelle*
|
2146
|
-
|
2147
|
-
* `ActiveRecord::Calculations.calculate` called with `:average`
|
2148
|
-
(aliased as `ActiveRecord::Calculations.average`) will now use column-based
|
2149
|
-
type casting. This means that floating-point number columns will now be
|
2150
|
-
aggregated as `Float` and decimal columns will be aggregated as `BigDecimal`.
|
2151
|
-
|
2152
|
-
Integers are handled as a special case returning `BigDecimal` always
|
2153
|
-
(this was the case before already).
|
983
|
+
* When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
|
984
|
+
adapter. This allows decoupling the adapter the application chooses to use from the database connection details
|
985
|
+
set in the deployment environment.
|
2154
986
|
|
2155
987
|
```ruby
|
2156
|
-
#
|
2157
|
-
|
2158
|
-
|
2159
|
-
end
|
2160
|
-
|
2161
|
-
# Before:
|
2162
|
-
Measurement.average(:temperature).class
|
2163
|
-
# => BigDecimal
|
2164
|
-
|
2165
|
-
# After:
|
2166
|
-
Measurement.average(:temperature).class
|
2167
|
-
# => Float
|
988
|
+
# ENV['DATABASE_URL'] = "mysql://localhost/example_database"
|
989
|
+
config.active_record.protocol_adapters.mysql = "trilogy"
|
990
|
+
# will connect to MySQL using the trilogy adapter
|
2168
991
|
```
|
2169
992
|
|
2170
|
-
|
2171
|
-
database adapter. This is not the case anymore. If you relied on that kind
|
2172
|
-
of magic, you now need to register your own `ActiveRecord::Type`
|
2173
|
-
(see `ActiveRecord::Attributes::ClassMethods` for documentation).
|
2174
|
-
|
2175
|
-
*Josua Schmid*
|
993
|
+
*Jean Boussier*, *Kevin McPhillips*
|
2176
994
|
|
2177
|
-
*
|
995
|
+
* In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
|
996
|
+
the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
|
997
|
+
called with a generic warning message rather than silently ignoring the warning(s).
|
2178
998
|
|
2179
|
-
|
2180
|
-
a migration or schema. It takes a symbol which must correspond to one of the configured
|
2181
|
-
`NATIVE_DATABASE_TYPES`. The default is `:timestamp`, meaning `t.datetime` in a migration
|
2182
|
-
will create a "timestamp without time zone" column. To use "timestamp with time zone",
|
2183
|
-
change this to `:timestamptz` in an initializer.
|
2184
|
-
|
2185
|
-
You should run `bin/rails db:migrate` to rebuild your schema.rb if you change this.
|
2186
|
-
|
2187
|
-
*Alex Ghiculescu*
|
2188
|
-
|
2189
|
-
* PostgreSQL: handle `timestamp with time zone` columns correctly in `schema.rb`.
|
999
|
+
*Kevin McPhillips*
|
2190
1000
|
|
2191
|
-
|
2192
|
-
and are created as `timestamptz` columns when the schema is loaded.
|
1001
|
+
* `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
|
2193
1002
|
|
2194
|
-
*
|
1003
|
+
*Andrew Novoselac*
|
2195
1004
|
|
2196
|
-
*
|
2197
|
-
`ActiveRecord::
|
1005
|
+
* Fix `where(field: values)` queries when `field` is a serialized attribute
|
1006
|
+
(for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
|
1007
|
+
column).
|
2198
1008
|
|
2199
|
-
*
|
1009
|
+
*João Alves*
|
2200
1010
|
|
2201
|
-
*
|
1011
|
+
* Make the output of `ActiveRecord::Core#inspect` configurable.
|
2202
1012
|
|
2203
|
-
|
2204
|
-
named `ApplicationRecord` can now set a specific class to be the `primary_abstract_class`.
|
1013
|
+
By default, calling `inspect` on a record will yield a formatted string including just the `id`.
|
2205
1014
|
|
2206
1015
|
```ruby
|
2207
|
-
|
2208
|
-
self.primary_abstract_class
|
2209
|
-
end
|
1016
|
+
Post.first.inspect #=> "#<Post id: 1>"
|
2210
1017
|
```
|
2211
1018
|
|
2212
|
-
|
2213
|
-
|
2214
|
-
needs to know that the default connection is the same as the `ApplicationRecord` connection.
|
2215
|
-
However, some applications have a differently named `ApplicationRecord`. This prevents Active
|
2216
|
-
Record from opening duplicate connections to the same database.
|
2217
|
-
|
2218
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
2219
|
-
|
2220
|
-
* Support hash config for `structure_dump_flags` and `structure_load_flags` flags.
|
2221
|
-
Now that Active Record supports multiple databases configuration,
|
2222
|
-
we need a way to pass specific flags for dump/load databases since
|
2223
|
-
the options are not the same for different adapters.
|
2224
|
-
We can use in the original way:
|
1019
|
+
The attributes to be included in the output of `inspect` can be configured with
|
1020
|
+
`ActiveRecord::Core#attributes_for_inspect`.
|
2225
1021
|
|
2226
1022
|
```ruby
|
2227
|
-
|
2228
|
-
|
2229
|
-
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table'
|
1023
|
+
Post.attributes_for_inspect = [:id, :title]
|
1024
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
|
2230
1025
|
```
|
2231
1026
|
|
2232
|
-
|
2233
|
-
is the adapter
|
1027
|
+
With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
|
2234
1028
|
|
2235
1029
|
```ruby
|
2236
|
-
|
2237
|
-
|
2238
|
-
postgres: '--no-tablespaces'
|
2239
|
-
}
|
1030
|
+
Post.attributes_for_inspect = :all
|
1031
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
2240
1032
|
```
|
2241
1033
|
|
2242
|
-
|
1034
|
+
In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
|
2243
1035
|
|
2244
|
-
|
2245
|
-
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
2246
|
-
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
2247
|
-
are assumed to be adapter specification urls.
|
1036
|
+
You can also call `full_inspect` to get an inspection with all the attributes.
|
2248
1037
|
|
2249
|
-
|
1038
|
+
The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
|
2250
1039
|
|
2251
|
-
*
|
2252
|
-
|
2253
|
-
* Allow to opt-out of `strict_loading` mode on a per-record base.
|
2254
|
-
|
2255
|
-
This is useful when strict loading is enabled application wide or on a
|
2256
|
-
model level.
|
2257
|
-
|
2258
|
-
```ruby
|
2259
|
-
class User < ApplicationRecord
|
2260
|
-
has_many :bookmarks
|
2261
|
-
has_many :articles, strict_loading: true
|
2262
|
-
end
|
1040
|
+
*Andrew Novoselac*
|
2263
1041
|
|
2264
|
-
|
2265
|
-
|
2266
|
-
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
1042
|
+
* Don't mark attributes as changed when reassigned to `Float::INFINITY` or
|
1043
|
+
`-Float::INFINITY`.
|
2267
1044
|
|
2268
|
-
|
2269
|
-
user.bookmarks # => ActiveRecord::StrictLoadingViolationError
|
1045
|
+
*Maicol Bentancor*
|
2270
1046
|
|
2271
|
-
|
2272
|
-
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
2273
|
-
user.articles.strict_loading!(false) # => #<ActiveRecord::Associations::CollectionProxy>
|
2274
|
-
```
|
1047
|
+
* Support the `RETURNING` clause for MariaDB.
|
2275
1048
|
|
2276
|
-
*
|
1049
|
+
*fatkodima*, *Nikolay Kondratyev*
|
2277
1050
|
|
2278
|
-
*
|
2279
|
-
presence of exactly one record.
|
1051
|
+
* The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
|
2280
1052
|
|
2281
|
-
|
2282
|
-
multiple rows matching the condition; especially for when database
|
2283
|
-
constraints aren't enough or are impractical.
|
1053
|
+
Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
|
2284
1054
|
|
2285
1055
|
```ruby
|
2286
|
-
|
2287
|
-
|
2288
|
-
# => #<Product ...> (if one Product with given price)
|
2289
|
-
# => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
|
2290
|
-
|
2291
|
-
user.api_keys.find_sole_by(key: key)
|
2292
|
-
# as above
|
1056
|
+
add_reference :person, :alias, foreign_key: { deferrable: :deferred }
|
1057
|
+
add_reference :alias, :person, foreign_key: { deferrable: :deferred }
|
2293
1058
|
```
|
2294
1059
|
|
2295
|
-
*
|
1060
|
+
*Stephen Margheim*
|
2296
1061
|
|
2297
|
-
*
|
2298
|
-
|
2299
|
-
Before:
|
1062
|
+
* Add the `set_constraints` helper to PostgreSQL connections.
|
2300
1063
|
|
2301
1064
|
```ruby
|
2302
|
-
|
2303
|
-
def admin
|
2304
|
-
false # Overriding the getter to always return false
|
2305
|
-
end
|
2306
|
-
end
|
2307
|
-
|
2308
|
-
user = User.first
|
2309
|
-
user.update(admin: true)
|
2310
|
-
|
2311
|
-
user.admin # false (as expected, due to the getter overwrite)
|
2312
|
-
user.admin? # true (not expected, returned the DB column value)
|
2313
|
-
```
|
2314
|
-
|
2315
|
-
After this commit, `user.admin?` above returns false, as expected.
|
1065
|
+
Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
|
2316
1066
|
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
Since delegated_type assumes that the foreign_key ends with `_id`,
|
2324
|
-
`singular_id` defined by it does not work when the foreign_key does
|
2325
|
-
not end with `id`. This change fixes it by taking into account
|
2326
|
-
`primary_key` and `foreign_key` in the options.
|
2327
|
-
|
2328
|
-
*Ryota Egusa*
|
2329
|
-
|
2330
|
-
* Expose an `invert_where` method that will invert all scope conditions.
|
2331
|
-
|
2332
|
-
```ruby
|
2333
|
-
class User
|
2334
|
-
scope :active, -> { where(accepted: true, locked: false) }
|
1067
|
+
Post.transaction do
|
1068
|
+
Post.connection.set_constraints(:deferred)
|
1069
|
+
p = Post.create!(user_id: -1)
|
1070
|
+
u = User.create!
|
1071
|
+
p.user = u
|
1072
|
+
p.save!
|
2335
1073
|
end
|
2336
|
-
|
2337
|
-
User.active
|
2338
|
-
# ... WHERE `accepted` = 1 AND `locked` = 0
|
2339
|
-
|
2340
|
-
User.active.invert_where
|
2341
|
-
# ... WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
2342
|
-
```
|
2343
|
-
|
2344
|
-
*Kevin Deisz*
|
2345
|
-
|
2346
|
-
* Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
|
2347
|
-
|
2348
|
-
Previously, passing `false` would trigger the option validation logic
|
2349
|
-
to throw an error saying :polymorphic would not be a valid option.
|
2350
|
-
|
2351
|
-
*glaszig*
|
2352
|
-
|
2353
|
-
* Remove deprecated `database` kwarg from `connected_to`.
|
2354
|
-
|
2355
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
2356
|
-
|
2357
|
-
* Allow adding nonnamed expression indexes to be revertible.
|
2358
|
-
|
2359
|
-
Previously, the following code would raise an error, when executed while rolling back,
|
2360
|
-
and the index name should be specified explicitly. Now, the index name is inferred
|
2361
|
-
automatically.
|
2362
|
-
|
2363
|
-
```ruby
|
2364
|
-
add_index(:items, "to_tsvector('english', description)")
|
2365
1074
|
```
|
2366
1075
|
|
2367
|
-
|
2368
|
-
|
2369
|
-
*fatkodima*
|
2370
|
-
|
2371
|
-
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
2372
|
-
|
2373
|
-
Fixes #39065.
|
1076
|
+
*Cody Cutrer*
|
2374
1077
|
|
2375
|
-
|
1078
|
+
* Include `ActiveModel::API` in `ActiveRecord::Base`.
|
2376
1079
|
|
2377
|
-
*
|
1080
|
+
*Sean Doyle*
|
2378
1081
|
|
2379
|
-
|
1082
|
+
* Ensure `#signed_id` outputs `url_safe` strings.
|
2380
1083
|
|
2381
|
-
|
1084
|
+
*Jason Meller*
|
2382
1085
|
|
2383
|
-
|
2384
|
-
class Article < ApplicationRecord
|
2385
|
-
default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
|
2386
|
-
end
|
2387
|
-
```
|
1086
|
+
* Add `nulls_last` and working `desc.nulls_first` for MySQL.
|
2388
1087
|
|
2389
|
-
*
|
1088
|
+
*Tristan Fellows*
|
2390
1089
|
|
2391
|
-
*
|
1090
|
+
* Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
|
2392
1091
|
|
2393
1092
|
```ruby
|
2394
|
-
|
2395
|
-
account.users.joins(:contact).where.not(contact_id: nil)
|
2396
|
-
|
2397
|
-
# After:
|
2398
|
-
account.users.where.associated(:contact)
|
1093
|
+
Topic.includes(:posts).order(posts: { created_at: :desc })
|
2399
1094
|
```
|
2400
1095
|
|
2401
|
-
|
2402
|
-
|
2403
|
-
*Kasper Timm Hansen*
|
2404
|
-
|
2405
|
-
* Allow constructors (`build_association` and `create_association`) on
|
2406
|
-
`has_one :through` associations.
|
2407
|
-
|
2408
|
-
*Santiago Perez Perret*
|
2409
|
-
|
1096
|
+
*Myles Boone*
|
2410
1097
|
|
2411
|
-
Please check [
|
1098
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.
|