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