activerecord 6.0.0 → 7.2.3
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 +996 -594
- data/MIT-LICENSE +1 -1
- data/README.rdoc +34 -34
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +22 -20
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +41 -30
- data/lib/active_record/associations/association.rb +106 -41
- data/lib/active_record/associations/association_scope.rb +30 -21
- data/lib/active_record/associations/belongs_to_association.rb +69 -14
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
- data/lib/active_record/associations/builder/association.rb +39 -6
- data/lib/active_record/associations/builder/belongs_to.rb +47 -17
- data/lib/active_record/associations/builder/collection_association.rb +14 -6
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
- data/lib/active_record/associations/builder/has_many.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +13 -16
- data/lib/active_record/associations/builder/singular_association.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +90 -53
- data/lib/active_record/associations/collection_proxy.rb +54 -19
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +21 -1
- data/lib/active_record/associations/has_many_association.rb +41 -10
- data/lib/active_record/associations/has_many_through_association.rb +29 -12
- data/lib/active_record/associations/has_one_association.rb +33 -9
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +97 -54
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +237 -54
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +51 -17
- data/lib/active_record/associations/preloader.rb +55 -121
- data/lib/active_record/associations/singular_association.rb +16 -4
- data/lib/active_record/associations/through_association.rb +26 -15
- data/lib/active_record/associations.rb +454 -440
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +11 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +75 -34
- data/lib/active_record/attribute_methods/primary_key.rb +53 -31
- data/lib/active_record/attribute_methods/query.rb +31 -22
- data/lib/active_record/attribute_methods/read.rb +16 -17
- data/lib/active_record/attribute_methods/serialization.rb +177 -35
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
- data/lib/active_record/attribute_methods/write.rb +16 -28
- data/lib/active_record/attribute_methods.rb +227 -100
- data/lib/active_record/attributes.rb +94 -56
- data/lib/active_record/autosave_association.rb +119 -73
- data/lib/active_record/base.rb +31 -21
- data/lib/active_record/callbacks.rb +168 -55
- 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 -25
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
- data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
- data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
- data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
- data/lib/active_record/connection_adapters/column.rb +28 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -15
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
- data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
- 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 +102 -24
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
- 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 +176 -0
- data/lib/active_record/connection_handling.rb +243 -115
- data/lib/active_record/core.rb +481 -199
- data/lib/active_record/counter_cache.rb +69 -32
- data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
- data/lib/active_record/database_configurations/database_config.rb +77 -10
- data/lib/active_record/database_configurations/hash_config.rb +148 -26
- data/lib/active_record/database_configurations/url_config.rb +44 -45
- data/lib/active_record/database_configurations.rb +190 -114
- data/lib/active_record/delegated_type.rb +279 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +5 -6
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +171 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +224 -73
- data/lib/active_record/errors.rb +254 -36
- data/lib/active_record/explain.rb +30 -17
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +22 -15
- data/lib/active_record/fixture_set/model_metadata.rb +15 -6
- data/lib/active_record/fixture_set/render_context.rb +3 -1
- data/lib/active_record/fixture_set/table_row.rb +88 -16
- data/lib/active_record/fixture_set/table_rows.rb +4 -5
- data/lib/active_record/fixtures.rb +229 -116
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +121 -48
- data/lib/active_record/insert_all.rb +178 -29
- data/lib/active_record/integration.rb +16 -14
- data/lib/active_record/internal_metadata.rb +132 -21
- data/lib/active_record/legacy_yaml_adapter.rb +3 -36
- data/lib/active_record/locking/optimistic.rb +64 -33
- data/lib/active_record/locking/pessimistic.rb +21 -8
- data/lib/active_record/log_subscriber.rb +61 -30
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
- data/lib/active_record/middleware/database_selector.rb +25 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +160 -55
- data/lib/active_record/migration/compatibility.rb +286 -43
- 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/join_table.rb +1 -2
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +421 -193
- data/lib/active_record/model_schema.rb +217 -125
- data/lib/active_record/nested_attributes.rb +62 -27
- data/lib/active_record/no_touching.rb +4 -4
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +322 -319
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -15
- data/lib/active_record/query_logs.rb +193 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +54 -14
- data/lib/active_record/railtie.rb +250 -72
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +312 -197
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +45 -3
- data/lib/active_record/reflection.rb +389 -146
- data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
- data/lib/active_record/relation/batches.rb +214 -73
- data/lib/active_record/relation/calculations.rb +379 -124
- data/lib/active_record/relation/delegation.rb +36 -23
- data/lib/active_record/relation/finder_methods.rb +159 -49
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +41 -33
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +79 -53
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +1156 -279
- data/lib/active_record/relation/record_fetch_warning.rb +12 -11
- data/lib/active_record/relation/spawn_methods.rb +10 -9
- data/lib/active_record/relation/where_clause.rb +100 -66
- data/lib/active_record/relation.rb +829 -194
- data/lib/active_record/result.rb +76 -56
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +86 -47
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +140 -33
- data/lib/active_record/schema_migration.rb +74 -29
- data/lib/active_record/scoping/default.rb +73 -19
- data/lib/active_record/scoping/named.rb +10 -28
- data/lib/active_record/scoping.rb +65 -35
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +34 -8
- data/lib/active_record/serialization.rb +11 -4
- data/lib/active_record/signed_id.rb +138 -0
- data/lib/active_record/statement_cache.rb +26 -10
- data/lib/active_record/store.rb +19 -14
- data/lib/active_record/suppressor.rb +15 -17
- data/lib/active_record/table_metadata.rb +46 -36
- data/lib/active_record/tasks/database_tasks.rb +371 -205
- data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +189 -104
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +35 -25
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +31 -27
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +131 -99
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +33 -18
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +11 -6
- data/lib/active_record/type/time.rb +14 -0
- data/lib/active_record/type/type_map.rb +17 -21
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +7 -2
- data/lib/active_record/type_caster/connection.rb +4 -5
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -8
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +88 -18
- data/lib/active_record/validations.rb +15 -8
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +446 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +4 -8
- data/lib/arel/collectors/bind.rb +8 -1
- data/lib/arel/collectors/composite.rb +15 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/crud.rb +30 -22
- data/lib/arel/delete_manager.rb +23 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +82 -9
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +22 -10
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +14 -13
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/join_source.rb +1 -1
- 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 +122 -11
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/table_alias.rb +11 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes/update_statement.rb +11 -4
- data/lib/arel/nodes.rb +10 -3
- data/lib/arel/predications.rb +31 -28
- data/lib/arel/select_manager.rb +18 -9
- data/lib/arel/table.rb +21 -10
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +25 -5
- data/lib/arel/visitors/dot.rb +94 -90
- data/lib/arel/visitors/mysql.rb +34 -6
- data/lib/arel/visitors/postgresql.rb +5 -16
- data/lib/arel/visitors/sqlite.rb +25 -1
- data/lib/arel/visitors/to_sql.rb +227 -81
- data/lib/arel/visitors/visitor.rb +2 -3
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +37 -15
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +9 -3
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +117 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/null_relation.rb +0 -68
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
data/CHANGELOG.md
CHANGED
|
@@ -1,1013 +1,1415 @@
|
|
|
1
|
-
## Rails
|
|
1
|
+
## Rails 7.2.3 (October 28, 2025) ##
|
|
2
2
|
|
|
3
|
-
*
|
|
3
|
+
* Fix SQLite3 data loss during table alterations with CASCADE foreign keys.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
When altering a table in SQLite3 that is referenced by child tables with
|
|
6
|
+
`ON DELETE CASCADE` foreign keys, ActiveRecord would silently delete all
|
|
7
|
+
data from the child tables. This occurred because SQLite requires table
|
|
8
|
+
recreation for schema changes, and during this process the original table
|
|
9
|
+
is temporarily dropped, triggering CASCADE deletes on child tables.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
The root cause was incorrect ordering of operations. The original code
|
|
12
|
+
wrapped `disable_referential_integrity` inside a transaction, but
|
|
13
|
+
`PRAGMA foreign_keys` cannot be modified inside a transaction in SQLite -
|
|
14
|
+
attempting to do so simply has no effect. This meant foreign keys remained
|
|
15
|
+
enabled during table recreation, causing CASCADE deletes to fire.
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
|
|
18
|
+
procedure: `disable_referential_integrity` now wraps the transaction instead
|
|
19
|
+
of being wrapped by it. This ensures foreign keys are properly disabled
|
|
20
|
+
before the transaction starts and re-enabled after it commits, preventing
|
|
21
|
+
CASCADE deletes while maintaining data integrity through atomic transactions.
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
enum status: [:sent, :not_sent]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
*Edu Depetris*
|
|
23
|
+
*Ruy Rocha*
|
|
20
24
|
|
|
21
|
-
*
|
|
25
|
+
* Fix `belongs_to` associations not to clear the entire composite primary key.
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
When clearing a `belongs_to` association that references a model with composite primary key,
|
|
28
|
+
only the optional part of the key should be cleared.
|
|
24
29
|
|
|
30
|
+
*zzak*
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
* Fix invalid records being autosaved when distantly associated records are marked for deletion.
|
|
27
33
|
|
|
28
|
-
*
|
|
34
|
+
*Ian Terrell*, *axlekb AB*
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
* Prevent persisting invalid record.
|
|
31
37
|
|
|
32
|
-
*
|
|
38
|
+
*Edouard Chin*
|
|
33
39
|
|
|
34
|
-
|
|
40
|
+
* Fix count with group by qualified name on loaded relation.
|
|
35
41
|
|
|
36
42
|
*Ryuta Kamizono*
|
|
37
43
|
|
|
38
|
-
*
|
|
44
|
+
* Fix `sum` with qualified name on loaded relation.
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
*Chris Gunther*
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
* Fix prepared statements on mysql2 adapter.
|
|
43
49
|
|
|
44
|
-
*
|
|
50
|
+
*Jean Boussier*
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
* Fix query cache for pinned connections in multi threaded transactional tests.
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
When a pinned connection is used across separate threads, they now use a separate cache store
|
|
55
|
+
for each thread.
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
This improve accuracy of system tests, and any test using multiple threads.
|
|
51
58
|
|
|
52
|
-
*
|
|
59
|
+
*Heinrich Lee Yu*, *Jean Boussier*
|
|
53
60
|
|
|
54
|
-
*
|
|
61
|
+
* Don't add `id_value` attribute alias when attribute/column with that name already exists.
|
|
55
62
|
|
|
56
|
-
*
|
|
63
|
+
*Rob Lewis*
|
|
57
64
|
|
|
58
|
-
* Fix
|
|
65
|
+
* Fix false positive change detection involving STI and polymorhic has one relationships.
|
|
59
66
|
|
|
60
|
-
|
|
67
|
+
Polymorphic `has_one` relationships would always be considered changed when defined in a STI child
|
|
68
|
+
class, causing nedless extra autosaves.
|
|
61
69
|
|
|
62
|
-
*
|
|
70
|
+
*David Fritsch*
|
|
63
71
|
|
|
72
|
+
* Fix stale associaton detection for polymophic `belong_to`.
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
*Florent Beaurain*, *Thomas Crambert*
|
|
66
75
|
|
|
67
|
-
*
|
|
76
|
+
* Fix removal of PostgreSQL version comments in `structure.sql` for latest PostgreSQL versions which include `\restrict`.
|
|
68
77
|
|
|
69
|
-
*
|
|
78
|
+
*Brendan Weibrecht*
|
|
70
79
|
|
|
71
|
-
*
|
|
80
|
+
* Fix `#merge` with `#or` or `#and` and a mixture of attributes and SQL strings resulting in an incorrect query.
|
|
72
81
|
|
|
73
82
|
```ruby
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
base = Comment.joins(:post).where(user_id: 1).where("recent = 1")
|
|
84
|
+
puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql
|
|
76
85
|
```
|
|
77
86
|
|
|
78
|
-
|
|
87
|
+
Before:
|
|
79
88
|
|
|
80
|
-
```
|
|
81
|
-
|
|
89
|
+
```SQL
|
|
90
|
+
SELECT "comments".* FROM "comments"
|
|
91
|
+
INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
|
|
92
|
+
WHERE (recent = 1)
|
|
93
|
+
AND (
|
|
94
|
+
"comments"."user_id" = 1
|
|
95
|
+
AND (recent = 1)
|
|
96
|
+
AND "comments"."draft" = 1
|
|
97
|
+
OR "posts"."archived" = 1
|
|
98
|
+
)
|
|
99
|
+
```
|
|
82
100
|
|
|
83
|
-
|
|
84
|
-
e.estimate_of_type == sapphire.class.polymorphic_name
|
|
85
|
-
}.reject { |e|
|
|
86
|
-
e.estimate_of_id == sapphire.id
|
|
87
|
-
}
|
|
88
|
-
assert_equal [cars(:honda)], nor
|
|
101
|
+
After:
|
|
89
102
|
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
```SQL
|
|
104
|
+
SELECT "comments".* FROM "comments"
|
|
105
|
+
INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
|
|
106
|
+
WHERE "comments"."user_id" = 1
|
|
107
|
+
AND (recent = 1)
|
|
108
|
+
AND (
|
|
109
|
+
"comments"."user_id" = 1
|
|
110
|
+
AND (recent = 1)
|
|
111
|
+
AND "comments"."draft" = 1
|
|
112
|
+
OR "posts"."archived" = 1
|
|
92
113
|
)
|
|
93
|
-
assert_equal nor, without_sapphire.map(&:estimate_of)
|
|
94
114
|
```
|
|
95
115
|
|
|
96
|
-
|
|
116
|
+
*Joshua Young*
|
|
97
117
|
|
|
98
|
-
|
|
99
|
-
sapphire = treasures(:sapphire)
|
|
118
|
+
* Fix inline `has_and_belongs_to_many` fixtures for tables with composite primary keys.
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
assert_equal [treasures(:diamond), cars(:honda)], nand
|
|
120
|
+
*fatkodima*
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
|
|
106
|
-
)
|
|
107
|
-
assert_equal nand, without_sapphire.map(&:estimate_of)
|
|
108
|
-
```
|
|
122
|
+
* Fix `annotate` comments to propagate to `update_all`/`delete_all`.
|
|
109
123
|
|
|
110
|
-
*
|
|
124
|
+
*fatkodima*
|
|
111
125
|
|
|
112
|
-
* Fix
|
|
126
|
+
* Fix checking whether an unpersisted record is `include?`d in a strictly
|
|
127
|
+
loaded `has_and_belongs_to_many` association.
|
|
113
128
|
|
|
114
|
-
|
|
129
|
+
*Hartley McGuire*
|
|
115
130
|
|
|
116
|
-
|
|
131
|
+
* Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys.
|
|
117
132
|
|
|
118
|
-
*
|
|
119
|
-
the versioned entries in `ActiveSupport::Cache`. This also means that
|
|
120
|
-
`ActiveRecord::Relation#cache_key` will now return a stable key that does not
|
|
121
|
-
include the max timestamp or count any more.
|
|
133
|
+
*fatkodima*
|
|
122
134
|
|
|
123
|
-
|
|
124
|
-
cache keys with timestamps until you set `ActiveRecord::Base.collection_cache_versioning = true`.
|
|
125
|
-
That's the setting for all new apps on Rails 6.0+
|
|
135
|
+
* `create_or_find_by` will now correctly rollback a transaction.
|
|
126
136
|
|
|
127
|
-
|
|
137
|
+
When using `create_or_find_by`, raising a ActiveRecord::Rollback error
|
|
138
|
+
in a `after_save` callback had no effect, the transaction was committed
|
|
139
|
+
and a record created.
|
|
128
140
|
|
|
129
|
-
*
|
|
141
|
+
*Edouard Chin*
|
|
130
142
|
|
|
131
|
-
|
|
143
|
+
* Gracefully handle `Timeout.timeout` firing during connection configuration.
|
|
132
144
|
|
|
133
|
-
|
|
145
|
+
Use of `Timeout.timeout` could result in improperly initialized database connection.
|
|
134
146
|
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
This could lead to a partially configured connection being used, resulting in various exceptions,
|
|
148
|
+
the most common being with the PostgreSQLAdapter raising `undefined method 'key?' for nil`
|
|
149
|
+
or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
|
|
137
150
|
|
|
138
|
-
*
|
|
151
|
+
*Jean Boussier*
|
|
139
152
|
|
|
140
|
-
*
|
|
153
|
+
* The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".
|
|
141
154
|
|
|
142
|
-
|
|
155
|
+
*Mike Dalessio*
|
|
143
156
|
|
|
144
|
-
|
|
157
|
+
* Handle libpq returning a database version of 0 on no/bad connection in `PostgreSQLAdapter`.
|
|
145
158
|
|
|
146
|
-
|
|
159
|
+
Before, this version would be cached and an error would be raised during connection configuration when
|
|
160
|
+
comparing it with the minimum required version for the adapter. This meant that the connection could
|
|
161
|
+
never be successfully configured on subsequent reconnection attempts.
|
|
147
162
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
another instance of the same callback on the same association hadn't
|
|
151
|
-
finished running. When control returned to the first instance of the
|
|
152
|
-
callback, the instance variable had changed, and subsequent associated
|
|
153
|
-
records weren't saved correctly. Specifically, the ID field for the
|
|
154
|
-
`belongs_to` corresponding to the `has_many` was `nil`.
|
|
163
|
+
Now, this is treated as a connection failure consistent with libpq, raising a `ActiveRecord::ConnectionFailed`
|
|
164
|
+
and ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
*Joshua Young*, *Rian McGuire*
|
|
157
167
|
|
|
158
|
-
|
|
168
|
+
* Fix error handling during connection configuration.
|
|
159
169
|
|
|
160
|
-
|
|
170
|
+
Active Record wasn't properly handling errors during the connection configuration phase.
|
|
171
|
+
This could lead to a partially configured connection being used, resulting in various exceptions,
|
|
172
|
+
the most common being with the PostgreSQLAdapter raising `undefined method `key?' for nil`
|
|
173
|
+
or `TypeError: wrong argument type nil (expected PG::TypeMap)`.
|
|
161
174
|
|
|
162
|
-
|
|
175
|
+
*Jean Boussier*
|
|
176
|
+
|
|
177
|
+
* Fix a case where a non-retryable query could be marked retryable.
|
|
178
|
+
|
|
179
|
+
*Hartley McGuire*
|
|
180
|
+
|
|
181
|
+
* Handle circular references when autosaving associations.
|
|
182
|
+
|
|
183
|
+
*zzak*
|
|
184
|
+
|
|
185
|
+
* Prevent persisting invalid record.
|
|
186
|
+
|
|
187
|
+
*Edouard Chin*
|
|
188
|
+
|
|
189
|
+
* Fix support for PostgreSQL enum types with commas in their name.
|
|
190
|
+
|
|
191
|
+
*Arthur Hess*
|
|
192
|
+
|
|
193
|
+
* Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.
|
|
194
|
+
|
|
195
|
+
*Nikita Vasilevsky*
|
|
196
|
+
|
|
197
|
+
* Fix joining on a scoped association with string joins and bind parameters.
|
|
163
198
|
|
|
164
199
|
```ruby
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
200
|
+
class Instructor < ActiveRecord::Base
|
|
201
|
+
has_many :instructor_roles, -> { active }
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
class InstructorRole < ActiveRecord::Base
|
|
205
|
+
scope :active, -> {
|
|
206
|
+
joins("JOIN students ON instructor_roles.student_id = students.id")
|
|
207
|
+
.where(students { status: 1 })
|
|
208
|
+
}
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
Instructor.joins(:instructor_roles).first
|
|
169
212
|
```
|
|
170
213
|
|
|
171
|
-
|
|
214
|
+
The above example would result in `ActiveRecord::StatementInvalid` because the
|
|
215
|
+
`active` scope bind parameters would be lost.
|
|
216
|
+
|
|
217
|
+
*Jean Boussier*
|
|
218
|
+
|
|
219
|
+
* Fix a potential race condition with system tests and transactional fixtures.
|
|
220
|
+
|
|
221
|
+
*Sjoerd Lagarde*
|
|
222
|
+
|
|
223
|
+
* Fix count with group by qualified name on loaded relation.
|
|
224
|
+
|
|
225
|
+
*Ryuta Kamizono*
|
|
226
|
+
|
|
227
|
+
* Fix sum with qualified name on loaded relation.
|
|
228
|
+
|
|
229
|
+
*Chris Gunther*
|
|
230
|
+
|
|
231
|
+
* Fix autosave associations to no longer validated unmodified associated records.
|
|
232
|
+
|
|
233
|
+
Active Record was incorrectly performing validation on associated record that
|
|
234
|
+
weren't created nor modified as part of the transaction:
|
|
172
235
|
|
|
173
236
|
```ruby
|
|
174
|
-
|
|
175
|
-
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
|
|
176
|
-
add_column :items, :attr3, :integer, limit: 10 # => ArgumentError
|
|
177
|
-
add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
|
|
237
|
+
Post.create!(author: User.find(1)) # Fail if user is invalid
|
|
178
238
|
```
|
|
179
239
|
|
|
240
|
+
*Jean Boussier*
|
|
241
|
+
|
|
242
|
+
* Remember when a database connection has recently been verified (for
|
|
243
|
+
two seconds, by default), to avoid repeated reverifications during a
|
|
244
|
+
single request.
|
|
245
|
+
|
|
246
|
+
This should recreate a similar rate of verification as in Rails 7.1,
|
|
247
|
+
where connections are leased for the duration of a request, and thus
|
|
248
|
+
only verified once.
|
|
249
|
+
|
|
250
|
+
*Matthew Draper*
|
|
251
|
+
|
|
252
|
+
* Fix prepared statements on mysql2 adapter.
|
|
253
|
+
|
|
254
|
+
*Jean Boussier*
|
|
255
|
+
|
|
256
|
+
* Fix a race condition in `ActiveRecord::Base#method_missing` when lazily defining attributes.
|
|
257
|
+
|
|
258
|
+
If multiple thread were concurrently triggering attribute definition on the same model,
|
|
259
|
+
it could result in a `NoMethodError` being raised.
|
|
260
|
+
|
|
261
|
+
*Jean Boussier*
|
|
262
|
+
|
|
263
|
+
* Fix MySQL default functions getting dropped when changing a column's nullability.
|
|
264
|
+
|
|
265
|
+
*Bastian Bartmann*
|
|
266
|
+
|
|
267
|
+
* Fix `add_unique_constraint`/`add_check_constraint`/`/`add_foreign_key` to be revertible when
|
|
268
|
+
given invalid options.
|
|
269
|
+
|
|
270
|
+
*fatkodima*
|
|
271
|
+
|
|
272
|
+
* Fix asynchronous destroying of polymorphic `belongs_to` associations.
|
|
273
|
+
|
|
274
|
+
*fatkodima*
|
|
275
|
+
|
|
276
|
+
* NOT VALID constraints should not dump in `create_table`.
|
|
277
|
+
|
|
180
278
|
*Ryuta Kamizono*
|
|
181
279
|
|
|
182
|
-
*
|
|
183
|
-
whether preloaded / eager loaded or not, with the exception of `unscoped`.
|
|
280
|
+
* Fix finding by nil composite primary key association.
|
|
184
281
|
|
|
185
|
-
|
|
282
|
+
*fatkodima*
|
|
283
|
+
|
|
284
|
+
* Fix parsing of SQLite foreign key names when they contain non-ASCII characters
|
|
285
|
+
|
|
286
|
+
*Zacharias Knudsen*
|
|
287
|
+
|
|
288
|
+
* Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines.
|
|
289
|
+
|
|
290
|
+
*Steve Hill*
|
|
291
|
+
|
|
292
|
+
* Ensure normalized attribute queries use `IS NULL` consistently for `nil` and normalized `nil` values.
|
|
293
|
+
|
|
294
|
+
*Joshua Young*
|
|
295
|
+
|
|
296
|
+
* Restore back the ability to pass only database name for `DATABASE_URL`.
|
|
297
|
+
|
|
298
|
+
*fatkodima*
|
|
299
|
+
|
|
300
|
+
* Fix `order` with using association name as an alias.
|
|
301
|
+
|
|
302
|
+
*Ryuta Kamizono*
|
|
303
|
+
|
|
304
|
+
* Improve invalid argument error for with.
|
|
305
|
+
|
|
306
|
+
*Ryuta Kamizono*
|
|
307
|
+
|
|
308
|
+
* Deduplicate `with` CTE expressions.
|
|
309
|
+
|
|
310
|
+
*fatkodima*
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
## Rails 7.2.2.2 (August 13, 2025) ##
|
|
314
|
+
|
|
315
|
+
* Call inspect on ids in RecordNotFound error
|
|
316
|
+
|
|
317
|
+
[CVE-2025-55193]
|
|
318
|
+
|
|
319
|
+
*Gannon McGibbon*, *John Hawthorn*
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
## Rails 7.2.2.1 (December 10, 2024) ##
|
|
323
|
+
|
|
324
|
+
* No changes.
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
## Rails 7.2.2 (October 30, 2024) ##
|
|
328
|
+
|
|
329
|
+
* Fix support for `query_cache: false` in `database.yml`.
|
|
330
|
+
|
|
331
|
+
`query_cache: false` would no longer entirely disable the Active Record query cache.
|
|
332
|
+
|
|
333
|
+
*zzak*
|
|
334
|
+
|
|
335
|
+
* Set `.attributes_for_inspect` to `:all` by default.
|
|
336
|
+
|
|
337
|
+
For new applications it is set to `[:id]` in config/environment/production.rb.
|
|
338
|
+
|
|
339
|
+
In the console all the attributes are always shown.
|
|
340
|
+
|
|
341
|
+
*Andrew Novoselac*
|
|
342
|
+
|
|
343
|
+
* `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
|
|
344
|
+
|
|
345
|
+
*Kazuma Watanabe*
|
|
346
|
+
|
|
347
|
+
* Fix marshalling of unsaved associated records in 7.1 format.
|
|
348
|
+
|
|
349
|
+
The 7.1 format would only marshal associated records if the association was loaded.
|
|
350
|
+
But associations that would only contain unsaved records would be skipped.
|
|
351
|
+
|
|
352
|
+
*Jean Boussier*
|
|
353
|
+
|
|
354
|
+
* Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
|
|
355
|
+
|
|
356
|
+
*David Stosik*
|
|
357
|
+
|
|
358
|
+
* Allow to save records with polymorphic join tables that have `inverse_of`
|
|
359
|
+
specified.
|
|
360
|
+
|
|
361
|
+
*Markus Doits*
|
|
362
|
+
|
|
363
|
+
* Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
|
|
364
|
+
|
|
365
|
+
*Joshua Young*
|
|
366
|
+
|
|
367
|
+
* Fix `dependent: :destroy` for bi-directional has one through association.
|
|
368
|
+
|
|
369
|
+
Fixes #50948.
|
|
186
370
|
|
|
187
371
|
```ruby
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
372
|
+
class Left < ActiveRecord::Base
|
|
373
|
+
has_one :middle, dependent: :destroy
|
|
374
|
+
has_one :right, through: :middle
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
class Middle < ActiveRecord::Base
|
|
378
|
+
belongs_to :left, dependent: :destroy
|
|
379
|
+
belongs_to :right, dependent: :destroy
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
class Right < ActiveRecord::Base
|
|
383
|
+
has_one :middle, dependent: :destroy
|
|
384
|
+
has_one :left, through: :middle
|
|
192
385
|
end
|
|
193
386
|
```
|
|
387
|
+
In the above example `left.destroy` wouldn't destroy its associated `Right`
|
|
388
|
+
record.
|
|
194
389
|
|
|
195
|
-
|
|
390
|
+
*Andy Stewart*
|
|
391
|
+
|
|
392
|
+
* Properly handle lazily pinned connection pools.
|
|
393
|
+
|
|
394
|
+
Fixes #53147.
|
|
395
|
+
|
|
396
|
+
When using transactional fixtures with system tests to similar tools
|
|
397
|
+
such as capybara, it could happen that a connection end up pinned by the
|
|
398
|
+
server thread rather than the test thread, causing
|
|
399
|
+
`"Cannot expire connection, it is owned by a different thread"` errors.
|
|
400
|
+
|
|
401
|
+
*Jean Boussier*
|
|
402
|
+
|
|
403
|
+
* Fix `ActiveRecord::Base.with` to accept more than two sub queries.
|
|
404
|
+
|
|
405
|
+
Fixes #53110.
|
|
196
406
|
|
|
197
407
|
```ruby
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
|
201
|
-
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
|
202
|
-
end
|
|
408
|
+
User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
|
|
409
|
+
undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
|
|
203
410
|
```
|
|
204
411
|
|
|
205
|
-
|
|
412
|
+
The above now works as expected.
|
|
206
413
|
|
|
207
|
-
*
|
|
414
|
+
*fatkodima*
|
|
208
415
|
|
|
209
|
-
*
|
|
416
|
+
* Properly release pinned connections with non joinable connections.
|
|
210
417
|
|
|
211
|
-
|
|
418
|
+
Fixes #52973
|
|
212
419
|
|
|
213
|
-
|
|
420
|
+
When running system tests with transactional fixtures on, it could happen that
|
|
421
|
+
the connection leased by the Puma thread wouldn't be properly released back to the pool,
|
|
422
|
+
causing "Cannot expire connection, it is owned by a different thread" errors in later tests.
|
|
214
423
|
|
|
215
|
-
*
|
|
424
|
+
*Jean Boussier*
|
|
216
425
|
|
|
217
|
-
|
|
426
|
+
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
|
218
427
|
|
|
219
|
-
|
|
220
|
-
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
|
428
|
+
Fixes #52742
|
|
221
429
|
|
|
222
|
-
|
|
430
|
+
*Ryota Kitazawa*, *Takayuki Nagatomi*
|
|
223
431
|
|
|
224
|
-
|
|
432
|
+
* Fix an issue where `.left_outer_joins` used with multiple associations that have
|
|
433
|
+
the same child association but different parents does not join all parents.
|
|
225
434
|
|
|
226
|
-
|
|
435
|
+
Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
|
|
227
436
|
|
|
228
|
-
|
|
229
|
-
account.memberships.extract_associated(:user)
|
|
230
|
-
# => Returns collection of User records
|
|
231
|
-
```
|
|
437
|
+
Now it will correctly join both parents.
|
|
232
438
|
|
|
233
|
-
|
|
439
|
+
Fixes #41498.
|
|
234
440
|
|
|
235
|
-
*
|
|
441
|
+
*Garrett Blehm*
|
|
236
442
|
|
|
237
|
-
|
|
443
|
+
* Ensure `ActiveRecord::Encryption.config` is always ready before access.
|
|
238
444
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
```
|
|
445
|
+
Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
|
|
446
|
+
was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
|
|
447
|
+
`ActiveRecord::Base` was loaded would give incorrect results.
|
|
243
448
|
|
|
244
|
-
|
|
449
|
+
`ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
|
|
450
|
+
soon as needed.
|
|
245
451
|
|
|
246
|
-
|
|
452
|
+
When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
|
|
453
|
+
`ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
|
|
454
|
+
before any use of `ActiveRecord::Base`.
|
|
247
455
|
|
|
248
|
-
*
|
|
456
|
+
*Maxime Réty*
|
|
249
457
|
|
|
250
|
-
|
|
251
|
-
|
|
458
|
+
* Add `TimeZoneConverter#==` method, so objects will be properly compared by
|
|
459
|
+
their type, scale, limit & precision.
|
|
252
460
|
|
|
253
|
-
|
|
461
|
+
Address #52699.
|
|
254
462
|
|
|
255
|
-
|
|
256
|
-
# SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
|
|
463
|
+
*Ruy Rocha*
|
|
257
464
|
|
|
258
|
-
Example (for PostgreSQL with pg_hint_plan):
|
|
259
465
|
|
|
260
|
-
|
|
261
|
-
# SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
|
466
|
+
## Rails 7.2.1.2 (October 23, 2024) ##
|
|
262
467
|
|
|
263
|
-
|
|
468
|
+
* No changes.
|
|
264
469
|
|
|
265
|
-
* https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html
|
|
266
|
-
* https://pghintplan.osdn.jp/pg_hint_plan.html
|
|
267
|
-
* https://docs.oracle.com/en/database/oracle/oracle-database/12.2/tgsql/influencing-the-optimizer.html
|
|
268
|
-
* https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-2017
|
|
269
|
-
* https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.admin.perf.doc/doc/c0070117.html
|
|
270
470
|
|
|
271
|
-
|
|
471
|
+
## Rails 7.2.1.1 (October 15, 2024) ##
|
|
272
472
|
|
|
273
|
-
*
|
|
473
|
+
* No changes.
|
|
274
474
|
|
|
275
|
-
For example, the following code no longer return false as casted non-empty string:
|
|
276
475
|
|
|
277
|
-
|
|
278
|
-
class Post < ActiveRecord::Base
|
|
279
|
-
attribute :user_defined_text, :text
|
|
280
|
-
end
|
|
476
|
+
## Rails 7.2.1 (August 22, 2024) ##
|
|
281
477
|
|
|
282
|
-
|
|
283
|
-
```
|
|
478
|
+
* Fix detection for `enum` columns with parallelized tests and PostgreSQL.
|
|
284
479
|
|
|
285
|
-
*
|
|
480
|
+
*Rafael Mendonça França*
|
|
286
481
|
|
|
287
|
-
*
|
|
482
|
+
* Allow to eager load nested nil associations.
|
|
288
483
|
|
|
289
|
-
*
|
|
484
|
+
*fatkodima*
|
|
290
485
|
|
|
291
|
-
*
|
|
292
|
-
allowing bulk inserts akin to the bulk updates provided by `update_all` and
|
|
293
|
-
bulk deletes by `delete_all`.
|
|
486
|
+
* Fix swallowing ignore order warning when batching using `BatchEnumerator`.
|
|
294
487
|
|
|
295
|
-
|
|
296
|
-
for PostgreSQL (9.5+) and SQLite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
|
|
297
|
-
for MySQL.
|
|
488
|
+
*fatkodima*
|
|
298
489
|
|
|
299
|
-
|
|
490
|
+
* Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
|
|
300
491
|
|
|
301
|
-
*
|
|
302
|
-
for current environment and loads the seeds.
|
|
492
|
+
*Jean Boussier*
|
|
303
493
|
|
|
304
|
-
|
|
494
|
+
* Restore inferred association class with the same modularized name.
|
|
305
495
|
|
|
306
|
-
*
|
|
496
|
+
*Justin Ko*
|
|
307
497
|
|
|
308
|
-
|
|
498
|
+
* Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
|
|
309
499
|
|
|
310
|
-
*
|
|
500
|
+
*Jean Boussier*
|
|
311
501
|
|
|
312
|
-
|
|
313
|
-
To continue case sensitive comparison on the case insensitive column,
|
|
314
|
-
pass `case_sensitive: true` option explicitly to the uniqueness validator.
|
|
502
|
+
* Check invalid `enum` options for the new syntax.
|
|
315
503
|
|
|
316
|
-
|
|
504
|
+
The options using `_` prefix in the old syntax are invalid in the new syntax.
|
|
317
505
|
|
|
318
|
-
*
|
|
506
|
+
*Rafael Mendonça França*
|
|
319
507
|
|
|
320
|
-
|
|
508
|
+
* Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
|
|
509
|
+
actual cast type.
|
|
321
510
|
|
|
322
|
-
*
|
|
511
|
+
*Vasiliy Ermolovich*
|
|
323
512
|
|
|
324
|
-
*
|
|
513
|
+
* Fix `create_table` with `:auto_increment` option for MySQL adapter.
|
|
325
514
|
|
|
326
|
-
|
|
515
|
+
*fatkodima*
|
|
327
516
|
|
|
328
|
-
class Post < ActiveRecord::Base
|
|
329
|
-
enum status: %i[ drafted active trashed ]
|
|
330
|
-
end
|
|
331
517
|
|
|
332
|
-
|
|
333
|
-
Post.not_active # => where.not(status: :active)
|
|
334
|
-
Post.not_trashed # => where.not(status: :trashed)
|
|
518
|
+
## Rails 7.2.0 (August 09, 2024) ##
|
|
335
519
|
|
|
336
|
-
|
|
520
|
+
* Handle commas in Sqlite3 default function definitions.
|
|
337
521
|
|
|
338
|
-
*
|
|
522
|
+
*Stephen Margheim*
|
|
339
523
|
|
|
340
|
-
|
|
524
|
+
* Fixes `validates_associated` raising an exception when configured with a
|
|
525
|
+
singular association and having `index_nested_attribute_errors` enabled.
|
|
341
526
|
|
|
342
|
-
*
|
|
527
|
+
*Martin Spickermann*
|
|
343
528
|
|
|
529
|
+
* The constant `ActiveRecord::ImmutableRelation` has been deprecated because
|
|
530
|
+
we want to reserve that name for a stronger sense of "immutable relation".
|
|
531
|
+
Please use `ActiveRecord::UnmodifiableRelation` instead.
|
|
344
532
|
|
|
345
|
-
|
|
533
|
+
*Xavier Noria*
|
|
346
534
|
|
|
347
|
-
*
|
|
535
|
+
* Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
|
|
536
|
+
`DatabaseConfig`.
|
|
348
537
|
|
|
538
|
+
*Hartley McGuire*
|
|
349
539
|
|
|
350
|
-
|
|
540
|
+
* Fixed a memory performance issue in Active Record attribute methods definition.
|
|
351
541
|
|
|
352
|
-
*
|
|
542
|
+
*Jean Boussier*
|
|
353
543
|
|
|
354
|
-
|
|
544
|
+
* Define the new Active Support notification event `start_transaction.active_record`.
|
|
355
545
|
|
|
356
|
-
|
|
546
|
+
This event is fired when database transactions or savepoints start, and
|
|
547
|
+
complements `transaction.active_record`, which is emitted when they finish.
|
|
357
548
|
|
|
358
|
-
|
|
549
|
+
The payload has the transaction (`:transaction`) and the connection (`:connection`).
|
|
359
550
|
|
|
360
|
-
*
|
|
551
|
+
*Xavier Noria*
|
|
361
552
|
|
|
362
|
-
|
|
553
|
+
* Fix an issue where the IDs reader method did not return expected results
|
|
554
|
+
for preloaded associations in models using composite primary keys.
|
|
363
555
|
|
|
364
|
-
*
|
|
556
|
+
*Jay Ang*
|
|
365
557
|
|
|
366
|
-
|
|
367
|
-
`destroy_all` on the matched records.
|
|
558
|
+
* The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
|
|
368
559
|
|
|
369
|
-
|
|
560
|
+
*Xavier Noria*
|
|
370
561
|
|
|
371
|
-
|
|
372
|
-
Person.destroy_by(name: 'David', rating: 4)
|
|
562
|
+
* The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
|
|
373
563
|
|
|
374
|
-
|
|
375
|
-
david.posts.destroy_by(id: [1, 2, 3])
|
|
564
|
+
*Xavier Noria*
|
|
376
565
|
|
|
377
|
-
|
|
378
|
-
`delete_all` on the matched records.
|
|
566
|
+
* 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.
|
|
379
567
|
|
|
380
|
-
|
|
568
|
+
*Xavier Noria*
|
|
381
569
|
|
|
382
|
-
|
|
383
|
-
Person.delete_by(name: 'David', rating: 4)
|
|
570
|
+
* Fix inference of association model on nested models with the same demodularized name.
|
|
384
571
|
|
|
385
|
-
|
|
386
|
-
david.posts.delete_by(id: [1, 2, 3])
|
|
572
|
+
E.g. with the following setup:
|
|
387
573
|
|
|
388
|
-
|
|
574
|
+
```ruby
|
|
575
|
+
class Nested::Post < ApplicationRecord
|
|
576
|
+
has_one :post, through: :other
|
|
577
|
+
end
|
|
578
|
+
```
|
|
389
579
|
|
|
390
|
-
|
|
580
|
+
Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
|
|
391
581
|
|
|
392
|
-
|
|
582
|
+
*Joshua Young*
|
|
393
583
|
|
|
394
|
-
|
|
584
|
+
* PostgreSQL `Cidr#change?` detects the address prefix change.
|
|
395
585
|
|
|
396
|
-
*
|
|
586
|
+
*Taketo Takashima*
|
|
397
587
|
|
|
398
|
-
|
|
588
|
+
* Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
|
|
399
589
|
|
|
400
|
-
|
|
401
|
-
regarded as leaked. Use `klass.unscoped` to avoid the leaking scope.
|
|
590
|
+
Previously, it always returned `nil`.
|
|
402
591
|
|
|
403
|
-
*
|
|
592
|
+
*fatkodima*
|
|
593
|
+
|
|
594
|
+
* Support `touch_all` in batches.
|
|
595
|
+
|
|
596
|
+
```ruby
|
|
597
|
+
Post.in_batches.touch_all
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
*fatkodima*
|
|
404
601
|
|
|
405
|
-
*
|
|
602
|
+
* Add support for `:if_not_exists` and `:force` options to `create_schema`.
|
|
406
603
|
|
|
407
|
-
|
|
408
|
-
application to automatically switch between the writing and reading
|
|
409
|
-
database connections.
|
|
604
|
+
*fatkodima*
|
|
410
605
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
606
|
+
* Fix `index_errors` having incorrect index in association validation errors.
|
|
607
|
+
|
|
608
|
+
*lulalala*
|
|
609
|
+
|
|
610
|
+
* Add `index_errors: :nested_attributes_order` mode.
|
|
611
|
+
|
|
612
|
+
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.
|
|
613
|
+
|
|
614
|
+
*lulalala*
|
|
615
|
+
|
|
616
|
+
* Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
|
|
617
|
+
|
|
618
|
+
*Joé Dupuis*
|
|
619
|
+
|
|
620
|
+
* Association option `query_constraints` is deprecated in favor of `foreign_key`.
|
|
621
|
+
|
|
622
|
+
*Nikita Vasilevsky*
|
|
623
|
+
|
|
624
|
+
* Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
|
|
625
|
+
|
|
626
|
+
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.
|
|
627
|
+
|
|
628
|
+
*DHH*
|
|
417
629
|
|
|
418
|
-
|
|
419
|
-
configuration options:
|
|
630
|
+
* Added support for recursive common table expressions.
|
|
420
631
|
|
|
632
|
+
```ruby
|
|
633
|
+
Post.with_recursive(
|
|
634
|
+
post_and_replies: [
|
|
635
|
+
Post.where(id: 42),
|
|
636
|
+
Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
|
|
637
|
+
]
|
|
638
|
+
)
|
|
421
639
|
```
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
640
|
+
|
|
641
|
+
Generates the following SQL:
|
|
642
|
+
|
|
643
|
+
```sql
|
|
644
|
+
WITH RECURSIVE "post_and_replies" AS (
|
|
645
|
+
(SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
|
|
646
|
+
UNION ALL
|
|
647
|
+
(SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
|
|
648
|
+
)
|
|
649
|
+
SELECT "posts".* FROM "posts"
|
|
425
650
|
```
|
|
426
651
|
|
|
427
|
-
|
|
428
|
-
configuration options:
|
|
652
|
+
*ClearlyClaire*
|
|
429
653
|
|
|
654
|
+
* `validate_constraint` can be called in a `change_table` block.
|
|
655
|
+
|
|
656
|
+
ex:
|
|
657
|
+
```ruby
|
|
658
|
+
change_table :products do |t|
|
|
659
|
+
t.check_constraint "price > discounted_price", name: "price_check", validate: false
|
|
660
|
+
t.validate_check_constraint "price_check"
|
|
661
|
+
end
|
|
430
662
|
```
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
663
|
+
|
|
664
|
+
*Cody Cutrer*
|
|
665
|
+
|
|
666
|
+
* `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
|
|
667
|
+
|
|
668
|
+
Ex:
|
|
669
|
+
```ruby
|
|
670
|
+
ActiveRecord::Base.connection
|
|
671
|
+
.select_value("select '2024-01-01'::date").class #=> Date
|
|
434
672
|
```
|
|
435
673
|
|
|
436
|
-
*
|
|
674
|
+
*Joé Dupuis*
|
|
437
675
|
|
|
438
|
-
*
|
|
676
|
+
* Strict loading using `:n_plus_one_only` does not eagerly load child associations.
|
|
439
677
|
|
|
440
|
-
|
|
678
|
+
With this change, child associations are no longer eagerly loaded, to
|
|
679
|
+
match intended behavior and to prevent non-deterministic order issues caused
|
|
680
|
+
by calling methods like `first` or `last`. As `first` and `last` don't cause
|
|
681
|
+
an N+1 by themselves, calling child associations will no longer raise.
|
|
682
|
+
Fixes #49473.
|
|
441
683
|
|
|
442
|
-
|
|
684
|
+
Before:
|
|
443
685
|
|
|
444
|
-
|
|
686
|
+
```ruby
|
|
687
|
+
person = Person.find(1)
|
|
688
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
|
689
|
+
person.posts.first
|
|
690
|
+
# SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
|
|
691
|
+
person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
|
|
692
|
+
```
|
|
445
693
|
|
|
694
|
+
After:
|
|
446
695
|
|
|
447
|
-
|
|
696
|
+
```ruby
|
|
697
|
+
person = Person.find(1)
|
|
698
|
+
person.strict_loading!(mode: :n_plus_one_only)
|
|
699
|
+
person.posts.first # this is 1+1, not N+1
|
|
700
|
+
# SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
|
|
701
|
+
person.posts.first.firm # no longer raises
|
|
702
|
+
```
|
|
448
703
|
|
|
449
|
-
*
|
|
704
|
+
*Reid Lynch*
|
|
450
705
|
|
|
451
|
-
|
|
706
|
+
* Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
|
|
452
707
|
|
|
453
|
-
*
|
|
708
|
+
*Mike Dalessio*
|
|
454
709
|
|
|
455
|
-
|
|
710
|
+
* Allow `ActiveRecord::Base#pluck` to accept hash values.
|
|
456
711
|
|
|
457
|
-
|
|
712
|
+
```ruby
|
|
713
|
+
# Before
|
|
714
|
+
Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
|
|
458
715
|
|
|
459
|
-
|
|
716
|
+
# After
|
|
717
|
+
Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
|
|
718
|
+
```
|
|
460
719
|
|
|
461
|
-
*
|
|
720
|
+
*fatkodima*
|
|
462
721
|
|
|
463
|
-
|
|
722
|
+
* Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
|
|
464
723
|
|
|
465
|
-
*
|
|
724
|
+
*Kevin McPhillips*
|
|
466
725
|
|
|
467
|
-
|
|
726
|
+
* `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
|
|
727
|
+
|
|
728
|
+
This allows to register callbacks on it.
|
|
729
|
+
|
|
730
|
+
```ruby
|
|
731
|
+
Article.transaction do |transaction|
|
|
732
|
+
article.update(published: true)
|
|
733
|
+
transaction.after_commit do
|
|
734
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
*Jean Boussier*
|
|
740
|
+
|
|
741
|
+
* Add `ActiveRecord::Base.current_transaction`.
|
|
742
|
+
|
|
743
|
+
Returns the current transaction, to allow registering callbacks on it.
|
|
744
|
+
|
|
745
|
+
```ruby
|
|
746
|
+
Article.current_transaction.after_commit do
|
|
747
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
748
|
+
end
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
*Jean Boussier*
|
|
752
|
+
|
|
753
|
+
* Add `ActiveRecord.after_all_transactions_commit` callback.
|
|
754
|
+
|
|
755
|
+
Useful for code that may run either inside or outside a transaction and needs
|
|
756
|
+
to perform work after the state changes have been properly persisted.
|
|
757
|
+
|
|
758
|
+
```ruby
|
|
759
|
+
def publish_article(article)
|
|
760
|
+
article.update(published: true)
|
|
761
|
+
ActiveRecord.after_all_transactions_commit do
|
|
762
|
+
PublishNotificationMailer.with(article: article).deliver_later
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
In the above example, the block is either executed immediately if called outside
|
|
768
|
+
of a transaction, or called after the open transaction is committed.
|
|
769
|
+
|
|
770
|
+
If the transaction is rolled back, the block isn't called.
|
|
771
|
+
|
|
772
|
+
*Jean Boussier*
|
|
773
|
+
|
|
774
|
+
* Add the ability to ignore counter cache columns until they are backfilled.
|
|
775
|
+
|
|
776
|
+
Starting to use counter caches on existing large tables can be troublesome, because the column
|
|
777
|
+
values must be backfilled separately of the column addition (to not lock the table for too long)
|
|
778
|
+
and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
|
|
779
|
+
counter caches internally, can produce incorrect results). People usually use database triggers
|
|
780
|
+
or callbacks on child associations while backfilling before introducing a counter cache
|
|
781
|
+
configuration to the association.
|
|
782
|
+
|
|
783
|
+
Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
|
|
784
|
+
|
|
785
|
+
```ruby
|
|
786
|
+
class Comment < ApplicationRecord
|
|
787
|
+
belongs_to :post, counter_cache: { active: false }
|
|
788
|
+
end
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
|
|
792
|
+
but get the results directly from the database. After the counter cache column is backfilled, simply
|
|
793
|
+
remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
|
|
794
|
+
mentioned methods.
|
|
795
|
+
|
|
796
|
+
*fatkodima*
|
|
797
|
+
|
|
798
|
+
* Retry known idempotent SELECT queries on connection-related exceptions.
|
|
799
|
+
|
|
800
|
+
SELECT queries we construct by walking the Arel tree and / or with known model attributes
|
|
801
|
+
are idempotent and can safely be retried in the case of a connection error. Previously,
|
|
802
|
+
adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
|
|
803
|
+
when encountering a connection error mid-request.
|
|
804
|
+
|
|
805
|
+
*Adrianna Chang*
|
|
806
|
+
|
|
807
|
+
* Allow association's `foreign_key` to be composite.
|
|
808
|
+
|
|
809
|
+
`query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
|
|
810
|
+
Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
|
|
811
|
+
|
|
812
|
+
*Nikita Vasilevsky*
|
|
813
|
+
|
|
814
|
+
* Allow association's `primary_key` to be composite.
|
|
815
|
+
|
|
816
|
+
Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
|
|
817
|
+
Now it's possible to explicitly set it as composite on the association.
|
|
818
|
+
|
|
819
|
+
*Nikita Vasilevsky*
|
|
820
|
+
|
|
821
|
+
* Add `config.active_record.permanent_connection_checkout` setting.
|
|
468
822
|
|
|
469
|
-
|
|
823
|
+
Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
|
|
824
|
+
|
|
825
|
+
`ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
|
|
826
|
+
the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
|
|
827
|
+
is available connections.
|
|
828
|
+
|
|
829
|
+
This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
|
|
830
|
+
migrate it to use `ActiveRecord::Base.with_connection` instead.
|
|
831
|
+
|
|
832
|
+
The default behavior remains unchanged, and there is currently no plans to change the default.
|
|
833
|
+
|
|
834
|
+
*Jean Boussier*
|
|
835
|
+
|
|
836
|
+
* Add dirties option to uncached.
|
|
837
|
+
|
|
838
|
+
This adds a `dirties` option to `ActiveRecord::Base.uncached` and
|
|
839
|
+
`ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
|
|
840
|
+
|
|
841
|
+
When set to `true` (the default), writes will clear all query caches belonging to the current thread.
|
|
842
|
+
When set to `false`, writes to the affected connection pool will not clear any query cache.
|
|
843
|
+
|
|
844
|
+
This is needed by Solid Cache so that cache writes do not clear query caches.
|
|
845
|
+
|
|
846
|
+
*Donal McBreen*
|
|
847
|
+
|
|
848
|
+
* Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
|
|
849
|
+
|
|
850
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
|
851
|
+
connection will be held for the duration of the request or job.
|
|
852
|
+
|
|
853
|
+
This deprecation is a soft deprecation, no warnings will be issued and there is no
|
|
854
|
+
current plan to remove the method.
|
|
855
|
+
|
|
856
|
+
*Jean Boussier*
|
|
857
|
+
|
|
858
|
+
* Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
|
|
859
|
+
|
|
860
|
+
The method has been renamed as `lease_connection` to better reflect that the returned
|
|
861
|
+
connection will be held for the duration of the request or job.
|
|
862
|
+
|
|
863
|
+
*Jean Boussier*
|
|
864
|
+
|
|
865
|
+
* Expose a generic fixture accessor for fixture names that may conflict with Minitest.
|
|
866
|
+
|
|
867
|
+
```ruby
|
|
868
|
+
assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
|
869
|
+
assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
*Jean Boussier*
|
|
873
|
+
|
|
874
|
+
* Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
|
|
875
|
+
incorrect error message.
|
|
876
|
+
|
|
877
|
+
This has been fixed to raise with a more appropriate error message.
|
|
878
|
+
|
|
879
|
+
*Joshua Young*
|
|
880
|
+
|
|
881
|
+
* Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
|
|
882
|
+
|
|
883
|
+
This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
|
|
884
|
+
an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
|
|
885
|
+
|
|
886
|
+
*Joshua Young*
|
|
887
|
+
|
|
888
|
+
* Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
|
|
470
889
|
|
|
471
890
|
*Rafael Mendonça França*
|
|
472
891
|
|
|
473
|
-
*
|
|
892
|
+
* Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
|
|
474
893
|
|
|
475
894
|
*Rafael Mendonça França*
|
|
476
895
|
|
|
477
|
-
* Remove
|
|
896
|
+
* Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
|
|
478
897
|
|
|
479
898
|
*Rafael Mendonça França*
|
|
480
899
|
|
|
481
|
-
*
|
|
900
|
+
* Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
|
|
482
901
|
|
|
483
902
|
*Rafael Mendonça França*
|
|
484
903
|
|
|
485
|
-
*
|
|
904
|
+
* Remove deprecated support to quote `ActiveSupport::Duration`.
|
|
486
905
|
|
|
487
906
|
*Rafael Mendonça França*
|
|
488
907
|
|
|
489
|
-
* Remove
|
|
908
|
+
* Remove deprecated `#quote_bound_value`.
|
|
490
909
|
|
|
491
910
|
*Rafael Mendonça França*
|
|
492
911
|
|
|
493
|
-
* Remove deprecated `ActiveRecord::
|
|
912
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
|
|
494
913
|
|
|
495
914
|
*Rafael Mendonça França*
|
|
496
915
|
|
|
497
|
-
* Remove deprecated
|
|
916
|
+
* Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
|
|
917
|
+
`#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
|
|
918
|
+
for the current role when the `role` argument isn't provided.
|
|
498
919
|
|
|
499
920
|
*Rafael Mendonça França*
|
|
500
921
|
|
|
501
|
-
*
|
|
922
|
+
* Remove deprecated `#all_connection_pools`.
|
|
502
923
|
|
|
503
|
-
|
|
924
|
+
*Rafael Mendonça França*
|
|
504
925
|
|
|
505
|
-
|
|
926
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
|
|
506
927
|
|
|
507
|
-
*
|
|
928
|
+
*Rafael Mendonça França*
|
|
508
929
|
|
|
509
|
-
|
|
930
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
|
|
510
931
|
|
|
511
|
-
*
|
|
932
|
+
*Rafael Mendonça França*
|
|
512
933
|
|
|
513
|
-
|
|
934
|
+
* Remove deprecated `#all_foreign_keys_valid?` from database adapters.
|
|
514
935
|
|
|
515
|
-
*
|
|
936
|
+
*Rafael Mendonça França*
|
|
516
937
|
|
|
517
|
-
|
|
938
|
+
* Remove deprecated support to passing coder and class as second argument to `serialize`.
|
|
518
939
|
|
|
519
|
-
*
|
|
940
|
+
*Rafael Mendonça França*
|
|
520
941
|
|
|
521
|
-
|
|
522
|
-
format for InnoDB tables. The default setting is `DYNAMIC`.
|
|
523
|
-
The row format is required for indexing on `varchar(255)` with `utf8mb4` columns.
|
|
942
|
+
* Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
|
|
524
943
|
|
|
525
|
-
*
|
|
944
|
+
*Rafael Mendonça França*
|
|
526
945
|
|
|
527
|
-
*
|
|
946
|
+
* Remove deprecated `TestFixtures.fixture_path`.
|
|
528
947
|
|
|
529
|
-
*
|
|
948
|
+
*Rafael Mendonça França*
|
|
530
949
|
|
|
531
|
-
*
|
|
950
|
+
* Remove deprecated behavior to support referring to a singular association by its plural name.
|
|
532
951
|
|
|
533
|
-
*
|
|
952
|
+
*Rafael Mendonça França*
|
|
534
953
|
|
|
535
|
-
*
|
|
954
|
+
* Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
|
|
536
955
|
|
|
537
|
-
*
|
|
956
|
+
*Rafael Mendonça França*
|
|
538
957
|
|
|
539
|
-
*
|
|
958
|
+
* Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
|
|
959
|
+
`ActiveRecord::MigrationContext`.
|
|
540
960
|
|
|
541
|
-
*
|
|
961
|
+
*Rafael Mendonça França*
|
|
542
962
|
|
|
543
|
-
*
|
|
963
|
+
* Remove deprecated `ActiveRecord::Migration.check_pending!` method.
|
|
544
964
|
|
|
545
|
-
|
|
546
|
-
you're building out multiple databases and want to make sure you're not sending
|
|
547
|
-
writes when you want a read.
|
|
965
|
+
*Rafael Mendonça França*
|
|
548
966
|
|
|
549
|
-
|
|
550
|
-
query the database will raise an exception regardless of whether the database
|
|
551
|
-
user is able to write.
|
|
967
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
|
|
552
968
|
|
|
553
|
-
|
|
554
|
-
read-only queries without opening a second connection. One purpose of this is to
|
|
555
|
-
catch accidental writes, not all writes.
|
|
969
|
+
*Rafael Mendonça França*
|
|
556
970
|
|
|
557
|
-
|
|
971
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
|
|
558
972
|
|
|
559
|
-
*
|
|
973
|
+
*Rafael Mendonça França*
|
|
560
974
|
|
|
561
|
-
|
|
975
|
+
* Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
|
|
562
976
|
|
|
563
|
-
*
|
|
977
|
+
*Rafael Mendonça França*
|
|
564
978
|
|
|
565
|
-
|
|
979
|
+
* Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
|
|
566
980
|
|
|
567
|
-
*
|
|
981
|
+
*Rafael Mendonça França*
|
|
568
982
|
|
|
569
|
-
*
|
|
983
|
+
* Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
|
|
570
984
|
|
|
571
|
-
|
|
572
|
-
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
|
985
|
+
*Rafael Mendonça França*
|
|
573
986
|
|
|
574
|
-
|
|
575
|
-
class DeveloperName < ActiveRecord::Type::String
|
|
576
|
-
def deserialize(value)
|
|
577
|
-
"Developer: #{value}"
|
|
578
|
-
end
|
|
579
|
-
end
|
|
987
|
+
* Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
|
|
580
988
|
|
|
581
|
-
|
|
582
|
-
self.table_name = "developers"
|
|
989
|
+
*Rafael Mendonça França*
|
|
583
990
|
|
|
584
|
-
|
|
991
|
+
* Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
|
|
585
992
|
|
|
586
|
-
|
|
587
|
-
end
|
|
993
|
+
*Rafael Mendonça França*
|
|
588
994
|
|
|
589
|
-
|
|
590
|
-
developer.update_column :name, "name"
|
|
995
|
+
* Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
|
|
591
996
|
|
|
592
|
-
|
|
593
|
-
puts loaded_developer.name # should be "Developer: name" but it's just "name"
|
|
594
|
-
```
|
|
997
|
+
*Rafael Mendonça França*
|
|
595
998
|
|
|
596
|
-
|
|
999
|
+
* Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
|
|
597
1000
|
|
|
598
|
-
*
|
|
1001
|
+
*Rafael Mendonça França*
|
|
599
1002
|
|
|
600
|
-
|
|
601
|
-
explicit order clause, ActiveRecord sorts records by primary key. This can
|
|
602
|
-
result in unpredictable and surprising behaviour when the primary key is
|
|
603
|
-
not an auto-incrementing integer, for example when it's a UUID. This change
|
|
604
|
-
makes it possible to override the column used for implicit ordering such
|
|
605
|
-
that `first` and `last` will return more predictable results.
|
|
1003
|
+
* Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
|
|
606
1004
|
|
|
607
|
-
|
|
1005
|
+
*Rafael Mendonça França*
|
|
608
1006
|
|
|
609
|
-
|
|
610
|
-
self.implicit_order_column = "created_at"
|
|
611
|
-
end
|
|
1007
|
+
* Remove deprecated support to call `alias_attribute` with non-existent attribute names.
|
|
612
1008
|
|
|
613
|
-
*
|
|
1009
|
+
*Rafael Mendonça França*
|
|
614
1010
|
|
|
615
|
-
*
|
|
1011
|
+
* Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
|
|
616
1012
|
|
|
617
|
-
*
|
|
1013
|
+
*Rafael Mendonça França*
|
|
618
1014
|
|
|
619
|
-
*
|
|
1015
|
+
* Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
|
|
620
1016
|
|
|
621
|
-
|
|
1017
|
+
Serialize data to the MessagePack format, for efficient storage in binary columns.
|
|
622
1018
|
|
|
623
|
-
|
|
1019
|
+
The binary encoding requires around 30% less space than the base64 encoding
|
|
1020
|
+
used by the default serializer.
|
|
624
1021
|
|
|
625
|
-
|
|
1022
|
+
*Donal McBreen*
|
|
626
1023
|
|
|
627
|
-
|
|
1024
|
+
* Add support for encrypting binary columns.
|
|
628
1025
|
|
|
629
|
-
|
|
1026
|
+
Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
|
|
630
1027
|
|
|
631
|
-
|
|
1028
|
+
Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
|
|
1029
|
+
incidentally worked for MySQL and SQLite, but not PostgreSQL.
|
|
632
1030
|
|
|
633
|
-
|
|
634
|
-
class MySubclassedError < ActiveRecord::StatementInvalid
|
|
635
|
-
def initialize(message, sql:, binds:)
|
|
636
|
-
super(message, sql: sql, binds: binds)
|
|
637
|
-
end
|
|
638
|
-
end
|
|
639
|
-
```
|
|
1031
|
+
*Donal McBreen*
|
|
640
1032
|
|
|
641
|
-
|
|
1033
|
+
* Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
|
|
642
1034
|
|
|
643
|
-
*
|
|
1035
|
+
*Rafael Mendonça França*
|
|
644
1036
|
|
|
645
|
-
|
|
1037
|
+
* Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
|
|
646
1038
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
end
|
|
1039
|
+
The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
|
|
1040
|
+
will yield that same connection.
|
|
650
1041
|
|
|
651
|
-
|
|
1042
|
+
This is useful to perform a few database operations without causing a connection to be leased for the
|
|
1043
|
+
entire duration of the request or job.
|
|
652
1044
|
|
|
653
|
-
|
|
654
|
-
...
|
|
655
|
-
)
|
|
1045
|
+
*Jean Boussier*
|
|
656
1046
|
|
|
657
|
-
|
|
658
|
-
|
|
1047
|
+
* Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
|
|
1048
|
+
notification includes `:row_count` field.
|
|
659
1049
|
|
|
660
|
-
*
|
|
1050
|
+
*Jason Nochlin*
|
|
661
1051
|
|
|
662
|
-
*
|
|
1052
|
+
* Fix an issue with `where.associated` losing the current join type scope.
|
|
663
1053
|
|
|
664
|
-
|
|
1054
|
+
Example:
|
|
665
1055
|
|
|
666
|
-
|
|
1056
|
+
```ruby
|
|
1057
|
+
Post.left_joins(:author).where.associated(:author)
|
|
1058
|
+
```
|
|
667
1059
|
|
|
668
|
-
|
|
1060
|
+
Previously, the `LEFT OUTER JOIN` would be lost and converted to an `INNER JOIN`.
|
|
669
1061
|
|
|
670
|
-
*
|
|
671
|
-
if the attribute does not exist.
|
|
1062
|
+
*Saleh Alhaddad*
|
|
672
1063
|
|
|
673
|
-
|
|
1064
|
+
* Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
|
|
1065
|
+
of Active Record models, when an application is eager loaded. As a result, encrypted attributes
|
|
1066
|
+
could be misconfigured in some cases.
|
|
674
1067
|
|
|
675
|
-
*
|
|
1068
|
+
*Maxime Réty*
|
|
676
1069
|
|
|
677
|
-
|
|
678
|
-
User.connected_to(database: { writing: "postgres://foo" }) do
|
|
679
|
-
User.create!(name: "Gannon")
|
|
680
|
-
end
|
|
1070
|
+
* Deprecate defining an `enum` with keyword arguments.
|
|
681
1071
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
1072
|
+
```ruby
|
|
1073
|
+
class Function > ApplicationRecord
|
|
1074
|
+
# BAD
|
|
1075
|
+
enum color: [:red, :blue],
|
|
1076
|
+
type: [:instance, :class]
|
|
1077
|
+
|
|
1078
|
+
# GOOD
|
|
1079
|
+
enum :color, [:red, :blue]
|
|
1080
|
+
enum :type, [:instance, :class]
|
|
685
1081
|
end
|
|
686
|
-
|
|
1082
|
+
```
|
|
687
1083
|
|
|
688
|
-
*
|
|
1084
|
+
*Hartley McGuire*
|
|
689
1085
|
|
|
690
|
-
*
|
|
1086
|
+
* Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
|
|
691
1087
|
|
|
692
|
-
|
|
1088
|
+
When set, validates that the timestamp prefix for a migration is no more than a day ahead of
|
|
1089
|
+
the timestamp associated with the current time. This is designed to prevent migrations prefixes
|
|
1090
|
+
from being hand-edited to future timestamps, which impacts migration generation and other
|
|
1091
|
+
migration commands.
|
|
693
1092
|
|
|
694
|
-
|
|
1093
|
+
*Adrianna Chang*
|
|
695
1094
|
|
|
696
|
-
|
|
1095
|
+
* Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
|
|
697
1096
|
|
|
698
|
-
|
|
1097
|
+
As well as `disconnect!` and `verify!`.
|
|
699
1098
|
|
|
700
|
-
|
|
701
|
-
|
|
1099
|
+
This generally isn't a big problem as connections must not be shared between
|
|
1100
|
+
threads, but is required when running transactional tests or system tests
|
|
1101
|
+
and could lead to a SEGV.
|
|
702
1102
|
|
|
703
|
-
|
|
1103
|
+
*Jean Boussier*
|
|
704
1104
|
|
|
705
|
-
|
|
1105
|
+
* Support `:source_location` tag option for query log tags.
|
|
706
1106
|
|
|
707
|
-
|
|
1107
|
+
```ruby
|
|
1108
|
+
config.active_record.query_log_tags << :source_location
|
|
1109
|
+
```
|
|
708
1110
|
|
|
709
|
-
|
|
1111
|
+
Calculating the caller location is a costly operation and should be used primarily in development
|
|
1112
|
+
(note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
|
|
1113
|
+
or occasionally on production for debugging purposes.
|
|
710
1114
|
|
|
711
|
-
*
|
|
1115
|
+
*fatkodima*
|
|
712
1116
|
|
|
713
|
-
* Add
|
|
1117
|
+
* Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
|
|
714
1118
|
|
|
715
|
-
|
|
1119
|
+
Allow compression to be disabled by setting `compress: false`
|
|
716
1120
|
|
|
1121
|
+
```ruby
|
|
1122
|
+
class User
|
|
1123
|
+
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
|
|
1124
|
+
end
|
|
717
1125
|
```
|
|
718
|
-
class AnimalsModel < ApplicationRecord
|
|
719
|
-
self.abstract_class = true
|
|
720
1126
|
|
|
721
|
-
|
|
722
|
-
end
|
|
1127
|
+
*Donal McBreen*
|
|
723
1128
|
|
|
724
|
-
|
|
725
|
-
# connected to both the animals_primary db for writing and the animals_replica for reading
|
|
726
|
-
end
|
|
727
|
-
```
|
|
1129
|
+
* Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
|
|
728
1130
|
|
|
729
|
-
|
|
730
|
-
a database that the model didn't connect to. Connecting to the database in this block is
|
|
731
|
-
useful when you have another defined connection, for example `slow_replica` that you don't
|
|
732
|
-
want to connect to by default but need in the console, or a specific code block.
|
|
1131
|
+
A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
|
|
733
1132
|
|
|
734
|
-
|
|
735
|
-
ActiveRecord::Base.connected_to(role: :reading) do
|
|
736
|
-
Dog.first # finds dog from replica connected to AnimalsBase
|
|
737
|
-
Book.first # doesn't have a reading connection, will raise an error
|
|
738
|
-
end
|
|
739
|
-
```
|
|
1133
|
+
*Rafael Mendonça França*
|
|
740
1134
|
|
|
741
|
-
|
|
742
|
-
ActiveRecord::Base.connected_to(database: :slow_replica) do
|
|
743
|
-
SlowReplicaModel.first # if the db config has a slow_replica configuration this will be used to do the lookup, otherwise this will throw an exception
|
|
744
|
-
end
|
|
745
|
-
```
|
|
1135
|
+
* Add `row_count` field to `sql.active_record` notification.
|
|
746
1136
|
|
|
747
|
-
|
|
1137
|
+
This field returns the amount of rows returned by the query that emitted the notification.
|
|
748
1138
|
|
|
749
|
-
|
|
1139
|
+
This metric is useful in cases where one wants to detect queries with big result sets.
|
|
750
1140
|
|
|
751
|
-
|
|
752
|
-
commit checks that only valid definition values are provided, those can
|
|
753
|
-
be a Hash, an array of Symbols or an array of Strings. Otherwise it
|
|
754
|
-
raises an `ArgumentError`.
|
|
1141
|
+
*Marvin Bitterlich*
|
|
755
1142
|
|
|
756
|
-
|
|
1143
|
+
* Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
|
|
757
1144
|
|
|
758
|
-
|
|
1145
|
+
Previously, this would only raise on collection associations and produce a generic error on singular associations.
|
|
759
1146
|
|
|
760
|
-
|
|
1147
|
+
Now, it will raise on both collection and singular associations.
|
|
761
1148
|
|
|
762
|
-
|
|
763
|
-
class Post < ActiveRecord::Base
|
|
764
|
-
has_one :category
|
|
765
|
-
belongs_to :author
|
|
766
|
-
has_many :comments
|
|
767
|
-
end
|
|
1149
|
+
*Joshua Young*
|
|
768
1150
|
|
|
769
|
-
|
|
770
|
-
post.reload_category
|
|
771
|
-
post.reload_author
|
|
772
|
-
post.comments.reload
|
|
773
|
-
```
|
|
1151
|
+
* Fix single quote escapes on default generated MySQL columns.
|
|
774
1152
|
|
|
775
|
-
|
|
1153
|
+
MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
|
|
776
1154
|
|
|
777
|
-
|
|
778
|
-
With this change you can create indexes while adding new
|
|
779
|
-
columns into the existing tables.
|
|
1155
|
+
Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
|
|
780
1156
|
|
|
781
|
-
|
|
1157
|
+
This would result in issues when importing the schema on a fresh instance of a MySQL database.
|
|
782
1158
|
|
|
783
|
-
|
|
784
|
-
t.string :country_code, index: true
|
|
785
|
-
end
|
|
786
|
-
|
|
787
|
-
*Mehmet Emin İNAÇ*
|
|
1159
|
+
Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
|
|
788
1160
|
|
|
789
|
-
*
|
|
1161
|
+
*Yash Kapadia*
|
|
790
1162
|
|
|
791
|
-
|
|
792
|
-
|
|
1163
|
+
* Fix Migrations with versions older than 7.1 validating options given to
|
|
1164
|
+
`add_reference` and `t.references`.
|
|
793
1165
|
|
|
794
|
-
*
|
|
1166
|
+
*Hartley McGuire*
|
|
795
1167
|
|
|
796
|
-
*
|
|
1168
|
+
* Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
|
|
797
1169
|
|
|
798
|
-
*
|
|
1170
|
+
*JP Rosevear*
|
|
799
1171
|
|
|
800
|
-
*
|
|
1172
|
+
* Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
|
|
801
1173
|
|
|
802
|
-
|
|
1174
|
+
This wouldn't always work previously because boolean values would be interpreted as strings.
|
|
803
1175
|
|
|
804
|
-
|
|
1176
|
+
e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
|
|
1177
|
+
cache.
|
|
805
1178
|
|
|
806
|
-
|
|
1179
|
+
*Mike Coutermarsh*, *Jean Boussier*
|
|
807
1180
|
|
|
808
|
-
|
|
1181
|
+
* Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
|
|
809
1182
|
|
|
810
|
-
|
|
1183
|
+
It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
|
|
1184
|
+
but with support for `after_commit` and `after_rollback` callback options.
|
|
811
1185
|
|
|
812
|
-
*
|
|
1186
|
+
*Joshua Young*
|
|
813
1187
|
|
|
814
|
-
*
|
|
1188
|
+
* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
|
|
815
1189
|
|
|
816
|
-
|
|
817
|
-
create_table :users do |t|
|
|
818
|
-
t.string :email
|
|
819
|
-
end
|
|
1190
|
+
Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
|
|
820
1191
|
|
|
821
|
-
|
|
822
|
-
```
|
|
1192
|
+
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`.
|
|
823
1193
|
|
|
824
|
-
|
|
1194
|
+
The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
|
|
825
1195
|
|
|
826
|
-
*
|
|
1196
|
+
*Maxime Réty*
|
|
827
1197
|
|
|
828
|
-
|
|
1198
|
+
* Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
|
|
829
1199
|
|
|
830
|
-
*
|
|
1200
|
+
*Maxime Réty*
|
|
831
1201
|
|
|
832
|
-
*
|
|
1202
|
+
* The object returned by `explain` now responds to `pluck`, `first`,
|
|
1203
|
+
`last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
|
|
1204
|
+
new methods run `EXPLAIN` on the corresponding queries:
|
|
833
1205
|
|
|
834
|
-
|
|
1206
|
+
```ruby
|
|
1207
|
+
User.all.explain.count
|
|
1208
|
+
# EXPLAIN SELECT COUNT(*) FROM `users`
|
|
1209
|
+
# ...
|
|
835
1210
|
|
|
836
|
-
|
|
1211
|
+
User.all.explain.maximum(:id)
|
|
1212
|
+
# EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
|
|
1213
|
+
# ...
|
|
1214
|
+
```
|
|
837
1215
|
|
|
838
|
-
|
|
839
|
-
The previous default 3-Byte encoding character set `utf8` is not enough to support them.
|
|
1216
|
+
*Petrik de Heus*
|
|
840
1217
|
|
|
841
|
-
|
|
1218
|
+
* Fixes an issue where `validates_associated` `:on` option wasn't respected
|
|
1219
|
+
when validating associated records.
|
|
842
1220
|
|
|
843
|
-
*
|
|
1221
|
+
*Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
|
|
844
1222
|
|
|
845
|
-
|
|
1223
|
+
* Allow overriding SQLite defaults from `database.yml`.
|
|
846
1224
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
specify sensitive attributes to specific model.
|
|
1225
|
+
Any PRAGMA configuration set under the `pragmas` key in the configuration
|
|
1226
|
+
file takes precedence over Rails' defaults, and additional PRAGMAs can be
|
|
1227
|
+
set as well.
|
|
851
1228
|
|
|
852
|
-
```
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1229
|
+
```yaml
|
|
1230
|
+
database: storage/development.sqlite3
|
|
1231
|
+
timeout: 5000
|
|
1232
|
+
pragmas:
|
|
1233
|
+
journal_mode: off
|
|
1234
|
+
temp_store: memory
|
|
857
1235
|
```
|
|
858
1236
|
|
|
859
|
-
*
|
|
1237
|
+
*Stephen Margheim*
|
|
860
1238
|
|
|
861
|
-
*
|
|
862
|
-
`indexes_per_table`, `columns_per_multicolumn_index`, `sql_query_length`,
|
|
863
|
-
and `joins_per_query` methods in `DatabaseLimits`.
|
|
1239
|
+
* Remove warning message when running SQLite in production, but leave it unconfigured.
|
|
864
1240
|
|
|
865
|
-
|
|
1241
|
+
There are valid use cases for running SQLite in production. However, it must be done
|
|
1242
|
+
with care, so instead of a warning most users won't see anyway, it's preferable to
|
|
1243
|
+
leave the configuration commented out to force them to think about having the database
|
|
1244
|
+
on a persistent volume etc.
|
|
866
1245
|
|
|
867
|
-
*
|
|
1246
|
+
*Jacopo Beschi*, *Jean Boussier*
|
|
868
1247
|
|
|
869
|
-
|
|
870
|
-
is an inflexible data model. In order to improve multiple-database
|
|
871
|
-
handling in Rails, we've changed this to return an object. Some methods
|
|
872
|
-
are provided to make the object behave hash-like in order to ease the
|
|
873
|
-
transition process. Since most applications don't manipulate the hash
|
|
874
|
-
we've decided to add backwards-compatible functionality that will throw
|
|
875
|
-
a deprecation warning if used, however calling `ActiveRecord::Base.configurations`
|
|
876
|
-
will use the new version internally and externally.
|
|
1248
|
+
* Add support for generated columns to the SQLite3 adapter.
|
|
877
1249
|
|
|
878
|
-
|
|
1250
|
+
Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
|
|
1251
|
+
This adds support for those to the SQLite3 adapter.
|
|
879
1252
|
|
|
880
|
-
```
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1253
|
+
```ruby
|
|
1254
|
+
create_table :users do |t|
|
|
1255
|
+
t.string :name
|
|
1256
|
+
t.virtual :name_upper, type: :string, as: 'UPPER(name)'
|
|
1257
|
+
t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
|
|
1258
|
+
end
|
|
884
1259
|
```
|
|
885
1260
|
|
|
886
|
-
|
|
1261
|
+
*Stephen Margheim*
|
|
887
1262
|
|
|
888
|
-
|
|
889
|
-
{ "development" => { "adapter" => "sqlite3", "database" => "db/development.sqlite3" } }
|
|
890
|
-
```
|
|
1263
|
+
* TrilogyAdapter: ignore `host` if `socket` parameter is set.
|
|
891
1264
|
|
|
892
|
-
|
|
1265
|
+
This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
|
|
893
1266
|
|
|
894
1267
|
```
|
|
895
|
-
|
|
896
|
-
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
|
897
|
-
@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
|
|
898
|
-
]
|
|
1268
|
+
DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
|
|
899
1269
|
```
|
|
900
1270
|
|
|
901
|
-
|
|
902
|
-
calling hash methods on the `configurations` hash directly, a new method `configs_for` has
|
|
903
|
-
been provided that allows you to select the correct configuration. `env_name` and
|
|
904
|
-
`spec_name` arguments are optional. For example, these return an array of
|
|
905
|
-
database config objects for the requested environment and a single database config object
|
|
906
|
-
will be returned for the requested environment and specification name respectively.
|
|
1271
|
+
*Jean Boussier*
|
|
907
1272
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
|
|
911
|
-
```
|
|
1273
|
+
* Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
|
|
1274
|
+
`assert_no_queries_match` assertions public.
|
|
912
1275
|
|
|
913
|
-
|
|
1276
|
+
To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
|
|
1277
|
+
`assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
|
|
1278
|
+
`assert_no_queries_match` are used. These assertions can now be used in applications as well.
|
|
914
1279
|
|
|
915
|
-
|
|
1280
|
+
```ruby
|
|
1281
|
+
class ArticleTest < ActiveSupport::TestCase
|
|
1282
|
+
test "queries are made" do
|
|
1283
|
+
assert_queries_count(1) { Article.first }
|
|
1284
|
+
end
|
|
916
1285
|
|
|
1286
|
+
test "creates a foreign key" do
|
|
1287
|
+
assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
|
|
1288
|
+
@connection.add_foreign_key(:comments, :posts)
|
|
1289
|
+
end
|
|
1290
|
+
end
|
|
1291
|
+
end
|
|
917
1292
|
```
|
|
918
|
-
production:
|
|
919
|
-
adapter: postgresql
|
|
920
|
-
advisory_locks: false
|
|
921
|
-
```
|
|
922
|
-
|
|
923
|
-
*Guo Xiang*
|
|
924
1293
|
|
|
925
|
-
*
|
|
1294
|
+
*Petrik de Heus*, *fatkodima*
|
|
926
1295
|
|
|
927
|
-
|
|
1296
|
+
* Fix `has_secure_token` calls the setter method on initialize.
|
|
928
1297
|
|
|
929
|
-
*
|
|
1298
|
+
*Abeid Ahmed*
|
|
930
1299
|
|
|
931
|
-
|
|
1300
|
+
* When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
|
|
1301
|
+
adapter. This allows decoupling the adapter the application chooses to use from the database connection details
|
|
1302
|
+
set in the deployment environment.
|
|
932
1303
|
|
|
933
|
-
|
|
1304
|
+
```ruby
|
|
1305
|
+
# ENV['DATABASE_URL'] = "mysql://localhost/example_database"
|
|
1306
|
+
config.active_record.protocol_adapters.mysql = "trilogy"
|
|
1307
|
+
# will connect to MySQL using the trilogy adapter
|
|
1308
|
+
```
|
|
934
1309
|
|
|
935
|
-
*
|
|
1310
|
+
*Jean Boussier*, *Kevin McPhillips*
|
|
936
1311
|
|
|
937
|
-
*
|
|
938
|
-
|
|
1312
|
+
* In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
|
|
1313
|
+
the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
|
|
1314
|
+
called with a generic warning message rather than silently ignoring the warning(s).
|
|
939
1315
|
|
|
940
|
-
*
|
|
1316
|
+
*Kevin McPhillips*
|
|
941
1317
|
|
|
942
|
-
*
|
|
1318
|
+
* `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
|
|
943
1319
|
|
|
944
|
-
*
|
|
1320
|
+
*Andrew Novoselac*
|
|
945
1321
|
|
|
946
|
-
* Fix `
|
|
1322
|
+
* Fix `where(field: values)` queries when `field` is a serialized attribute
|
|
1323
|
+
(for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
|
|
1324
|
+
column).
|
|
947
1325
|
|
|
948
|
-
*
|
|
1326
|
+
*João Alves*
|
|
949
1327
|
|
|
950
|
-
*
|
|
1328
|
+
* Make the output of `ActiveRecord::Core#inspect` configurable.
|
|
951
1329
|
|
|
952
|
-
|
|
1330
|
+
By default, calling `inspect` on a record will yield a formatted string including just the `id`.
|
|
953
1331
|
|
|
954
|
-
|
|
1332
|
+
```ruby
|
|
1333
|
+
Post.first.inspect #=> "#<Post id: 1>"
|
|
1334
|
+
```
|
|
955
1335
|
|
|
956
|
-
|
|
1336
|
+
The attributes to be included in the output of `inspect` can be configured with
|
|
1337
|
+
`ActiveRecord::Core#attributes_for_inspect`.
|
|
957
1338
|
|
|
958
|
-
|
|
1339
|
+
```ruby
|
|
1340
|
+
Post.attributes_for_inspect = [:id, :title]
|
|
1341
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
|
|
1342
|
+
```
|
|
959
1343
|
|
|
960
|
-
|
|
1344
|
+
With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
|
|
961
1345
|
|
|
962
|
-
|
|
1346
|
+
```ruby
|
|
1347
|
+
Post.attributes_for_inspect = :all
|
|
1348
|
+
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
|
1349
|
+
```
|
|
963
1350
|
|
|
964
|
-
|
|
1351
|
+
In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
|
|
965
1352
|
|
|
966
|
-
|
|
1353
|
+
You can also call `full_inspect` to get an inspection with all the attributes.
|
|
967
1354
|
|
|
968
|
-
|
|
1355
|
+
The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
|
|
969
1356
|
|
|
970
|
-
*
|
|
971
|
-
use loaded association ids if present.
|
|
1357
|
+
*Andrew Novoselac*
|
|
972
1358
|
|
|
973
|
-
|
|
1359
|
+
* Don't mark attributes as changed when reassigned to `Float::INFINITY` or
|
|
1360
|
+
`-Float::INFINITY`.
|
|
974
1361
|
|
|
975
|
-
*
|
|
1362
|
+
*Maicol Bentancor*
|
|
976
1363
|
|
|
977
|
-
|
|
1364
|
+
* Support the `RETURNING` clause for MariaDB.
|
|
978
1365
|
|
|
979
|
-
*
|
|
1366
|
+
*fatkodima*, *Nikolay Kondratyev*
|
|
980
1367
|
|
|
981
|
-
|
|
1368
|
+
* The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
|
|
982
1369
|
|
|
983
|
-
|
|
1370
|
+
Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
|
|
984
1371
|
|
|
985
|
-
|
|
1372
|
+
```ruby
|
|
1373
|
+
add_reference :person, :alias, foreign_key: { deferrable: :deferred }
|
|
1374
|
+
add_reference :alias, :person, foreign_key: { deferrable: :deferred }
|
|
1375
|
+
```
|
|
986
1376
|
|
|
987
|
-
*
|
|
1377
|
+
*Stephen Margheim*
|
|
988
1378
|
|
|
989
|
-
|
|
1379
|
+
* Add the `set_constraints` helper to PostgreSQL connections.
|
|
990
1380
|
|
|
991
|
-
|
|
1381
|
+
```ruby
|
|
1382
|
+
Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
|
|
1383
|
+
|
|
1384
|
+
Post.transaction do
|
|
1385
|
+
Post.connection.set_constraints(:deferred)
|
|
1386
|
+
p = Post.create!(user_id: -1)
|
|
1387
|
+
u = User.create!
|
|
1388
|
+
p.user = u
|
|
1389
|
+
p.save!
|
|
1390
|
+
end
|
|
1391
|
+
```
|
|
992
1392
|
|
|
993
|
-
*
|
|
1393
|
+
*Cody Cutrer*
|
|
994
1394
|
|
|
995
|
-
*
|
|
1395
|
+
* Include `ActiveModel::API` in `ActiveRecord::Base`.
|
|
996
1396
|
|
|
997
|
-
*
|
|
1397
|
+
*Sean Doyle*
|
|
998
1398
|
|
|
999
|
-
*
|
|
1399
|
+
* Ensure `#signed_id` outputs `url_safe` strings.
|
|
1000
1400
|
|
|
1001
|
-
*
|
|
1401
|
+
*Jason Meller*
|
|
1002
1402
|
|
|
1003
|
-
* Add `
|
|
1004
|
-
`ActiveRecord::Base.find_or_create_by`/`!` by leaning on unique constraints in the database.
|
|
1403
|
+
* Add `nulls_last` and working `desc.nulls_first` for MySQL.
|
|
1005
1404
|
|
|
1006
|
-
*
|
|
1405
|
+
*Tristan Fellows*
|
|
1007
1406
|
|
|
1008
|
-
*
|
|
1407
|
+
* Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
|
|
1009
1408
|
|
|
1010
|
-
|
|
1409
|
+
```ruby
|
|
1410
|
+
Topic.includes(:posts).order(posts: { created_at: :desc })
|
|
1411
|
+
```
|
|
1011
1412
|
|
|
1413
|
+
*Myles Boone*
|
|
1012
1414
|
|
|
1013
|
-
Please check [
|
|
1415
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.
|