activerecord 7.0.0 → 7.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 +515 -1268
- data/MIT-LICENSE +1 -1
- data/README.rdoc +31 -31
- 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 +28 -17
- data/lib/active_record/associations/collection_proxy.rb +36 -13
- 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 +28 -18
- data/lib/active_record/associations/has_many_through_association.rb +10 -6
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
- data/lib/active_record/associations/join_dependency.rb +18 -14
- 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 +2 -4
- 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 +378 -491
- data/lib/active_record/attribute_assignment.rb +1 -13
- 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 +153 -70
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -6
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +153 -40
- data/lib/active_record/attributes.rb +63 -48
- data/lib/active_record/autosave_association.rb +70 -38
- data/lib/active_record/base.rb +12 -8
- data/lib/active_record/callbacks.rb +16 -32
- 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 -34
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +124 -132
- 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 +297 -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 +215 -63
- data/lib/active_record/connection_adapters/abstract/quoting.rb +83 -65
- 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 +163 -29
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +319 -135
- data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +512 -126
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +282 -119
- 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 +27 -140
- data/lib/active_record/connection_adapters/mysql/quoting.rb +64 -52
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
- 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 +16 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +101 -48
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
- 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 +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +94 -61
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +6 -10
- 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 +379 -66
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +370 -203
- 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 +61 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +64 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +321 -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 +98 -106
- data/lib/active_record/core.rb +220 -177
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -2
- 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 +88 -35
- data/lib/active_record/delegated_type.rb +40 -11
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/disable_joins_association_relation.rb +1 -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 +13 -14
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +8 -4
- data/lib/active_record/encryption/derived_secret_key_provider.rb +9 -3
- data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +47 -25
- data/lib/active_record/encryption/encrypted_attribute_type.rb +49 -14
- data/lib/active_record/encryption/encryptor.rb +25 -10
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +83 -86
- 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/message.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 +4 -4
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +23 -22
- data/lib/active_record/encryption.rb +1 -0
- data/lib/active_record/enum.rb +131 -27
- data/lib/active_record/errors.rb +151 -31
- data/lib/active_record/explain.rb +21 -12
- data/lib/active_record/explain_subscriber.rb +1 -1
- 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 +169 -99
- data/lib/active_record/future_result.rb +47 -8
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +34 -18
- data/lib/active_record/insert_all.rb +72 -22
- data/lib/active_record/integration.rb +13 -10
- data/lib/active_record/internal_metadata.rb +124 -20
- data/lib/active_record/locking/optimistic.rb +39 -24
- data/lib/active_record/locking/pessimistic.rb +8 -5
- data/lib/active_record/log_subscriber.rb +28 -27
- data/lib/active_record/marshalling.rb +56 -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 +18 -13
- data/lib/active_record/middleware/shard_selector.rb +7 -5
- data/lib/active_record/migration/command_recorder.rb +110 -13
- data/lib/active_record/migration/compatibility.rb +174 -64
- 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 +292 -125
- data/lib/active_record/model_schema.rb +113 -112
- data/lib/active_record/nested_attributes.rb +35 -9
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +177 -345
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +19 -25
- data/lib/active_record/query_logs.rb +102 -51
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +34 -9
- data/lib/active_record/railtie.rb +153 -100
- data/lib/active_record/railties/controller_runtime.rb +24 -10
- data/lib/active_record/railties/databases.rake +148 -152
- 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 +278 -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 +293 -108
- data/lib/active_record/relation/delegation.rb +31 -20
- 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 +38 -4
- 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 +25 -1
- data/lib/active_record/relation/query_methods.rb +625 -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 +602 -96
- data/lib/active_record/result.rb +55 -52
- data/lib/active_record/runtime_registry.rb +63 -1
- data/lib/active_record/sanitization.rb +76 -30
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +82 -30
- data/lib/active_record/schema_migration.rb +75 -24
- data/lib/active_record/scoping/default.rb +20 -12
- 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/serialization.rb +5 -0
- data/lib/active_record/signed_id.rb +29 -8
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +16 -11
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +7 -3
- data/lib/active_record/tasks/database_tasks.rb +191 -121
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +17 -15
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_fixtures.rb +174 -152
- 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 +109 -27
- data/lib/active_record/translation.rb +1 -3
- 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 +9 -7
- 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 +12 -6
- 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 +63 -14
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +266 -30
- 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/filter_predications.rb +1 -1
- 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/filter.rb +1 -1
- 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} +9 -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/to_sql.rb +112 -34
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +21 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +59 -17
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
data/CHANGELOG.md
CHANGED
|
@@ -1,1697 +1,944 @@
|
|
|
1
|
-
## Rails 7.
|
|
1
|
+
## Rails 7.2.1 (August 22, 2024) ##
|
|
2
2
|
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
```ruby
|
|
6
|
-
Post.create(name: "broken \xC8 UTF-8")
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
Would cause all adapters to fail in a non controlled way in the code
|
|
10
|
-
responsible to detect write queries.
|
|
11
|
-
|
|
12
|
-
The query is now properly passed to the database connection, which might or might
|
|
13
|
-
not be able to handle it, but will either succeed or failed in a more correct way.
|
|
14
|
-
|
|
15
|
-
*Jean Boussier*
|
|
16
|
-
|
|
17
|
-
* Move database and shard selection config options to a generator.
|
|
18
|
-
|
|
19
|
-
Rather than generating the config options in `production.rb` when applications are created, applications can now run a generator to create an initializer and uncomment / update options as needed. All multi-db configuration can be implemented in this initializer.
|
|
20
|
-
|
|
21
|
-
*Eileen M. Uchitelle*
|
|
22
|
-
|
|
23
|
-
## Rails 7.0.0.rc3 (December 14, 2021) ##
|
|
24
|
-
|
|
25
|
-
* No changes.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## Rails 7.0.0.rc2 (December 14, 2021) ##
|
|
29
|
-
|
|
30
|
-
* No changes.
|
|
31
|
-
|
|
32
|
-
## Rails 7.0.0.rc1 (December 06, 2021) ##
|
|
33
|
-
|
|
34
|
-
* Remove deprecated `ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name`.
|
|
35
|
-
|
|
36
|
-
*Rafael Mendonça França*
|
|
37
|
-
|
|
38
|
-
* Remove deprecated `ActiveRecord::Connection#in_clause_length`.
|
|
39
|
-
|
|
40
|
-
*Rafael Mendonça França*
|
|
41
|
-
|
|
42
|
-
* Remove deprecated `ActiveRecord::Connection#allowed_index_name_length`.
|
|
3
|
+
* Fix detection for `enum` columns with parallelized tests and PostgreSQL.
|
|
43
4
|
|
|
44
5
|
*Rafael Mendonça França*
|
|
45
6
|
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
*Rafael Mendonça França*
|
|
49
|
-
|
|
50
|
-
* Load STI Models in fixtures
|
|
51
|
-
|
|
52
|
-
Data from Fixtures now loads based on the specific class for models with
|
|
53
|
-
Single Table Inheritance. This affects enums defined in subclasses, previously
|
|
54
|
-
the value of these fields was not parsed and remained `nil`
|
|
55
|
-
|
|
56
|
-
*Andres Howard*
|
|
57
|
-
|
|
58
|
-
* `#authenticate` returns false when the password is blank instead of raising an error.
|
|
59
|
-
|
|
60
|
-
*Muhammad Muhammad Ibrahim*
|
|
7
|
+
* Allow to eager load nested nil associations.
|
|
61
8
|
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
`ActiveRecord::QueryMethods#in_order_of` didn't work as expected for enums stored as integers in the database when passing an array of strings or symbols as the order argument. This unexpected behavior occurred because the string or symbol values were not casted to match the integers in the database.
|
|
65
|
-
|
|
66
|
-
The following example now works as expected:
|
|
67
|
-
|
|
68
|
-
```ruby
|
|
69
|
-
class Book < ApplicationRecord
|
|
70
|
-
enum status: [:proposed, :written, :published]
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
Book.in_order_of(:status, %w[written published proposed])
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
*Alexandre Ruban*
|
|
77
|
-
|
|
78
|
-
* Ignore persisted in-memory records when merging target lists.
|
|
79
|
-
|
|
80
|
-
*Kevin Sjöberg*
|
|
81
|
-
|
|
82
|
-
* Add a new option `:update_only` to `upsert_all` to configure the list of columns to update in case of conflict.
|
|
83
|
-
|
|
84
|
-
Before, you could only customize the update SQL sentence via `:on_duplicate`. There is now a new option `:update_only` that lets you provide a list of columns to update in case of conflict:
|
|
85
|
-
|
|
86
|
-
```ruby
|
|
87
|
-
Commodity.upsert_all(
|
|
88
|
-
[
|
|
89
|
-
{ id: 2, name: "Copper", price: 4.84 },
|
|
90
|
-
{ id: 4, name: "Gold", price: 1380.87 },
|
|
91
|
-
{ id: 6, name: "Aluminium", price: 0.35 }
|
|
92
|
-
],
|
|
93
|
-
update_only: [:price] # Only prices will be updated
|
|
94
|
-
)
|
|
95
|
-
```
|
|
9
|
+
*fatkodima*
|
|
96
10
|
|
|
97
|
-
|
|
11
|
+
* Fix swallowing ignore order warning when batching using `BatchEnumerator`.
|
|
98
12
|
|
|
99
|
-
*
|
|
13
|
+
*fatkodima*
|
|
100
14
|
|
|
101
|
-
|
|
15
|
+
* Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
|
|
102
16
|
|
|
103
|
-
*
|
|
17
|
+
*Jean Boussier*
|
|
104
18
|
|
|
105
|
-
|
|
19
|
+
* Restore inferred association class with the same modularized name.
|
|
106
20
|
|
|
107
|
-
*
|
|
21
|
+
*Justin Ko*
|
|
108
22
|
|
|
109
|
-
|
|
23
|
+
* Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
|
|
110
24
|
|
|
111
|
-
*
|
|
25
|
+
*Jean Boussier*
|
|
112
26
|
|
|
113
|
-
|
|
27
|
+
* Check invalid `enum` options for the new syntax.
|
|
114
28
|
|
|
115
|
-
|
|
29
|
+
The options using `_` prefix in the old syntax are invalid in the new syntax.
|
|
116
30
|
|
|
117
31
|
*Rafael Mendonça França*
|
|
118
32
|
|
|
119
|
-
*
|
|
120
|
-
|
|
121
|
-
Previously, SQL queries in logs containing `ActiveRecord::Base.filter_attributes` were not filtered.
|
|
122
|
-
|
|
123
|
-
Now, the filter attributes will be masked `[FILTERED]` in the logs when `prepared_statement` is enabled.
|
|
33
|
+
* Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
|
|
34
|
+
actual cast type.
|
|
124
35
|
|
|
125
|
-
|
|
126
|
-
# Before:
|
|
127
|
-
Foo Load (0.2ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "hello"], ["LIMIT", 1]]
|
|
128
|
-
|
|
129
|
-
# After:
|
|
130
|
-
Foo Load (0.5ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "[FILTERED]"], ["LIMIT", 1]]
|
|
131
|
-
```
|
|
36
|
+
*Vasiliy Ermolovich*
|
|
132
37
|
|
|
133
|
-
|
|
38
|
+
* Fix `create_table` with `:auto_increment` option for MySQL adapter.
|
|
134
39
|
|
|
135
|
-
*
|
|
136
|
-
|
|
137
|
-
*Rafael Mendonça França*
|
|
40
|
+
*fatkodima*
|
|
138
41
|
|
|
139
|
-
* Remove deprecated `Tasks::DatabaseTasks.current_config`.
|
|
140
42
|
|
|
141
|
-
|
|
43
|
+
## Rails 7.2.0 (August 09, 2024) ##
|
|
142
44
|
|
|
143
|
-
*
|
|
45
|
+
* Handle commas in Sqlite3 default function definitions.
|
|
144
46
|
|
|
145
|
-
*
|
|
47
|
+
*Stephen Margheim*
|
|
146
48
|
|
|
147
|
-
*
|
|
49
|
+
* Fixes `validates_associated` raising an exception when configured with a
|
|
50
|
+
singular association and having `index_nested_attribute_errors` enabled.
|
|
148
51
|
|
|
149
|
-
*
|
|
52
|
+
*Martin Spickermann*
|
|
150
53
|
|
|
151
|
-
*
|
|
54
|
+
* The constant `ActiveRecord::ImmutableRelation` has been deprecated because
|
|
55
|
+
we want to reserve that name for a stronger sense of "immutable relation".
|
|
56
|
+
Please use `ActiveRecord::UnmodifiableRelation` instead.
|
|
152
57
|
|
|
153
|
-
*
|
|
58
|
+
*Xavier Noria*
|
|
154
59
|
|
|
155
|
-
*
|
|
60
|
+
* Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
|
|
61
|
+
`DatabaseConfig`.
|
|
156
62
|
|
|
157
|
-
*
|
|
63
|
+
*Hartley McGuire*
|
|
158
64
|
|
|
159
|
-
*
|
|
160
|
-
and will be consistently replaced by the latter condition.
|
|
65
|
+
* Fixed a memory performance issue in Active Record attribute methods definition.
|
|
161
66
|
|
|
162
|
-
|
|
163
|
-
# Rails 6.1 (IN clause is replaced by merger side equality condition)
|
|
164
|
-
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
|
165
|
-
# Rails 6.1 (both conflict conditions exists, deprecated)
|
|
166
|
-
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
|
|
167
|
-
# Rails 6.1 with rewhere to migrate to Rails 7.0's behavior
|
|
168
|
-
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
|
|
169
|
-
# Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
|
|
170
|
-
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
|
171
|
-
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
|
67
|
+
*Jean Boussier*
|
|
172
68
|
|
|
173
|
-
|
|
69
|
+
* Define the new Active Support notification event `start_transaction.active_record`.
|
|
174
70
|
|
|
175
|
-
|
|
71
|
+
This event is fired when database transactions or savepoints start, and
|
|
72
|
+
complements `transaction.active_record`, which is emitted when they finish.
|
|
176
73
|
|
|
177
|
-
|
|
74
|
+
The payload has the transaction (`:transaction`) and the connection (`:connection`).
|
|
178
75
|
|
|
179
|
-
*
|
|
76
|
+
*Xavier Noria*
|
|
180
77
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
* `db:structure:load`
|
|
184
|
-
* `db:structure:load_if_sql`
|
|
185
|
-
* `db:structure:dump:#{name}`
|
|
186
|
-
* `db:structure:load:#{name}`
|
|
187
|
-
* `db:test:load_structure`
|
|
188
|
-
* `db:test:load_structure:#{name}`
|
|
78
|
+
* Fix an issue where the IDs reader method did not return expected results
|
|
79
|
+
for preloaded associations in models using composite primary keys.
|
|
189
80
|
|
|
190
|
-
*
|
|
81
|
+
*Jay Ang*
|
|
191
82
|
|
|
192
|
-
*
|
|
83
|
+
* The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
|
|
193
84
|
|
|
194
|
-
*
|
|
85
|
+
*Xavier Noria*
|
|
195
86
|
|
|
196
|
-
*
|
|
87
|
+
* The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
|
|
197
88
|
|
|
198
|
-
|
|
89
|
+
*Xavier Noria*
|
|
199
90
|
|
|
200
|
-
|
|
201
|
-
to be committed, so in order to avoid this mistake, the transaction block is rolled back.
|
|
91
|
+
* 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.
|
|
202
92
|
|
|
203
|
-
*
|
|
93
|
+
*Xavier Noria*
|
|
204
94
|
|
|
205
|
-
*
|
|
95
|
+
* Fix inference of association model on nested models with the same demodularized name.
|
|
206
96
|
|
|
207
|
-
|
|
97
|
+
E.g. with the following setup:
|
|
208
98
|
|
|
209
99
|
```ruby
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
tenant.shard
|
|
214
|
-
}
|
|
100
|
+
class Nested::Post < ApplicationRecord
|
|
101
|
+
has_one :post, through: :other
|
|
102
|
+
end
|
|
215
103
|
```
|
|
216
104
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
|
220
|
-
|
|
221
|
-
* Remove deprecated support to pass a column to `type_cast`.
|
|
222
|
-
|
|
223
|
-
*Rafael Mendonça França*
|
|
224
|
-
|
|
225
|
-
* Remove deprecated support to type cast to database values `ActiveRecord::Base` objects.
|
|
226
|
-
|
|
227
|
-
*Rafael Mendonça França*
|
|
105
|
+
Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
|
|
228
106
|
|
|
229
|
-
*
|
|
107
|
+
*Joshua Young*
|
|
230
108
|
|
|
231
|
-
|
|
109
|
+
* PostgreSQL `Cidr#change?` detects the address prefix change.
|
|
232
110
|
|
|
233
|
-
*
|
|
111
|
+
*Taketo Takashima*
|
|
234
112
|
|
|
235
|
-
|
|
113
|
+
* Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
|
|
236
114
|
|
|
237
|
-
|
|
115
|
+
Previously, it always returned `nil`.
|
|
238
116
|
|
|
239
|
-
|
|
117
|
+
*fatkodima*
|
|
240
118
|
|
|
241
|
-
|
|
119
|
+
* Support `touch_all` in batches.
|
|
242
120
|
|
|
243
121
|
```ruby
|
|
244
|
-
|
|
122
|
+
Post.in_batches.touch_all
|
|
245
123
|
```
|
|
246
124
|
|
|
247
|
-
*
|
|
125
|
+
*fatkodima*
|
|
248
126
|
|
|
249
|
-
*
|
|
127
|
+
* Add support for `:if_not_exists` and `:force` options to `create_schema`.
|
|
250
128
|
|
|
251
|
-
*
|
|
129
|
+
*fatkodima*
|
|
252
130
|
|
|
253
|
-
*
|
|
131
|
+
* Fix `index_errors` having incorrect index in association validation errors.
|
|
254
132
|
|
|
255
|
-
*
|
|
133
|
+
*lulalala*
|
|
256
134
|
|
|
257
|
-
*
|
|
135
|
+
* Add `index_errors: :nested_attributes_order` mode.
|
|
258
136
|
|
|
259
|
-
|
|
137
|
+
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.
|
|
260
138
|
|
|
261
|
-
*
|
|
139
|
+
*lulalala*
|
|
262
140
|
|
|
263
|
-
|
|
141
|
+
* Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
|
|
264
142
|
|
|
265
|
-
*
|
|
143
|
+
*Joé Dupuis*
|
|
266
144
|
|
|
267
|
-
*
|
|
145
|
+
* Association option `query_constraints` is deprecated in favor of `foreign_key`.
|
|
268
146
|
|
|
269
|
-
*
|
|
147
|
+
*Nikita Vasilevsky*
|
|
270
148
|
|
|
271
|
-
* Add `
|
|
149
|
+
* Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
|
|
272
150
|
|
|
273
|
-
|
|
274
|
-
class Entry < ApplicationRecord
|
|
275
|
-
delegated_type :entryable, types: %w[ Message Comment ]
|
|
276
|
-
accepts_nested_attributes_for :entryable
|
|
277
|
-
end
|
|
151
|
+
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.
|
|
278
152
|
|
|
279
|
-
|
|
280
|
-
# => #<Entry:0x00>
|
|
281
|
-
# id: 1
|
|
282
|
-
# entryable_id: 1,
|
|
283
|
-
# entryable_type: 'Message'
|
|
284
|
-
# ...>
|
|
285
|
-
|
|
286
|
-
entry.entryable
|
|
287
|
-
# => #<Message:0x01>
|
|
288
|
-
# id: 1
|
|
289
|
-
# content: 'Hello world'
|
|
290
|
-
# ...>
|
|
291
|
-
```
|
|
153
|
+
*DHH*
|
|
292
154
|
|
|
293
|
-
|
|
155
|
+
* Added support for recursive common table expressions.
|
|
294
156
|
|
|
295
157
|
```ruby
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
* Use subquery for DELETE with GROUP_BY and HAVING clauses.
|
|
303
|
-
|
|
304
|
-
Prior to this change, deletes with GROUP_BY and HAVING were returning an error.
|
|
305
|
-
|
|
306
|
-
After this change, GROUP_BY and HAVING are valid clauses in DELETE queries, generating the following query:
|
|
307
|
-
|
|
308
|
-
```sql
|
|
309
|
-
DELETE FROM "posts" WHERE "posts"."id" IN (
|
|
310
|
-
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."id" HAVING (count(comments.id) >= 2))
|
|
311
|
-
) [["flagged", "t"]]
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
*Ignacio Chiazzo Cardarello*
|
|
315
|
-
|
|
316
|
-
* Use subquery for UPDATE with GROUP_BY and HAVING clauses.
|
|
317
|
-
|
|
318
|
-
Prior to this change, updates with GROUP_BY and HAVING were being ignored, generating a SQL like this:
|
|
319
|
-
|
|
320
|
-
```sql
|
|
321
|
-
UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
|
|
322
|
-
SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
|
323
|
-
) [["flagged", "t"]]
|
|
158
|
+
Post.with_recursive(
|
|
159
|
+
post_and_replies: [
|
|
160
|
+
Post.where(id: 42),
|
|
161
|
+
Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
|
|
162
|
+
]
|
|
163
|
+
)
|
|
324
164
|
```
|
|
325
165
|
|
|
326
|
-
|
|
166
|
+
Generates the following SQL:
|
|
327
167
|
|
|
328
168
|
```sql
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
*Ignacio Chiazzo Cardarello*
|
|
336
|
-
|
|
337
|
-
* Add support for setting the filename of the schema or structure dump in the database config.
|
|
338
|
-
|
|
339
|
-
Applications may now set their the filename or path of the schema / structure dump file in their database configuration.
|
|
340
|
-
|
|
341
|
-
```yaml
|
|
342
|
-
production:
|
|
343
|
-
primary:
|
|
344
|
-
database: my_db
|
|
345
|
-
schema_dump: my_schema_dump_filename.rb
|
|
346
|
-
animals:
|
|
347
|
-
database: animals_db
|
|
348
|
-
schema_dump: false
|
|
169
|
+
WITH RECURSIVE "post_and_replies" AS (
|
|
170
|
+
(SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
|
|
171
|
+
UNION ALL
|
|
172
|
+
(SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
|
|
173
|
+
)
|
|
174
|
+
SELECT "posts".* FROM "posts"
|
|
349
175
|
```
|
|
350
176
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
*Eileen M. Uchitelle*, *Ryan Kerr*
|
|
354
|
-
|
|
355
|
-
* Add `ActiveRecord::Base.prohibit_shard_swapping` to prevent attempts to change the shard within a block.
|
|
177
|
+
*ClearlyClaire*
|
|
356
178
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
* Filter unchanged attributes with default function from insert query when `partial_inserts` is disabled.
|
|
360
|
-
|
|
361
|
-
*Akshay Birajdar*, *Jacopo Beschi*
|
|
362
|
-
|
|
363
|
-
* Add support for FILTER clause (SQL:2003) to Arel.
|
|
364
|
-
|
|
365
|
-
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.
|
|
366
|
-
|
|
367
|
-
*Andrey Novikov*
|
|
368
|
-
|
|
369
|
-
* Automatically set timestamps on record creation during bulk insert/upsert
|
|
370
|
-
|
|
371
|
-
Prior to this change, only updates during an upsert operation (e.g. `upsert_all`) would touch timestamps (`updated_{at,on}`). Now, record creations also touch timestamp columns (`{created,updated}_{at,on}`).
|
|
372
|
-
|
|
373
|
-
This behaviour is controlled by the `<model>.record_timestamps` config, matching the behaviour of `create`, `update`, etc. It can also be overridden by using the `record_timestamps:` keyword argument.
|
|
374
|
-
|
|
375
|
-
Note that this means `upsert_all` on models with `record_timestamps = false` will no longer touch `updated_{at,on}` automatically.
|
|
376
|
-
|
|
377
|
-
*Sam Bostock*
|
|
378
|
-
|
|
379
|
-
* Don't require `role` when passing `shard` to `connected_to`.
|
|
380
|
-
|
|
381
|
-
`connected_to` can now be called with a `shard` only. Note that `role` is still inherited if `connected_to` calls are nested.
|
|
382
|
-
|
|
383
|
-
*Eileen M. Uchitelle*
|
|
384
|
-
|
|
385
|
-
* Add option to lazily load the schema cache on the connection.
|
|
386
|
-
|
|
387
|
-
Previously, the only way to load the schema cache in Active Record was through the Railtie on boot. This option provides the ability to load the schema cache on the connection after it's been established. Loading the cache lazily on the connection can be beneficial for Rails applications that use multiple databases because it will load the cache at the time the connection is established. Currently Railties doesn't have access to the connections before boot.
|
|
388
|
-
|
|
389
|
-
To use the cache, set `config.active_record.lazily_load_schema_cache = true` in your application configuration. In addition a `schema_cache_path` should be set in your database configuration if you don't want to use the default "db/schema_cache.yml" path.
|
|
390
|
-
|
|
391
|
-
*Eileen M. Uchitelle*
|
|
392
|
-
|
|
393
|
-
* Allow automatic `inverse_of` detection for associations with scopes.
|
|
394
|
-
|
|
395
|
-
Automatic `inverse_of` detection now works for associations with scopes. For
|
|
396
|
-
example, the `comments` association here now automatically detects
|
|
397
|
-
`inverse_of: :post`, so we don't need to pass that option:
|
|
179
|
+
* `validate_constraint` can be called in a `change_table` block.
|
|
398
180
|
|
|
181
|
+
ex:
|
|
399
182
|
```ruby
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
class Comment < ActiveRecord::Base
|
|
405
|
-
belongs_to :post
|
|
183
|
+
change_table :products do |t|
|
|
184
|
+
t.check_constraint "price > discounted_price", name: "price_check", validate: false
|
|
185
|
+
t.validate_check_constraint "price_check"
|
|
406
186
|
end
|
|
407
187
|
```
|
|
408
188
|
|
|
409
|
-
|
|
410
|
-
association has a scope. In this example a scope on the `post` association
|
|
411
|
-
would still prevent Rails from finding the inverse for the `comments`
|
|
412
|
-
association.
|
|
189
|
+
*Cody Cutrer*
|
|
413
190
|
|
|
414
|
-
|
|
191
|
+
* `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
|
|
415
192
|
|
|
193
|
+
Ex:
|
|
416
194
|
```ruby
|
|
417
|
-
|
|
195
|
+
ActiveRecord::Base.connection
|
|
196
|
+
.select_value("select '2024-01-01'::date").class #=> Date
|
|
418
197
|
```
|
|
419
198
|
|
|
420
|
-
*
|
|
421
|
-
|
|
422
|
-
* Accept optional transaction args to `ActiveRecord::Locking::Pessimistic#with_lock`
|
|
199
|
+
*Joé Dupuis*
|
|
423
200
|
|
|
424
|
-
|
|
425
|
-
`isolation:`, and `joinable:`
|
|
201
|
+
* Strict loading using `:n_plus_one_only` does not eagerly load child associations.
|
|
426
202
|
|
|
427
|
-
|
|
203
|
+
With this change, child associations are no longer eagerly loaded, to
|
|
204
|
+
match intended behavior and to prevent non-deterministic order issues caused
|
|
205
|
+
by calling methods like `first` or `last`. As `first` and `last` don't cause
|
|
206
|
+
an N+1 by themselves, calling child associations will no longer raise.
|
|
207
|
+
Fixes #49473.
|
|
428
208
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases,
|
|
432
|
-
but becomes a major limitation when creating related records before the parent record is inserted into the database.
|
|
433
|
-
One example of this is looking up / creating a person via one or more unique alias.
|
|
209
|
+
Before:
|
|
434
210
|
|
|
435
211
|
```ruby
|
|
436
|
-
Person.
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
person = Person
|
|
442
|
-
.create_with(name: "David Heinemeier Hansson")
|
|
443
|
-
.create_or_find_by(id: alias.user_id)
|
|
444
|
-
end
|
|
212
|
+
person = Person.find(1)
|
|
213
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
|
214
|
+
person.posts.first
|
|
215
|
+
# SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
|
|
216
|
+
person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
|
|
445
217
|
```
|
|
446
218
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
By passing the `:deferrable` option to the `add_foreign_key` statement in migrations, it's possible to defer this
|
|
450
|
-
check.
|
|
219
|
+
After:
|
|
451
220
|
|
|
452
221
|
```ruby
|
|
453
|
-
|
|
222
|
+
person = Person.find(1)
|
|
223
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
|
224
|
+
person.posts.first # this is 1+1, not N+1
|
|
225
|
+
# SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
|
|
226
|
+
person.posts.first.firm # no longer raises
|
|
454
227
|
```
|
|
455
228
|
|
|
456
|
-
|
|
457
|
-
`SET CONSTRAINTS ALL DEFERRED` within a transaction. This will cause the foreign keys to be checked after the
|
|
458
|
-
transaction.
|
|
459
|
-
|
|
460
|
-
It's also possible to adjust the default behavior from an immediate check (after the statement), to a deferred check
|
|
461
|
-
(after the transaction):
|
|
229
|
+
*Reid Lynch*
|
|
462
230
|
|
|
463
|
-
|
|
464
|
-
add_foreign_key :aliases, :person, deferrable: :deferred
|
|
465
|
-
```
|
|
231
|
+
* Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
|
|
466
232
|
|
|
467
|
-
*
|
|
233
|
+
*Mike Dalessio*
|
|
468
234
|
|
|
469
|
-
* Allow
|
|
235
|
+
* Allow `ActiveRecord::Base#pluck` to accept hash values.
|
|
470
236
|
|
|
471
|
-
For example:
|
|
472
237
|
```ruby
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
238
|
+
# Before
|
|
239
|
+
Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
|
|
240
|
+
|
|
241
|
+
# After
|
|
242
|
+
Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
|
|
476
243
|
```
|
|
477
244
|
|
|
478
|
-
|
|
245
|
+
*fatkodima*
|
|
479
246
|
|
|
480
|
-
|
|
481
|
-
{ :user=>"user", :password=>"secret", :dbname=>"app", :adapter=>"postgresql" }
|
|
482
|
-
```
|
|
247
|
+
* Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
|
|
483
248
|
|
|
484
|
-
*
|
|
249
|
+
*Kevin McPhillips*
|
|
485
250
|
|
|
486
|
-
*
|
|
251
|
+
* `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
|
|
487
252
|
|
|
488
|
-
|
|
253
|
+
This allows to register callbacks on it.
|
|
489
254
|
|
|
490
255
|
```ruby
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
t.enum :current_mood, enum_type: "mood", default: "happy", null: false
|
|
256
|
+
Article.transaction do |transaction|
|
|
257
|
+
article.update(published: true)
|
|
258
|
+
transaction.after_commit do
|
|
259
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
496
260
|
end
|
|
497
261
|
end
|
|
498
262
|
```
|
|
499
263
|
|
|
500
|
-
|
|
501
|
-
the PostgreSQL adapter.
|
|
502
|
-
|
|
503
|
-
*Alex Ghiculescu*
|
|
504
|
-
|
|
505
|
-
* Avoid COMMENT statements in PostgreSQL structure dumps
|
|
506
|
-
|
|
507
|
-
COMMENT statements are now omitted from the output of `db:structure:dump` when using PostgreSQL >= 11.
|
|
508
|
-
This allows loading the dump without a pgsql superuser account.
|
|
509
|
-
|
|
510
|
-
Fixes #36816, #43107.
|
|
511
|
-
|
|
512
|
-
*Janosch Müller*
|
|
264
|
+
*Jean Boussier*
|
|
513
265
|
|
|
514
|
-
* Add
|
|
266
|
+
* Add `ActiveRecord::Base.current_transaction`.
|
|
515
267
|
|
|
516
|
-
|
|
517
|
-
support of those to the PostgreSQL adapter.
|
|
268
|
+
Returns the current transaction, to allow registering callbacks on it.
|
|
518
269
|
|
|
519
270
|
```ruby
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
t.virtual :name_upcased, type: :string, as: 'upper(name)', stored: true
|
|
271
|
+
Article.current_transaction.after_commit do
|
|
272
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
523
273
|
end
|
|
524
274
|
```
|
|
525
275
|
|
|
526
|
-
*
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
|
530
|
-
|
|
531
|
-
* No changes.
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
|
535
|
-
|
|
536
|
-
* Remove warning when overwriting existing scopes
|
|
537
|
-
|
|
538
|
-
Removes the following unnecessary warning message that appeared when overwriting existing scopes
|
|
539
|
-
|
|
540
|
-
```
|
|
541
|
-
Creating scope :my_scope_name. Overwriting existing method "MyClass.my_scope_name" when overwriting existing scopes
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
*Weston Ganger*
|
|
545
|
-
|
|
546
|
-
* Use full precision for `updated_at` in `insert_all`/`upsert_all`
|
|
547
|
-
|
|
548
|
-
`CURRENT_TIMESTAMP` provides differing precision depending on the database,
|
|
549
|
-
and not all databases support explicitly specifying additional precision.
|
|
550
|
-
|
|
551
|
-
Instead, we delegate to the new `connection.high_precision_current_timestamp`
|
|
552
|
-
for the SQL to produce a high precision timestamp on the current database.
|
|
553
|
-
|
|
554
|
-
Fixes #42992
|
|
555
|
-
|
|
556
|
-
*Sam Bostock*
|
|
557
|
-
|
|
558
|
-
* Add ssl support for postgresql database tasks
|
|
559
|
-
|
|
560
|
-
Add `PGSSLMODE`, `PGSSLCERT`, `PGSSLKEY` and `PGSSLROOTCERT` to pg_env from database config
|
|
561
|
-
when running postgresql database tasks.
|
|
562
|
-
|
|
563
|
-
```yaml
|
|
564
|
-
# config/database.yml
|
|
565
|
-
|
|
566
|
-
production:
|
|
567
|
-
sslmode: verify-full
|
|
568
|
-
sslcert: client.crt
|
|
569
|
-
sslkey: client.key
|
|
570
|
-
sslrootcert: ca.crt
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
Environment variables
|
|
574
|
-
|
|
575
|
-
```
|
|
576
|
-
PGSSLMODE=verify-full
|
|
577
|
-
PGSSLCERT=client.crt
|
|
578
|
-
PGSSLKEY=client.key
|
|
579
|
-
PGSSLROOTCERT=ca.crt
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
Fixes #42994
|
|
583
|
-
|
|
584
|
-
*Michael Bayucot*
|
|
585
|
-
|
|
586
|
-
* Avoid scoping update callbacks in `ActiveRecord::Relation#update!`.
|
|
587
|
-
|
|
588
|
-
Making it consistent with how scoping is applied only to the query in `ActiveRecord::Relation#update`
|
|
589
|
-
and not also to the callbacks from the update itself.
|
|
590
|
-
|
|
591
|
-
*Dylan Thacker-Smith*
|
|
592
|
-
|
|
593
|
-
* Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
|
|
594
|
-
using `String#constantize` instead of the model's `polymorphic_class_for`.
|
|
595
|
-
|
|
596
|
-
When updating a polymorphic association, the old `foreign_type` was not inferred correctly when:
|
|
597
|
-
1. `touch`ing the previously associated record
|
|
598
|
-
2. updating the previously associated record's `counter_cache`
|
|
599
|
-
|
|
600
|
-
*Jimmy Bourassa*
|
|
601
|
-
|
|
602
|
-
* Add config option for ignoring tables when dumping the schema cache.
|
|
276
|
+
*Jean Boussier*
|
|
603
277
|
|
|
604
|
-
|
|
278
|
+
* Add `ActiveRecord.after_all_transactions_commit` callback.
|
|
605
279
|
|
|
606
|
-
|
|
280
|
+
Useful for code that may run either inside or outside a transaction and needs
|
|
281
|
+
to perform work after the state changes have been properly persisted.
|
|
607
282
|
|
|
608
283
|
```ruby
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
config.active_record.schema_cache_ignored_tables = [/^_/]
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
*Eileen M. Uchitelle*
|
|
619
|
-
|
|
620
|
-
* Make schema cache methods return consistent results.
|
|
621
|
-
|
|
622
|
-
Previously the schema cache methods `primary_keys`, `columns`, `columns_hash`, and `indexes`
|
|
623
|
-
would behave differently than one another when a table didn't exist and differently across
|
|
624
|
-
database adapters. This change unifies the behavior so each method behaves the same regardless
|
|
625
|
-
of adapter.
|
|
626
|
-
|
|
627
|
-
The behavior now is:
|
|
628
|
-
|
|
629
|
-
`columns`: (unchanged) raises a db error if the table does not exist.
|
|
630
|
-
`columns_hash`: (unchanged) raises a db error if the table does not exist.
|
|
631
|
-
`primary_keys`: (unchanged) returns `nil` if the table does not exist.
|
|
632
|
-
`indexes`: (changed for mysql2) returns `[]` if the table does not exist.
|
|
633
|
-
|
|
634
|
-
*Eileen M. Uchitelle*
|
|
635
|
-
|
|
636
|
-
* Reestablish connection to previous database after after running `db:schema:load:name`
|
|
637
|
-
|
|
638
|
-
After running `db:schema:load:name` the previous connection is restored.
|
|
639
|
-
|
|
640
|
-
*Jacopo Beschi*
|
|
641
|
-
|
|
642
|
-
* Add database config option `database_tasks`
|
|
643
|
-
|
|
644
|
-
If you would like to connect to an external database without any database
|
|
645
|
-
management tasks such as schema management, migrations, seeds, etc. you can set
|
|
646
|
-
the per database config option `database_tasks: false`
|
|
647
|
-
|
|
648
|
-
```yaml
|
|
649
|
-
# config/database.yml
|
|
650
|
-
|
|
651
|
-
production:
|
|
652
|
-
primary:
|
|
653
|
-
database: my_database
|
|
654
|
-
adapter: mysql2
|
|
655
|
-
animals:
|
|
656
|
-
database: my_animals_database
|
|
657
|
-
adapter: mysql2
|
|
658
|
-
database_tasks: false
|
|
284
|
+
def publish_article(article)
|
|
285
|
+
article.update(published: true)
|
|
286
|
+
ActiveRecord.after_all_transactions_commit do
|
|
287
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
288
|
+
end
|
|
289
|
+
end
|
|
659
290
|
```
|
|
660
291
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
* Fix `ActiveRecord::InternalMetadata` to not be broken by `config.active_record.record_timestamps = false`
|
|
292
|
+
In the above example, the block is either executed immediately if called outside
|
|
293
|
+
of a transaction, or called after the open transaction is committed.
|
|
664
294
|
|
|
665
|
-
|
|
666
|
-
various DB management tasks.
|
|
295
|
+
If the transaction is rolled back, the block isn't called.
|
|
667
296
|
|
|
668
|
-
|
|
297
|
+
*Jean Boussier*
|
|
669
298
|
|
|
670
|
-
* Add
|
|
299
|
+
* Add the ability to ignore counter cache columns until they are backfilled.
|
|
671
300
|
|
|
672
|
-
|
|
301
|
+
Starting to use counter caches on existing large tables can be troublesome, because the column
|
|
302
|
+
values must be backfilled separately of the column addition (to not lock the table for too long)
|
|
303
|
+
and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
|
|
304
|
+
counter caches internally, can produce incorrect results). People usually use database triggers
|
|
305
|
+
or callbacks on child associations while backfilling before introducing a counter cache
|
|
306
|
+
configuration to the association.
|
|
673
307
|
|
|
674
|
-
|
|
675
|
-
# config/application.rb
|
|
676
|
-
module MyApp
|
|
677
|
-
class Application < Rails::Application
|
|
678
|
-
config.active_record.query_log_tags_enabled = true
|
|
679
|
-
end
|
|
680
|
-
end
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
By default the application, controller and action details are added to the query tags:
|
|
308
|
+
Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
|
|
684
309
|
|
|
685
310
|
```ruby
|
|
686
|
-
class
|
|
687
|
-
|
|
688
|
-
@books = Book.all
|
|
689
|
-
end
|
|
311
|
+
class Comment < ApplicationRecord
|
|
312
|
+
belongs_to :post, counter_cache: { active: false }
|
|
690
313
|
end
|
|
691
314
|
```
|
|
692
315
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
316
|
+
While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
|
|
317
|
+
but get the results directly from the database. After the counter cache column is backfilled, simply
|
|
318
|
+
remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
|
|
319
|
+
mentioned methods.
|
|
697
320
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
```ruby
|
|
701
|
-
config.active_record.query_log_tags = [
|
|
702
|
-
:application,
|
|
703
|
-
:controller,
|
|
704
|
-
:action,
|
|
705
|
-
{
|
|
706
|
-
custom_static: "foo",
|
|
707
|
-
custom_dynamic: -> { Time.now }
|
|
708
|
-
}
|
|
709
|
-
]
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
*Keeran Raj Hawoldar*, *Eileen M. Uchitelle*, *Kasper Timm Hansen*
|
|
321
|
+
*fatkodima*
|
|
713
322
|
|
|
714
|
-
*
|
|
323
|
+
* Retry known idempotent SELECT queries on connection-related exceptions.
|
|
715
324
|
|
|
716
|
-
|
|
325
|
+
SELECT queries we construct by walking the Arel tree and / or with known model attributes
|
|
326
|
+
are idempotent and can safely be retried in the case of a connection error. Previously,
|
|
327
|
+
adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
|
|
328
|
+
when encountering a connection error mid-request.
|
|
717
329
|
|
|
718
|
-
*
|
|
330
|
+
*Adrianna Chang*
|
|
719
331
|
|
|
720
|
-
|
|
721
|
-
about to use for `#or` or `#and` is structurally compatible with the
|
|
722
|
-
receiver.
|
|
332
|
+
* Allow association's `foreign_key` to be composite.
|
|
723
333
|
|
|
724
|
-
|
|
334
|
+
`query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
|
|
335
|
+
Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
|
|
725
336
|
|
|
726
|
-
*
|
|
337
|
+
*Nikita Vasilevsky*
|
|
727
338
|
|
|
728
|
-
|
|
729
|
-
returned in based on a SQL expression. By default, this will be accomplished
|
|
730
|
-
using a case statement, as in:
|
|
339
|
+
* Allow association's `primary_key` to be composite.
|
|
731
340
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
```
|
|
341
|
+
Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
|
|
342
|
+
Now it's possible to explicitly set it as composite on the association.
|
|
735
343
|
|
|
736
|
-
|
|
344
|
+
*Nikita Vasilevsky*
|
|
737
345
|
|
|
738
|
-
|
|
739
|
-
SELECT "posts".* FROM "posts" ORDER BY CASE "posts"."id" WHEN 3 THEN 1 WHEN 5 THEN 2 WHEN 1 THEN 3 ELSE 4 END ASC
|
|
740
|
-
```
|
|
346
|
+
* Add `config.active_record.permanent_connection_checkout` setting.
|
|
741
347
|
|
|
742
|
-
|
|
743
|
-
`FIELD` function, that connection adapter will generate the following SQL
|
|
744
|
-
instead:
|
|
348
|
+
Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
|
|
745
349
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
350
|
+
`ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
|
|
351
|
+
the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
|
|
352
|
+
is available connections.
|
|
749
353
|
|
|
750
|
-
|
|
354
|
+
This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
|
|
355
|
+
migrate it to use `ActiveRecord::Base.with_connection` instead.
|
|
751
356
|
|
|
752
|
-
|
|
357
|
+
The default behavior remains unchanged, and there is currently no plans to change the default.
|
|
753
358
|
|
|
754
|
-
|
|
359
|
+
*Jean Boussier*
|
|
755
360
|
|
|
756
|
-
|
|
757
|
-
scope = Post.includes(:comments).order(:"comments.label")
|
|
758
|
-
=> true
|
|
759
|
-
```
|
|
361
|
+
* Add dirties option to uncached.
|
|
760
362
|
|
|
761
|
-
|
|
363
|
+
This adds a `dirties` option to `ActiveRecord::Base.uncached` and
|
|
364
|
+
`ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
|
|
762
365
|
|
|
763
|
-
|
|
366
|
+
When set to `true` (the default), writes will clear all query caches belonging to the current thread.
|
|
367
|
+
When set to `false`, writes to the affected connection pool will not clear any query cache.
|
|
764
368
|
|
|
765
|
-
|
|
766
|
-
if a different associated object has been assigned and the foreign key will be updated in the
|
|
767
|
-
next save.
|
|
369
|
+
This is needed by Solid Cache so that cache writes do not clear query caches.
|
|
768
370
|
|
|
769
|
-
|
|
770
|
-
association to reference a different associated object.
|
|
371
|
+
*Donal McBreen*
|
|
771
372
|
|
|
772
|
-
|
|
373
|
+
* Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
|
|
773
374
|
|
|
774
|
-
|
|
375
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
|
376
|
+
connection will be held for the duration of the request or job.
|
|
775
377
|
|
|
776
|
-
|
|
777
|
-
|
|
378
|
+
This deprecation is a soft deprecation, no warnings will be issued and there is no
|
|
379
|
+
current plan to remove the method.
|
|
778
380
|
|
|
779
|
-
|
|
780
|
-
# config/database.yml
|
|
381
|
+
*Jean Boussier*
|
|
781
382
|
|
|
782
|
-
|
|
783
|
-
schema_dump: false
|
|
784
|
-
```
|
|
383
|
+
* Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
|
|
785
384
|
|
|
786
|
-
|
|
385
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
|
386
|
+
connection will be held for the duration of the request or job.
|
|
787
387
|
|
|
788
|
-
*
|
|
388
|
+
*Jean Boussier*
|
|
789
389
|
|
|
790
|
-
|
|
791
|
-
on an outer table.
|
|
390
|
+
* Expose a generic fixture accessor for fixture names that may conflict with Minitest.
|
|
792
391
|
|
|
793
392
|
```ruby
|
|
794
|
-
|
|
795
|
-
|
|
393
|
+
assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
|
394
|
+
assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
|
|
796
395
|
```
|
|
797
396
|
|
|
798
|
-
*
|
|
799
|
-
|
|
800
|
-
* Move the forcing of clear text encoding to the `ActiveRecord::Encryption::Encryptor`.
|
|
397
|
+
*Jean Boussier*
|
|
801
398
|
|
|
802
|
-
|
|
399
|
+
* Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
|
|
400
|
+
incorrect error message.
|
|
803
401
|
|
|
804
|
-
|
|
402
|
+
This has been fixed to raise with a more appropriate error message.
|
|
805
403
|
|
|
806
|
-
*
|
|
404
|
+
*Joshua Young*
|
|
807
405
|
|
|
808
|
-
|
|
406
|
+
* Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
|
|
809
407
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
```
|
|
408
|
+
This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
|
|
409
|
+
an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
|
|
813
410
|
|
|
814
|
-
|
|
815
|
-
would cause old processes to no longer be able to create new records.
|
|
411
|
+
*Joshua Young*
|
|
816
412
|
|
|
817
|
-
|
|
818
|
-
to stop using it.
|
|
413
|
+
* Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
|
|
819
414
|
|
|
820
|
-
*
|
|
415
|
+
*Rafael Mendonça França*
|
|
821
416
|
|
|
822
|
-
* Rails
|
|
417
|
+
* Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
|
|
823
418
|
|
|
824
|
-
|
|
419
|
+
*Rafael Mendonça França*
|
|
825
420
|
|
|
826
|
-
|
|
827
|
-
config.active_record.verify_foreign_keys_for_fixtures = true
|
|
828
|
-
```
|
|
421
|
+
* Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
|
|
829
422
|
|
|
830
|
-
|
|
423
|
+
*Rafael Mendonça França*
|
|
831
424
|
|
|
832
|
-
|
|
425
|
+
* Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
|
|
833
426
|
|
|
834
|
-
*
|
|
427
|
+
*Rafael Mendonça França*
|
|
835
428
|
|
|
836
|
-
*
|
|
429
|
+
* Remove deprecated support to quote `ActiveSupport::Duration`.
|
|
837
430
|
|
|
838
|
-
|
|
839
|
-
the owner should still return `nil` on the `has_one` relation.
|
|
431
|
+
*Rafael Mendonça França*
|
|
840
432
|
|
|
841
|
-
|
|
433
|
+
* Remove deprecated `#quote_bound_value`.
|
|
842
434
|
|
|
843
|
-
*
|
|
435
|
+
*Rafael Mendonça França*
|
|
844
436
|
|
|
845
|
-
*
|
|
437
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
|
|
846
438
|
|
|
847
|
-
*
|
|
439
|
+
*Rafael Mendonça França*
|
|
848
440
|
|
|
849
|
-
*
|
|
441
|
+
* Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
|
|
442
|
+
`#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
|
|
443
|
+
for the current role when the `role` argument isn't provided.
|
|
850
444
|
|
|
851
|
-
|
|
852
|
-
that already exists or when removing a foreign key that does not exist.
|
|
445
|
+
*Rafael Mendonça França*
|
|
853
446
|
|
|
854
|
-
|
|
447
|
+
* Remove deprecated `#all_connection_pools`.
|
|
855
448
|
|
|
856
|
-
|
|
857
|
-
class AddAuthorsForeignKeyToArticles < ActiveRecord::Migration[7.0]
|
|
858
|
-
def change
|
|
859
|
-
add_foreign_key :articles, :authors, if_not_exists: true
|
|
860
|
-
end
|
|
861
|
-
end
|
|
862
|
-
```
|
|
449
|
+
*Rafael Mendonça França*
|
|
863
450
|
|
|
864
|
-
|
|
865
|
-
class RemoveAuthorsForeignKeyFromArticles < ActiveRecord::Migration[7.0]
|
|
866
|
-
def change
|
|
867
|
-
remove_foreign_key :articles, :authors, if_exists: true
|
|
868
|
-
end
|
|
869
|
-
end
|
|
870
|
-
```
|
|
451
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
|
|
871
452
|
|
|
872
|
-
*
|
|
453
|
+
*Rafael Mendonça França*
|
|
873
454
|
|
|
874
|
-
*
|
|
455
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
|
|
875
456
|
|
|
876
|
-
|
|
877
|
-
environment variables which persisted beyond the command being run, and may
|
|
878
|
-
have caused subsequent commands and connections to fail. Tasks running
|
|
879
|
-
across multiple postgresql databases like `rails db:test:prepare` may have
|
|
880
|
-
been affected.
|
|
457
|
+
*Rafael Mendonça França*
|
|
881
458
|
|
|
882
|
-
|
|
459
|
+
* Remove deprecated `#all_foreign_keys_valid?` from database adapters.
|
|
883
460
|
|
|
884
|
-
*
|
|
461
|
+
*Rafael Mendonça França*
|
|
885
462
|
|
|
886
|
-
|
|
463
|
+
* Remove deprecated support to passing coder and class as second argument to `serialize`.
|
|
887
464
|
|
|
888
|
-
*
|
|
465
|
+
*Rafael Mendonça França*
|
|
889
466
|
|
|
890
|
-
*
|
|
467
|
+
* Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
|
|
891
468
|
|
|
892
|
-
*
|
|
469
|
+
*Rafael Mendonça França*
|
|
893
470
|
|
|
894
|
-
*
|
|
471
|
+
* Remove deprecated `TestFixtures.fixture_path`.
|
|
895
472
|
|
|
896
|
-
*
|
|
473
|
+
*Rafael Mendonça França*
|
|
897
474
|
|
|
898
|
-
*
|
|
899
|
-
encryption. The encoding is part of the encrypted payload, so different encodings for
|
|
900
|
-
different values result in different ciphertexts. This can break unique constraints and
|
|
901
|
-
queries.
|
|
475
|
+
* Remove deprecated behavior to support referring to a singular association by its plural name.
|
|
902
476
|
|
|
903
|
-
|
|
904
|
-
that is `Encoding::UTF_8` by default. It can be disabled by setting it to `nil`.
|
|
477
|
+
*Rafael Mendonça França*
|
|
905
478
|
|
|
906
|
-
|
|
479
|
+
* Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
|
|
907
480
|
|
|
908
|
-
*
|
|
481
|
+
*Rafael Mendonça França*
|
|
909
482
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
lead to security vulnerabilities.
|
|
483
|
+
* Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
|
|
484
|
+
`ActiveRecord::MigrationContext`.
|
|
913
485
|
|
|
914
|
-
|
|
915
|
-
being compared, however until now it was still vulnerable when using bind parameters:
|
|
486
|
+
*Rafael Mendonça França*
|
|
916
487
|
|
|
917
|
-
|
|
918
|
-
User.where("login_token = ?", 0).first
|
|
919
|
-
```
|
|
488
|
+
* Remove deprecated `ActiveRecord::Migration.check_pending!` method.
|
|
920
489
|
|
|
921
|
-
|
|
490
|
+
*Rafael Mendonça França*
|
|
922
491
|
|
|
923
|
-
|
|
924
|
-
SELECT * FROM `users` WHERE `login_token` = 0 LIMIT 1;
|
|
925
|
-
```
|
|
492
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
|
|
926
493
|
|
|
927
|
-
|
|
494
|
+
*Rafael Mendonça França*
|
|
928
495
|
|
|
929
|
-
|
|
930
|
-
SELECT * FROM `users` WHERE `login_token` = '0' LIMIT 1;
|
|
931
|
-
```
|
|
496
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
|
|
932
497
|
|
|
933
|
-
*
|
|
498
|
+
*Rafael Mendonça França*
|
|
934
499
|
|
|
935
|
-
*
|
|
500
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
|
|
936
501
|
|
|
937
|
-
|
|
938
|
-
would silently have no effects.
|
|
502
|
+
*Rafael Mendonça França*
|
|
939
503
|
|
|
940
|
-
|
|
504
|
+
* Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
|
|
941
505
|
|
|
942
|
-
*
|
|
506
|
+
*Rafael Mendonça França*
|
|
943
507
|
|
|
944
|
-
|
|
508
|
+
* Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
|
|
945
509
|
|
|
946
|
-
|
|
947
|
-
Person.update!(:all, state: "confirmed")
|
|
948
|
-
```
|
|
510
|
+
*Rafael Mendonça França*
|
|
949
511
|
|
|
950
|
-
|
|
512
|
+
* Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
|
|
951
513
|
|
|
952
|
-
*
|
|
514
|
+
*Rafael Mendonça França*
|
|
953
515
|
|
|
954
|
-
|
|
516
|
+
* Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
|
|
955
517
|
|
|
956
|
-
*
|
|
518
|
+
*Rafael Mendonça França*
|
|
957
519
|
|
|
958
|
-
*
|
|
520
|
+
* Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
|
|
959
521
|
|
|
960
|
-
|
|
522
|
+
*Rafael Mendonça França*
|
|
961
523
|
|
|
962
|
-
|
|
524
|
+
* Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
|
|
963
525
|
|
|
964
|
-
*
|
|
526
|
+
*Rafael Mendonça França*
|
|
965
527
|
|
|
966
|
-
|
|
528
|
+
* Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
|
|
967
529
|
|
|
968
|
-
*
|
|
530
|
+
*Rafael Mendonça França*
|
|
969
531
|
|
|
970
|
-
|
|
532
|
+
* Remove deprecated support to call `alias_attribute` with non-existent attribute names.
|
|
971
533
|
|
|
972
|
-
*
|
|
534
|
+
*Rafael Mendonça França*
|
|
973
535
|
|
|
974
|
-
*
|
|
536
|
+
* Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
|
|
975
537
|
|
|
976
|
-
|
|
977
|
-
Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
|
|
538
|
+
*Rafael Mendonça França*
|
|
978
539
|
|
|
979
|
-
|
|
540
|
+
* Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
|
|
980
541
|
|
|
981
|
-
|
|
542
|
+
Serialize data to the MessagePack format, for efficient storage in binary columns.
|
|
982
543
|
|
|
983
|
-
|
|
984
|
-
|
|
544
|
+
The binary encoding requires around 30% less space than the base64 encoding
|
|
545
|
+
used by the default serializer.
|
|
985
546
|
|
|
986
|
-
*
|
|
547
|
+
*Donal McBreen*
|
|
987
548
|
|
|
988
|
-
* Add
|
|
549
|
+
* Add support for encrypting binary columns.
|
|
989
550
|
|
|
990
|
-
|
|
551
|
+
Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
|
|
991
552
|
|
|
992
|
-
|
|
553
|
+
Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
|
|
554
|
+
incidentally worked for MySQL and SQLite, but not PostgreSQL.
|
|
993
555
|
|
|
994
|
-
*
|
|
556
|
+
*Donal McBreen*
|
|
995
557
|
|
|
996
|
-
*
|
|
558
|
+
* Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
|
|
997
559
|
|
|
998
|
-
|
|
999
|
-
the `column_exists?` check would look for a column with the same name and type as the migration.
|
|
560
|
+
*Rafael Mendonça França*
|
|
1000
561
|
|
|
1001
|
-
|
|
1002
|
-
as the column after migration. For example a column set to `:mediumblob` in the migration will
|
|
1003
|
-
be casted to `binary` when calling `column.type`. Since there is no straightforward way to cast
|
|
1004
|
-
the type to the database type without running the migration, we opted to drop the type check from
|
|
1005
|
-
`add_column`. This means that migrations adding a duplicate column with a different type will no
|
|
1006
|
-
longer raise an error.
|
|
562
|
+
* Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
|
|
1007
563
|
|
|
1008
|
-
|
|
564
|
+
The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
|
|
565
|
+
will yield that same connection.
|
|
1009
566
|
|
|
1010
|
-
|
|
567
|
+
This is useful to perform a few database operations without causing a connection to be leased for the
|
|
568
|
+
entire duration of the request or job.
|
|
1011
569
|
|
|
1012
|
-
|
|
1013
|
-
in a new Rails application.
|
|
1014
|
-
For the above reasons log a warning message when running SQLite in production.
|
|
570
|
+
*Jean Boussier*
|
|
1015
571
|
|
|
1016
|
-
|
|
572
|
+
* Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
|
|
573
|
+
notification includes `:row_count` field.
|
|
1017
574
|
|
|
1018
|
-
*
|
|
575
|
+
*Jason Nochlin*
|
|
1019
576
|
|
|
1020
|
-
*
|
|
577
|
+
* The fix ensures that the association is joined using the appropriate join type
|
|
578
|
+
(either inner join or left outer join) based on the existing joins in the scope.
|
|
1021
579
|
|
|
1022
|
-
|
|
1023
|
-
databases. When set, this option instructs Rails to generate 2 or
|
|
1024
|
-
more queries rather than generating joins for `has_one` associations.
|
|
580
|
+
This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
|
|
1025
581
|
|
|
1026
|
-
|
|
582
|
+
Example:
|
|
1027
583
|
|
|
1028
|
-
```ruby
|
|
1029
|
-
class Person
|
|
1030
|
-
has_one :dog
|
|
1031
|
-
has_one :veterinarian, through: :dog, disable_joins: true
|
|
1032
|
-
end
|
|
1033
|
-
```
|
|
1034
584
|
|
|
1035
|
-
Then instead of generating join SQL, two queries are used for `@person.veterinarian`:
|
|
1036
585
|
|
|
586
|
+
```ruby
|
|
587
|
+
# `associated` will use `LEFT JOIN` instead of using `JOIN`
|
|
588
|
+
Post.left_joins(:author).where.associated(:author)
|
|
1037
589
|
```
|
|
1038
|
-
SELECT "dogs"."id" FROM "dogs" WHERE "dogs"."person_id" = ? [["person_id", 1]]
|
|
1039
|
-
SELECT "veterinarians".* FROM "veterinarians" WHERE "veterinarians"."dog_id" = ? [["dog_id", 1]]
|
|
1040
|
-
```
|
|
1041
|
-
|
|
1042
|
-
*Sarah Vessels*, *Eileen M. Uchitelle*
|
|
1043
|
-
|
|
1044
|
-
* `Arel::Visitors::Dot` now renders a complete set of properties when visiting
|
|
1045
|
-
`Arel::Nodes::SelectCore`, `SelectStatement`, `InsertStatement`, `UpdateStatement`, and
|
|
1046
|
-
`DeleteStatement`, which fixes #42026. Previously, some properties were omitted.
|
|
1047
590
|
|
|
1048
|
-
*
|
|
591
|
+
*Saleh Alhaddad*
|
|
1049
592
|
|
|
1050
|
-
* `
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
types caused an exception to be raised by `Arel::Visitors::Dot#accept`.
|
|
593
|
+
* Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
|
|
594
|
+
of Active Record models, when an application is eager loaded. As a result, encrypted attributes
|
|
595
|
+
could be misconfigured in some cases.
|
|
1054
596
|
|
|
1055
|
-
*
|
|
597
|
+
*Maxime Réty*
|
|
1056
598
|
|
|
1057
|
-
*
|
|
599
|
+
* Deprecate defining an `enum` with keyword arguments.
|
|
1058
600
|
|
|
1059
601
|
```ruby
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
602
|
+
class Function > ApplicationRecord
|
|
603
|
+
# BAD
|
|
604
|
+
enum color: [:red, :blue],
|
|
605
|
+
type: [:instance, :class]
|
|
1064
606
|
|
|
1065
|
-
|
|
1066
|
-
|
|
607
|
+
# GOOD
|
|
608
|
+
enum :color, [:red, :blue]
|
|
609
|
+
enum :type, [:instance, :class]
|
|
610
|
+
end
|
|
1067
611
|
```
|
|
1068
612
|
|
|
1069
|
-
*
|
|
613
|
+
*Hartley McGuire*
|
|
1070
614
|
|
|
1071
|
-
*
|
|
615
|
+
* Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
|
|
1072
616
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
617
|
+
When set, validates that the timestamp prefix for a migration is no more than a day ahead of
|
|
618
|
+
the timestamp associated with the current time. This is designed to prevent migrations prefixes
|
|
619
|
+
from being hand-edited to future timestamps, which impacts migration generation and other
|
|
620
|
+
migration commands.
|
|
1076
621
|
|
|
1077
|
-
*
|
|
622
|
+
*Adrianna Chang*
|
|
1078
623
|
|
|
1079
|
-
*
|
|
624
|
+
* Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
|
|
1080
625
|
|
|
1081
|
-
|
|
1082
|
-
databases. When set, this option instructs Rails to generate 2 or
|
|
1083
|
-
more queries rather than generating joins for associations.
|
|
626
|
+
As well as `disconnect!` and `verify!`.
|
|
1084
627
|
|
|
1085
|
-
|
|
628
|
+
This generally isn't a big problem as connections must not be shared between
|
|
629
|
+
threads, but is required when running transactional tests or system tests
|
|
630
|
+
and could lead to a SEGV.
|
|
1086
631
|
|
|
1087
|
-
|
|
1088
|
-
class Dog
|
|
1089
|
-
has_many :treats, through: :humans, disable_joins: true
|
|
1090
|
-
has_many :humans
|
|
1091
|
-
end
|
|
1092
|
-
```
|
|
632
|
+
*Jean Boussier*
|
|
1093
633
|
|
|
1094
|
-
|
|
634
|
+
* Support `:source_location` tag option for query log tags.
|
|
1095
635
|
|
|
636
|
+
```ruby
|
|
637
|
+
config.active_record.query_log_tags << :source_location
|
|
1096
638
|
```
|
|
1097
|
-
SELECT "humans"."id" FROM "humans" WHERE "humans"."dog_id" = ? [["dog_id", 1]]
|
|
1098
|
-
SELECT "treats".* FROM "treats" WHERE "treats"."human_id" IN (?, ?, ?) [["human_id", 1], ["human_id", 2], ["human_id", 3]]
|
|
1099
|
-
```
|
|
1100
|
-
|
|
1101
|
-
*Eileen M. Uchitelle*, *Aaron Patterson*, *Lee Quarella*
|
|
1102
|
-
|
|
1103
|
-
* Add setting for enumerating column names in SELECT statements.
|
|
1104
639
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
640
|
+
Calculating the caller location is a costly operation and should be used primarily in development
|
|
641
|
+
(note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
|
|
642
|
+
or occasionally on production for debugging purposes.
|
|
1108
643
|
|
|
1109
|
-
|
|
1110
|
-
in `SELECT` queries, which will return consistent results and avoid prepared
|
|
1111
|
-
statement errors.
|
|
644
|
+
*fatkodima*
|
|
1112
645
|
|
|
1113
|
-
|
|
646
|
+
* Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
|
|
1114
647
|
|
|
1115
|
-
|
|
1116
|
-
Book.limit(5)
|
|
1117
|
-
# SELECT * FROM books LIMIT 5
|
|
1118
|
-
```
|
|
1119
|
-
|
|
1120
|
-
After:
|
|
648
|
+
Allow compression to be disabled by setting `compress: false`
|
|
1121
649
|
|
|
1122
650
|
```ruby
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
class Application < Rails::Application
|
|
1126
|
-
config.active_record.enumerate_columns_in_select_statements = true
|
|
651
|
+
class User
|
|
652
|
+
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
|
|
1127
653
|
end
|
|
1128
|
-
end
|
|
1129
|
-
|
|
1130
|
-
# or, configure per-model
|
|
1131
|
-
class Book < ApplicationRecord
|
|
1132
|
-
self.enumerate_columns_in_select_statements = true
|
|
1133
|
-
end
|
|
1134
654
|
```
|
|
1135
655
|
|
|
1136
|
-
|
|
1137
|
-
Book.limit(5)
|
|
1138
|
-
# SELECT id, author_id, name, format, status, language, etc FROM books LIMIT 5
|
|
1139
|
-
```
|
|
656
|
+
*Donal McBreen*
|
|
1140
657
|
|
|
1141
|
-
|
|
658
|
+
* Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
|
|
1142
659
|
|
|
1143
|
-
|
|
660
|
+
A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
|
|
1144
661
|
|
|
1145
|
-
|
|
1146
|
-
Book.upsert_all(
|
|
1147
|
-
[{ id: 1, status: 1 }, { id: 2, status: 1 }],
|
|
1148
|
-
on_duplicate: Arel.sql("status = GREATEST(books.status, EXCLUDED.status)")
|
|
1149
|
-
)
|
|
1150
|
-
```
|
|
662
|
+
*Rafael Mendonça França*
|
|
1151
663
|
|
|
1152
|
-
|
|
664
|
+
* Add `row_count` field to `sql.active_record` notification.
|
|
1153
665
|
|
|
1154
|
-
|
|
666
|
+
This field returns the amount of rows returned by the query that emitted the notification.
|
|
1155
667
|
|
|
1156
|
-
|
|
1157
|
-
Article.insert_all(
|
|
1158
|
-
[
|
|
1159
|
-
{ title: "Article 1", slug: "article-1", published: false },
|
|
1160
|
-
{ title: "Article 2", slug: "article-2", published: false }
|
|
1161
|
-
],
|
|
1162
|
-
returning: Arel.sql("id, (xmax = '0') as inserted, name as new_name")
|
|
1163
|
-
)
|
|
1164
|
-
```
|
|
668
|
+
This metric is useful in cases where one wants to detect queries with big result sets.
|
|
1165
669
|
|
|
1166
|
-
*
|
|
670
|
+
*Marvin Bitterlich*
|
|
1167
671
|
|
|
1168
|
-
*
|
|
672
|
+
* Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
|
|
1169
673
|
|
|
1170
|
-
|
|
674
|
+
Previously, this would only raise on collection associations and produce a generic error on singular associations.
|
|
1171
675
|
|
|
1172
|
-
|
|
676
|
+
Now, it will raise on both collection and singular associations.
|
|
1173
677
|
|
|
1174
|
-
|
|
1175
|
-
are regular Active Record attributes backed by a column with
|
|
1176
|
-
the same name. The system will transparently encrypt these
|
|
1177
|
-
attributes before saving them into the database and will
|
|
1178
|
-
decrypt them when retrieving their values.
|
|
678
|
+
*Joshua Young*
|
|
1179
679
|
|
|
680
|
+
* Fix single quote escapes on default generated MySQL columns.
|
|
1180
681
|
|
|
1181
|
-
|
|
1182
|
-
class Person < ApplicationRecord
|
|
1183
|
-
encrypts :name
|
|
1184
|
-
encrypts :email_address, deterministic: true
|
|
1185
|
-
end
|
|
1186
|
-
```
|
|
682
|
+
MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
|
|
1187
683
|
|
|
1188
|
-
|
|
1189
|
-
guide](https://edgeguides.rubyonrails.org/active_record_encryption.html).
|
|
684
|
+
Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
|
|
1190
685
|
|
|
1191
|
-
|
|
686
|
+
This would result in issues when importing the schema on a fresh instance of a MySQL database.
|
|
1192
687
|
|
|
1193
|
-
|
|
1194
|
-
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
|
688
|
+
Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
|
|
1195
689
|
|
|
1196
|
-
*
|
|
690
|
+
*Yash Kapadia*
|
|
1197
691
|
|
|
1198
|
-
*
|
|
692
|
+
* Fix Migrations with versions older than 7.1 validating options given to
|
|
693
|
+
`add_reference` and `t.references`.
|
|
1199
694
|
|
|
1200
|
-
|
|
1201
|
-
to specify that we only want to raise on n plus one queries.
|
|
695
|
+
*Hartley McGuire*
|
|
1202
696
|
|
|
1203
|
-
|
|
1204
|
-
developer.strict_loading!(mode: :n_plus_one_only)
|
|
697
|
+
* Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
|
|
1205
698
|
|
|
1206
|
-
|
|
1207
|
-
developer.projects.first.client # Raises StrictLoadingViolationError
|
|
1208
|
-
```
|
|
699
|
+
*JP Rosevear*
|
|
1209
700
|
|
|
1210
|
-
|
|
1211
|
-
association to raise an error. Using `n_plus_one_only` mode allows us to
|
|
1212
|
-
lazily load belongs_to, has_many, and other associations that are fetched
|
|
1213
|
-
through a single query.
|
|
701
|
+
* Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
|
|
1214
702
|
|
|
1215
|
-
|
|
703
|
+
This wouldn't always work previously because boolean values would be interpreted as strings.
|
|
1216
704
|
|
|
1217
|
-
|
|
705
|
+
e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
|
|
706
|
+
cache.
|
|
1218
707
|
|
|
1219
|
-
|
|
708
|
+
*Mike Coutermarsh*, *Jean Boussier*
|
|
1220
709
|
|
|
1221
|
-
|
|
1222
|
-
# With this config
|
|
1223
|
-
ActiveRecord::Base.time_zone_aware_attributes = true
|
|
710
|
+
* Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
|
|
1224
711
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
t.datetime "datetime"
|
|
1228
|
-
end
|
|
712
|
+
It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
|
|
713
|
+
but with support for `after_commit` and `after_rollback` callback options.
|
|
1229
714
|
|
|
1230
|
-
|
|
1231
|
-
record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
|
|
1232
|
-
assert_equal Float::INFINITY, record.datetime # record.datetime gets nil
|
|
1233
|
-
```
|
|
715
|
+
*Joshua Young*
|
|
1234
716
|
|
|
1235
|
-
|
|
717
|
+
* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
|
|
1236
718
|
|
|
1237
|
-
|
|
719
|
+
Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
|
|
1238
720
|
|
|
1239
|
-
|
|
721
|
+
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`.
|
|
1240
722
|
|
|
1241
|
-
The
|
|
723
|
+
The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
|
|
1242
724
|
|
|
1243
|
-
|
|
1244
|
-
class Book < ActiveRecord::Base
|
|
1245
|
-
enum :status, { proposed: 0, written: 1, published: 2 }
|
|
1246
|
-
end
|
|
1247
|
-
```
|
|
725
|
+
*Maxime Réty*
|
|
1248
726
|
|
|
1249
|
-
|
|
727
|
+
* Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
|
|
1250
728
|
|
|
1251
|
-
|
|
1252
|
-
# SELECT `books`.* FROM `books` WHERE `books`.`status` = 'prohibited' LIMIT 1
|
|
1253
|
-
Book.find_by(status: :prohibited)
|
|
1254
|
-
# => #<Book id: 1, status: "proposed", ...> (for mysql2 adapter)
|
|
1255
|
-
# => ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: invalid input syntax for type integer: "prohibited" (for postgresql adapter)
|
|
1256
|
-
# => nil (for sqlite3 adapter)
|
|
1257
|
-
```
|
|
729
|
+
*Maxime Réty*
|
|
1258
730
|
|
|
1259
|
-
|
|
731
|
+
* The object returned by `explain` now responds to `pluck`, `first`,
|
|
732
|
+
`last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
|
|
733
|
+
new methods run `EXPLAIN` on the corresponding queries:
|
|
1260
734
|
|
|
1261
735
|
```ruby
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
#
|
|
1265
|
-
```
|
|
1266
|
-
|
|
1267
|
-
*Ryuta Kamizono*
|
|
736
|
+
User.all.explain.count
|
|
737
|
+
# EXPLAIN SELECT COUNT(*) FROM `users`
|
|
738
|
+
# ...
|
|
1268
739
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
```yml
|
|
1274
|
-
### monkeys.yml
|
|
1275
|
-
george:
|
|
1276
|
-
name: George the Monkey
|
|
1277
|
-
fruits: apple
|
|
1278
|
-
|
|
1279
|
-
### fruits.yml
|
|
1280
|
-
apple:
|
|
1281
|
-
name: apple
|
|
740
|
+
User.all.explain.maximum(:id)
|
|
741
|
+
# EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
|
|
742
|
+
# ...
|
|
1282
743
|
```
|
|
1283
744
|
|
|
1284
|
-
|
|
1285
|
-
these will now be populated when loading the fixture. Previously, fixture loading
|
|
1286
|
-
would crash if these columns were required, and leave them as null otherwise.
|
|
1287
|
-
|
|
1288
|
-
*Alex Ghiculescu*
|
|
1289
|
-
|
|
1290
|
-
* Allow applications to configure the thread pool for async queries.
|
|
1291
|
-
|
|
1292
|
-
Some applications may want one thread pool per database whereas others want to use
|
|
1293
|
-
a single global thread pool for all queries. By default, Rails will set `async_query_executor`
|
|
1294
|
-
to `nil` which will not initialize any executor. If `load_async` is called and no executor
|
|
1295
|
-
has been configured, the query will be executed in the foreground.
|
|
745
|
+
*Petrik de Heus*
|
|
1296
746
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
`config.active_record.global_executor_concurrency`. This defaults to 4. For applications that want
|
|
1300
|
-
to have a thread pool for each database connection, `config.active_record.async_query_executor` can
|
|
1301
|
-
be set to `:multi_thread_pool`. The configuration for each thread pool is set in the database
|
|
1302
|
-
configuration.
|
|
747
|
+
* Fixes an issue where `validates_associated` `:on` option wasn't respected
|
|
748
|
+
when validating associated records.
|
|
1303
749
|
|
|
1304
|
-
*
|
|
750
|
+
*Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
|
|
1305
751
|
|
|
1306
|
-
* Allow
|
|
752
|
+
* Allow overriding SQLite defaults from `database.yml`.
|
|
1307
753
|
|
|
1308
|
-
|
|
754
|
+
Any PRAGMA configuration set under the `pragmas` key in the configuration
|
|
755
|
+
file takes precedence over Rails' defaults, and additional PRAGMAs can be
|
|
756
|
+
set as well.
|
|
1309
757
|
|
|
1310
|
-
```
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
758
|
+
```yaml
|
|
759
|
+
database: storage/development.sqlite3
|
|
760
|
+
timeout: 5000
|
|
761
|
+
pragmas:
|
|
762
|
+
journal_mode: off
|
|
763
|
+
temp_store: memory
|
|
1315
764
|
```
|
|
1316
765
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
```ruby
|
|
1320
|
-
class Book < ActiveRecord::Base
|
|
1321
|
-
enum :status, [ :proposed, :written ], prefix: true, scopes: false
|
|
1322
|
-
enum :cover, [ :hard, :soft ], suffix: true, default: :hard
|
|
1323
|
-
end
|
|
1324
|
-
```
|
|
766
|
+
*Stephen Margheim*
|
|
1325
767
|
|
|
1326
|
-
|
|
768
|
+
* Remove warning message when running SQLite in production, but leave it unconfigured.
|
|
1327
769
|
|
|
1328
|
-
|
|
770
|
+
There are valid use cases for running SQLite in production. However, it must be done
|
|
771
|
+
with care, so instead of a warning most users won't see anyway, it's preferable to
|
|
772
|
+
leave the configuration commented out to force them to think about having the database
|
|
773
|
+
on a persistent volume etc.
|
|
1329
774
|
|
|
1330
|
-
|
|
775
|
+
*Jacopo Beschi*, *Jean Boussier*
|
|
1331
776
|
|
|
1332
|
-
|
|
1333
|
-
the query, it will be performed in the foreground.
|
|
777
|
+
* Add support for generated columns to the SQLite3 adapter.
|
|
1334
778
|
|
|
1335
|
-
|
|
1336
|
-
|
|
779
|
+
Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
|
|
780
|
+
This adds support for those to the SQLite3 adapter.
|
|
1337
781
|
|
|
1338
782
|
```ruby
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
783
|
+
create_table :users do |t|
|
|
784
|
+
t.string :name
|
|
785
|
+
t.virtual :name_upper, type: :string, as: 'UPPER(name)'
|
|
786
|
+
t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
|
|
1342
787
|
end
|
|
1343
788
|
```
|
|
1344
789
|
|
|
1345
|
-
|
|
1346
|
-
the main thread had to wait to access the result. This timing is useful to know
|
|
1347
|
-
whether or not it's worth to load the query asynchronously.
|
|
790
|
+
*Stephen Margheim*
|
|
1348
791
|
|
|
1349
|
-
|
|
1350
|
-
DEBUG -- : Category Load (62.1ms) SELECT * FROM `categories` LIMIT 50
|
|
1351
|
-
DEBUG -- : ASYNC Post Load (64ms) (db time 126.1ms) SELECT * FROM `posts` LIMIT 100
|
|
1352
|
-
```
|
|
792
|
+
* TrilogyAdapter: ignore `host` if `socket` parameter is set.
|
|
1353
793
|
|
|
1354
|
-
|
|
1355
|
-
waiting for the results, and the second set of parens with "db time" is how long
|
|
1356
|
-
the entire query took to execute.
|
|
1357
|
-
|
|
1358
|
-
*Jean Boussier*
|
|
794
|
+
This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
|
|
1359
795
|
|
|
1360
|
-
* Implemented `ActiveRecord::Relation#excluding` method.
|
|
1361
|
-
|
|
1362
|
-
This method excludes the specified record (or collection of records) from
|
|
1363
|
-
the resulting relation:
|
|
1364
|
-
|
|
1365
|
-
```ruby
|
|
1366
|
-
Post.excluding(post)
|
|
1367
|
-
Post.excluding(post_one, post_two)
|
|
1368
796
|
```
|
|
1369
|
-
|
|
1370
|
-
Also works on associations:
|
|
1371
|
-
|
|
1372
|
-
```ruby
|
|
1373
|
-
post.comments.excluding(comment)
|
|
1374
|
-
post.comments.excluding(comment_one, comment_two)
|
|
797
|
+
DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
|
|
1375
798
|
```
|
|
1376
799
|
|
|
1377
|
-
|
|
1378
|
-
and `Post.where.not(id: [post_one.id, post_two.id])` (for a collection).
|
|
1379
|
-
|
|
1380
|
-
*Glen Crawford*
|
|
1381
|
-
|
|
1382
|
-
* Skip optimised #exist? query when #include? is called on a relation
|
|
1383
|
-
with a having clause.
|
|
800
|
+
*Jean Boussier*
|
|
1384
801
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
#include? was called, due to an optimisation that would generate
|
|
1388
|
-
call #exists? on the relation instead, which effectively alters
|
|
1389
|
-
the select values of the query (and thus removes the aliased select
|
|
1390
|
-
values), but leaves the having clause intact. Because the having
|
|
1391
|
-
clause is then referencing an aliased column that is no longer
|
|
1392
|
-
present in the simplified query, an ActiveRecord::InvalidStatement
|
|
1393
|
-
error was raised.
|
|
802
|
+
* Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
|
|
803
|
+
`assert_no_queries_match` assertions public.
|
|
1394
804
|
|
|
1395
|
-
|
|
805
|
+
To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
|
|
806
|
+
`assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
|
|
807
|
+
`assert_no_queries_match` are used. These assertions can now be used in applications as well.
|
|
1396
808
|
|
|
1397
809
|
```ruby
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
.include?(Author.first)
|
|
1403
|
-
```
|
|
1404
|
-
|
|
1405
|
-
This change adds an addition check to the condition that skips the
|
|
1406
|
-
simplified #exists? query, which simply checks for the presence of
|
|
1407
|
-
a having clause.
|
|
1408
|
-
|
|
1409
|
-
Fixes #41417.
|
|
1410
|
-
|
|
1411
|
-
*Michael Smart*
|
|
1412
|
-
|
|
1413
|
-
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
|
1414
|
-
without Rails knowledge (e.g., if app gets killed during long-running query or due to Rack::Timeout), app won't end
|
|
1415
|
-
up in perpetual crash state for being inconsistent with PostgreSQL.
|
|
1416
|
-
|
|
1417
|
-
*wbharding*, *Martin Tepper*
|
|
1418
|
-
|
|
1419
|
-
* Add ability to apply `scoping` to `all_queries`.
|
|
1420
|
-
|
|
1421
|
-
Some applications may want to use the `scoping` method but previously it only
|
|
1422
|
-
worked on certain types of queries. This change allows the `scoping` method to apply
|
|
1423
|
-
to all queries for a model in a block.
|
|
810
|
+
class ArticleTest < ActiveSupport::TestCase
|
|
811
|
+
test "queries are made" do
|
|
812
|
+
assert_queries_count(1) { Article.first }
|
|
813
|
+
end
|
|
1424
814
|
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
815
|
+
test "creates a foreign key" do
|
|
816
|
+
assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
|
|
817
|
+
@connection.add_foreign_key(:comments, :posts)
|
|
818
|
+
end
|
|
819
|
+
end
|
|
1428
820
|
end
|
|
1429
821
|
```
|
|
1430
822
|
|
|
1431
|
-
*
|
|
1432
|
-
|
|
1433
|
-
* `ActiveRecord::Calculations.calculate` called with `:average`
|
|
1434
|
-
(aliased as `ActiveRecord::Calculations.average`) will now use column-based
|
|
1435
|
-
type casting. This means that floating-point number columns will now be
|
|
1436
|
-
aggregated as `Float` and decimal columns will be aggregated as `BigDecimal`.
|
|
823
|
+
*Petrik de Heus*, *fatkodima*
|
|
1437
824
|
|
|
1438
|
-
|
|
1439
|
-
(this was the case before already).
|
|
825
|
+
* Fix `has_secure_token` calls the setter method on initialize.
|
|
1440
826
|
|
|
1441
|
-
|
|
1442
|
-
# With the following schema:
|
|
1443
|
-
create_table "measurements" do |t|
|
|
1444
|
-
t.float "temperature"
|
|
1445
|
-
end
|
|
827
|
+
*Abeid Ahmed*
|
|
1446
828
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
829
|
+
* When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
|
|
830
|
+
adapter. This allows decoupling the adapter the application chooses to use from the database connection details
|
|
831
|
+
set in the deployment environment.
|
|
1450
832
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
833
|
+
```ruby
|
|
834
|
+
# ENV['DATABASE_URL'] = "mysql://localhost/example_database"
|
|
835
|
+
config.active_record.protocol_adapters.mysql = "trilogy"
|
|
836
|
+
# will connect to MySQL using the trilogy adapter
|
|
1454
837
|
```
|
|
1455
838
|
|
|
1456
|
-
|
|
1457
|
-
database adapter. This is not the case anymore. If you relied on that kind
|
|
1458
|
-
of magic, you now need to register your own `ActiveRecord::Type`
|
|
1459
|
-
(see `ActiveRecord::Attributes::ClassMethods` for documentation).
|
|
1460
|
-
|
|
1461
|
-
*Josua Schmid*
|
|
1462
|
-
|
|
1463
|
-
* PostgreSQL: introduce `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`.
|
|
1464
|
-
|
|
1465
|
-
This setting controls what native type Active Record should use when you call `datetime` in
|
|
1466
|
-
a migration or schema. It takes a symbol which must correspond to one of the configured
|
|
1467
|
-
`NATIVE_DATABASE_TYPES`. The default is `:timestamp`, meaning `t.datetime` in a migration
|
|
1468
|
-
will create a "timestamp without time zone" column. To use "timestamp with time zone",
|
|
1469
|
-
change this to `:timestamptz` in an initializer.
|
|
1470
|
-
|
|
1471
|
-
You should run `bin/rails db:migrate` to rebuild your schema.rb if you change this.
|
|
839
|
+
*Jean Boussier*, *Kevin McPhillips*
|
|
1472
840
|
|
|
1473
|
-
|
|
841
|
+
* In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
|
|
842
|
+
the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
|
|
843
|
+
called with a generic warning message rather than silently ignoring the warning(s).
|
|
1474
844
|
|
|
1475
|
-
*
|
|
845
|
+
*Kevin McPhillips*
|
|
1476
846
|
|
|
1477
|
-
|
|
1478
|
-
and are created as `timestamptz` columns when the schema is loaded.
|
|
847
|
+
* `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
|
|
1479
848
|
|
|
1480
|
-
*
|
|
849
|
+
*Andrew Novoselac*
|
|
1481
850
|
|
|
1482
|
-
*
|
|
1483
|
-
`ActiveRecord::
|
|
851
|
+
* Fix `where(field: values)` queries when `field` is a serialized attribute
|
|
852
|
+
(for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
|
|
853
|
+
column).
|
|
1484
854
|
|
|
1485
|
-
*
|
|
855
|
+
*João Alves*
|
|
1486
856
|
|
|
1487
|
-
*
|
|
857
|
+
* Make the output of `ActiveRecord::Core#inspect` configurable.
|
|
1488
858
|
|
|
1489
|
-
|
|
1490
|
-
named `ApplicationRecord` can now set a specific class to be the `primary_abstract_class`.
|
|
859
|
+
By default, calling `inspect` on a record will yield a formatted string including just the `id`.
|
|
1491
860
|
|
|
1492
861
|
```ruby
|
|
1493
|
-
|
|
1494
|
-
self.primary_abstract_class
|
|
1495
|
-
end
|
|
862
|
+
Post.first.inspect #=> "#<Post id: 1>"
|
|
1496
863
|
```
|
|
1497
864
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
needs to know that the default connection is the same as the `ApplicationRecord` connection.
|
|
1501
|
-
However, some applications have a differently named `ApplicationRecord`. This prevents Active
|
|
1502
|
-
Record from opening duplicate connections to the same database.
|
|
1503
|
-
|
|
1504
|
-
*Eileen M. Uchitelle*, *John Crepezzi*
|
|
1505
|
-
|
|
1506
|
-
* Support hash config for `structure_dump_flags` and `structure_load_flags` flags.
|
|
1507
|
-
Now that Active Record supports multiple databases configuration,
|
|
1508
|
-
we need a way to pass specific flags for dump/load databases since
|
|
1509
|
-
the options are not the same for different adapters.
|
|
1510
|
-
We can use in the original way:
|
|
865
|
+
The attributes to be included in the output of `inspect` can be configured with
|
|
866
|
+
`ActiveRecord::Core#attributes_for_inspect`.
|
|
1511
867
|
|
|
1512
868
|
```ruby
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table'
|
|
869
|
+
Post.attributes_for_inspect = [:id, :title]
|
|
870
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
|
|
1516
871
|
```
|
|
1517
872
|
|
|
1518
|
-
|
|
1519
|
-
is the adapter
|
|
873
|
+
With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
|
|
1520
874
|
|
|
1521
875
|
```ruby
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
postgres: '--no-tablespaces'
|
|
1525
|
-
}
|
|
876
|
+
Post.attributes_for_inspect = :all
|
|
877
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
|
1526
878
|
```
|
|
1527
879
|
|
|
1528
|
-
|
|
880
|
+
In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
|
|
1529
881
|
|
|
1530
|
-
|
|
1531
|
-
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
|
1532
|
-
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
|
1533
|
-
are assumed to be adapter specification urls.
|
|
882
|
+
You can also call `full_inspect` to get an inspection with all the attributes.
|
|
1534
883
|
|
|
1535
|
-
|
|
884
|
+
The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
|
|
1536
885
|
|
|
1537
|
-
*
|
|
886
|
+
*Andrew Novoselac*
|
|
1538
887
|
|
|
1539
|
-
*
|
|
888
|
+
* Don't mark attributes as changed when reassigned to `Float::INFINITY` or
|
|
889
|
+
`-Float::INFINITY`.
|
|
1540
890
|
|
|
1541
|
-
|
|
1542
|
-
model level.
|
|
891
|
+
*Maicol Bentancor*
|
|
1543
892
|
|
|
1544
|
-
|
|
1545
|
-
class User < ApplicationRecord
|
|
1546
|
-
has_many :bookmarks
|
|
1547
|
-
has_many :articles, strict_loading: true
|
|
1548
|
-
end
|
|
1549
|
-
|
|
1550
|
-
user = User.first
|
|
1551
|
-
user.articles # => ActiveRecord::StrictLoadingViolationError
|
|
1552
|
-
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
|
893
|
+
* Support the `RETURNING` clause for MariaDB.
|
|
1553
894
|
|
|
1554
|
-
|
|
1555
|
-
user.bookmarks # => ActiveRecord::StrictLoadingViolationError
|
|
895
|
+
*fatkodima*, *Nikolay Kondratyev*
|
|
1556
896
|
|
|
1557
|
-
|
|
1558
|
-
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
|
1559
|
-
user.articles.strict_loading!(false) # => #<ActiveRecord::Associations::CollectionProxy>
|
|
1560
|
-
```
|
|
897
|
+
* The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
|
|
1561
898
|
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
* Add `FinderMethods#sole` and `#find_sole_by` to find and assert the
|
|
1565
|
-
presence of exactly one record.
|
|
1566
|
-
|
|
1567
|
-
Used when you need a single row, but also want to assert that there aren't
|
|
1568
|
-
multiple rows matching the condition; especially for when database
|
|
1569
|
-
constraints aren't enough or are impractical.
|
|
899
|
+
Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
|
|
1570
900
|
|
|
1571
901
|
```ruby
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
# => #<Product ...> (if one Product with given price)
|
|
1575
|
-
# => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
|
|
1576
|
-
|
|
1577
|
-
user.api_keys.find_sole_by(key: key)
|
|
1578
|
-
# as above
|
|
902
|
+
add_reference :person, :alias, foreign_key: { deferrable: :deferred }
|
|
903
|
+
add_reference :alias, :person, foreign_key: { deferrable: :deferred }
|
|
1579
904
|
```
|
|
1580
905
|
|
|
1581
|
-
*
|
|
906
|
+
*Stephen Margheim*
|
|
1582
907
|
|
|
1583
|
-
*
|
|
1584
|
-
|
|
1585
|
-
Before:
|
|
908
|
+
* Add the `set_constraints` helper to PostgreSQL connections.
|
|
1586
909
|
|
|
1587
910
|
```ruby
|
|
1588
|
-
|
|
1589
|
-
def admin
|
|
1590
|
-
false # Overriding the getter to always return false
|
|
1591
|
-
end
|
|
1592
|
-
end
|
|
1593
|
-
|
|
1594
|
-
user = User.first
|
|
1595
|
-
user.update(admin: true)
|
|
1596
|
-
|
|
1597
|
-
user.admin # false (as expected, due to the getter overwrite)
|
|
1598
|
-
user.admin? # true (not expected, returned the DB column value)
|
|
1599
|
-
```
|
|
1600
|
-
|
|
1601
|
-
After this commit, `user.admin?` above returns false, as expected.
|
|
1602
|
-
|
|
1603
|
-
Fixes #40771.
|
|
1604
|
-
|
|
1605
|
-
*Felipe*
|
|
1606
|
-
|
|
1607
|
-
* Allow delegated_type to be specified primary_key and foreign_key.
|
|
911
|
+
Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
|
|
1608
912
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
* Expose an `invert_where` method that will invert all scope conditions.
|
|
1617
|
-
|
|
1618
|
-
```ruby
|
|
1619
|
-
class User
|
|
1620
|
-
scope :active, -> { where(accepted: true, locked: false) }
|
|
913
|
+
Post.transaction do
|
|
914
|
+
Post.connection.set_constraints(:deferred)
|
|
915
|
+
p = Post.create!(user_id: -1)
|
|
916
|
+
u = User.create!
|
|
917
|
+
p.user = u
|
|
918
|
+
p.save!
|
|
1621
919
|
end
|
|
1622
|
-
|
|
1623
|
-
User.active
|
|
1624
|
-
# ... WHERE `accepted` = 1 AND `locked` = 0
|
|
1625
|
-
|
|
1626
|
-
User.active.invert_where
|
|
1627
|
-
# ... WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
|
1628
920
|
```
|
|
1629
921
|
|
|
1630
|
-
*
|
|
922
|
+
*Cody Cutrer*
|
|
1631
923
|
|
|
1632
|
-
*
|
|
924
|
+
* Include `ActiveModel::API` in `ActiveRecord::Base`.
|
|
1633
925
|
|
|
1634
|
-
|
|
1635
|
-
to throw an error saying :polymorphic would not be a valid option.
|
|
926
|
+
*Sean Doyle*
|
|
1636
927
|
|
|
1637
|
-
|
|
928
|
+
* Ensure `#signed_id` outputs `url_safe` strings.
|
|
1638
929
|
|
|
1639
|
-
*
|
|
930
|
+
*Jason Meller*
|
|
1640
931
|
|
|
1641
|
-
|
|
932
|
+
* Add `nulls_last` and working `desc.nulls_first` for MySQL.
|
|
1642
933
|
|
|
1643
|
-
*
|
|
934
|
+
*Tristan Fellows*
|
|
1644
935
|
|
|
1645
|
-
|
|
1646
|
-
and the index name should be specified explicitly. Now, the index name is inferred
|
|
1647
|
-
automatically.
|
|
936
|
+
* Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
|
|
1648
937
|
|
|
1649
938
|
```ruby
|
|
1650
|
-
|
|
939
|
+
Topic.includes(:posts).order(posts: { created_at: :desc })
|
|
1651
940
|
```
|
|
1652
941
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
*fatkodima*
|
|
1656
|
-
|
|
1657
|
-
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
|
1658
|
-
|
|
1659
|
-
Fixes #39065.
|
|
1660
|
-
|
|
1661
|
-
*Alex Ghiculescu*
|
|
1662
|
-
|
|
1663
|
-
* Add option to run `default_scope` on all queries.
|
|
1664
|
-
|
|
1665
|
-
Previously, a `default_scope` would only run on select or insert queries. In some cases, like non-Rails tenant sharding solutions, it may be desirable to run `default_scope` on all queries in order to ensure queries are including a foreign key for the shard (i.e. `blog_id`).
|
|
1666
|
-
|
|
1667
|
-
Now applications can add an option to run on all queries including select, insert, delete, and update by adding an `all_queries` option to the default scope definition.
|
|
1668
|
-
|
|
1669
|
-
```ruby
|
|
1670
|
-
class Article < ApplicationRecord
|
|
1671
|
-
default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
|
|
1672
|
-
end
|
|
1673
|
-
```
|
|
1674
|
-
|
|
1675
|
-
*Eileen M. Uchitelle*
|
|
1676
|
-
|
|
1677
|
-
* Add `where.associated` to check for the presence of an association.
|
|
1678
|
-
|
|
1679
|
-
```ruby
|
|
1680
|
-
# Before:
|
|
1681
|
-
account.users.joins(:contact).where.not(contact_id: nil)
|
|
1682
|
-
|
|
1683
|
-
# After:
|
|
1684
|
-
account.users.where.associated(:contact)
|
|
1685
|
-
```
|
|
1686
|
-
|
|
1687
|
-
Also mirrors `where.missing`.
|
|
1688
|
-
|
|
1689
|
-
*Kasper Timm Hansen*
|
|
1690
|
-
|
|
1691
|
-
* Allow constructors (`build_association` and `create_association`) on
|
|
1692
|
-
`has_one :through` associations.
|
|
1693
|
-
|
|
1694
|
-
*Santiago Perez Perret*
|
|
1695
|
-
|
|
942
|
+
*Myles Boone*
|
|
1696
943
|
|
|
1697
|
-
Please check [
|
|
944
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.
|