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