Rails 7.2.3 (October 28, 2025)
- Fix SQLite3 data loss during table alterations with CASCADE foreign keys. - When altering a table in SQLite3 that is referenced by child tables with - ON DELETE CASCADEforeign keys, ActiveRecord would silently delete all data from the child tables. This occurred because SQLite requires table recreation for schema changes, and during this process the original table is temporarily dropped, triggering CASCADE deletes on child tables.- The root cause was incorrect ordering of operations. The original code wrapped - disable_referential_integrityinside a transaction, but- PRAGMA foreign_keyscannot be modified inside a transaction in SQLite - attempting to do so simply has no effect. This meant foreign keys remained enabled during table recreation, causing CASCADE deletes to fire.- The fix reverses the order to follow the official SQLite 12-step ALTER TABLE procedure: - disable_referential_integritynow wraps the transaction instead of being wrapped by it. This ensures foreign keys are properly disabled before the transaction starts and re-enabled after it commits, preventing CASCADE deletes while maintaining data integrity through atomic transactions.- Ruy Rocha 
- Fix - belongs_toassociations not to clear the entire composite primary key.- When clearing a - belongs_toassociation that references a model with composite primary key, only the optional part of the key should be cleared.- zzak 
- Fix invalid records being autosaved when distantly associated records are marked for deletion. - Ian Terrell, axlekb AB 
- Prevent persisting invalid record. - Edouard Chin 
- Fix count with group by qualified name on loaded relation. - Ryuta Kamizono 
- Fix - sumwith qualified name on loaded relation.- Chris Gunther 
- Fix prepared statements on mysql2 adapter. - Jean Boussier 
- Fix query cache for pinned connections in multi threaded transactional tests. - When a pinned connection is used across separate threads, they now use a separate cache store for each thread. - This improve accuracy of system tests, and any test using multiple threads. - Heinrich Lee Yu, Jean Boussier 
- Don't add - id_valueattribute alias when attribute/column with that name already exists.- Rob Lewis 
- Fix false positive change detection involving STI and polymorhic has one relationships. - Polymorphic - has_onerelationships would always be considered changed when defined in a STI child class, causing nedless extra autosaves.- David Fritsch 
- Fix stale associaton detection for polymophic - belong_to.- Florent Beaurain, Thomas Crambert 
- Fix removal of PostgreSQL version comments in - structure.sqlfor latest PostgreSQL versions which include- \restrict.- Brendan Weibrecht 
- Fix - #mergewith- #oror- #andand a mixture of attributes and SQL strings resulting in an incorrect query.- base = Comment.joins(:post).where(user_id: 1).where("recent = 1") puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql- Before: - SELECT "comments".* FROM "comments" INNER JOIN "posts" ON "posts"."id" = "comments"."post_id" WHERE (recent = 1) AND ( "comments"."user_id" = 1 AND (recent = 1) AND "comments"."draft" = 1 OR "posts"."archived" = 1 )- After: - SELECT "comments".* FROM "comments" INNER JOIN "posts" ON "posts"."id" = "comments"."post_id" WHERE "comments"."user_id" = 1 AND (recent = 1) AND ( "comments"."user_id" = 1 AND (recent = 1) AND "comments"."draft" = 1 OR "posts"."archived" = 1 )- Joshua Young 
- Fix inline - has_and_belongs_to_manyfixtures for tables with composite primary keys.- fatkodima 
- Fix - annotatecomments to propagate to- update_all/- delete_all.- fatkodima 
- Fix checking whether an unpersisted record is - include?d in a strictly loaded- has_and_belongs_to_manyassociation.- Hartley McGuire 
- Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys. - fatkodima 
- create_or_find_bywill now correctly rollback a transaction.- When using - create_or_find_by, raising a ActiveRecord::Rollback error in a- after_savecallback had no effect, the transaction was committed and a record created.- Edouard Chin 
- Gracefully handle - Timeout.timeoutfiring during connection configuration.- Use of - Timeout.timeoutcould result in improperly initialized database connection.- This could lead to a partially configured connection being used, resulting in various exceptions, the most common being with the PostgreSQLAdapter raising - undefined method 'key?' for nilor- TypeError: wrong argument type nil (expected PG::TypeMap).- Jean Boussier 
- The SQLite3 adapter quotes non-finite - Numericvalues like "Infinity" and "NaN".- Mike Dalessio 
- Handle libpq returning a database version of 0 on no/bad connection in - PostgreSQLAdapter.- Before, this version would be cached and an error would be raised during connection configuration when comparing it with the minimum required version for the adapter. This meant that the connection could never be successfully configured on subsequent reconnection attempts. - Now, this is treated as a connection failure consistent with libpq, raising a - ::ActiveRecord::ConnectionFailedand ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.- Joshua Young, Rian McGuire 
- Fix error handling during connection configuration. - Active Record wasn't properly handling errors during the connection configuration phase. This could lead to a partially configured connection being used, resulting in various exceptions, the most common being with the PostgreSQLAdapter raising - undefined methodkey?' for nil- orTypeError: wrong argument type nil (expected PG::TypeMap)`.- Jean Boussier 
- Fix a case where a non-retryable query could be marked retryable. - Hartley McGuire 
- Handle circular references when autosaving associations. - zzak 
- Prevent persisting invalid record. - Edouard Chin 
- Fix support for PostgreSQL enum types with commas in their name. - Arthur Hess 
- Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns. - Nikita Vasilevsky 
- Fix joining on a scoped association with string joins and bind parameters. - class Instructor < ActiveRecord::Base has_many :instructor_roles, -> { active } end class InstructorRole < ActiveRecord::Base scope :active, -> { joins("JOIN students ON instructor_roles.student_id = students.id") .where(students { status: 1 }) } end Instructor.joins(:instructor_roles).first- The above example would result in - ::ActiveRecord::StatementInvalidbecause the- activescope bind parameters would be lost.- Jean Boussier 
- Fix a potential race condition with system tests and transactional fixtures. - Sjoerd Lagarde 
- Fix count with group by qualified name on loaded relation. - Ryuta Kamizono 
- Fix sum with qualified name on loaded relation. - Chris Gunther 
- Fix autosave associations to no longer validated unmodified associated records. - Active Record was incorrectly performing validation on associated record that weren't created nor modified as part of the transaction: - Post.create!(author: User.find(1)) # Fail if user is invalid- Jean Boussier 
- Remember when a database connection has recently been verified (for two seconds, by default), to avoid repeated reverifications during a single request. - This should recreate a similar rate of verification as in Rails 7.1, where connections are leased for the duration of a request, and thus only verified once. - Matthew Draper 
- Fix prepared statements on mysql2 adapter. - Jean Boussier 
- Fix a race condition in - ActiveRecord::Base#method_missingwhen lazily defining attributes.- If multiple thread were concurrently triggering attribute definition on the same model, it could result in a - NoMethodErrorbeing raised.- Jean Boussier 
- Fix MySQL default functions getting dropped when changing a column's nullability. - Bastian Bartmann 
- Fix - add_unique_constraint/- add_check_constraint/- /add_foreign_key` to be revertible when given invalid options.- fatkodima 
- Fix asynchronous destroying of polymorphic - belongs_toassociations.- fatkodima 
- NOT VALID constraints should not dump in - create_table.- Ryuta Kamizono 
- Fix finding by nil composite primary key association. - fatkodima 
- Fix parsing of SQLite foreign key names when they contain non-ASCII characters - Zacharias Knudsen 
- Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines. - Steve Hill 
- Ensure normalized attribute queries use - IS NULLconsistently for- niland normalized- nilvalues.- Joshua Young 
- Restore back the ability to pass only database name for - DATABASE_URL.- fatkodima 
- Fix - orderwith using association name as an alias.- Ryuta Kamizono 
- Improve invalid argument error for with. - Ryuta Kamizono 
- Deduplicate - withCTE expressions.- fatkodima 
Rails 7.2.2.2 (August 13, 2025)
- Call inspect on ids in RecordNotFound error - [CVE-2025-55193] - Gannon McGibbon, John Hawthorn 
Rails 7.2.2.1 (December 10, 2024)
- No changes.
Rails 7.2.2 (October 30, 2024)
- Fix support for - query_cache: falsein- database.yml.- query_cache: falsewould no longer entirely disable the Active Record query cache.- zzak 
- Set - .attributes_for_inspectto- :allby default.- For new applications it is set to - [:id]in config/environment/production.rb.- In the console all the attributes are always shown. - Andrew Novoselac 
- PG::UnableToSend: no connection to the serveris now retryable as a connection-related exception- Kazuma Watanabe 
- Fix marshalling of unsaved associated records in 7.1 format. - The 7.1 format would only marshal associated records if the association was loaded. But associations that would only contain unsaved records would be skipped. - Jean Boussier 
- Fix incorrect SQL query when passing an empty hash to - ActiveRecord::Base.insert.- David Stosik 
- Allow to save records with polymorphic join tables that have - inverse_ofspecified.- Markus Doits 
- Fix association scopes applying on the incorrect join when using a polymorphic - has_many through:.- Joshua Young 
- Fix - dependent: :destroyfor bi-directional has one through association.- Fixes #50948. - class Left < ActiveRecord::Base has_one :middle, dependent: :destroy has_one :right, through: :middle end class Middle < ActiveRecord::Base belongs_to :left, dependent: :destroy belongs_to :right, dependent: :destroy end class Right < ActiveRecord::Base has_one :middle, dependent: :destroy has_one :left, through: :middle end- In the above example - left.destroywouldn't destroy its associated- Rightrecord.- Andy Stewart 
- Properly handle lazily pinned connection pools. - Fixes #53147. - When using transactional fixtures with system tests to similar tools such as capybara, it could happen that a connection end up pinned by the server thread rather than the test thread, causing - "Cannot expire connection, it is owned by a different thread"errors.- Jean Boussier 
- Fix - ActiveRecord::Base.withto accept more than two sub queries.- Fixes #53110. - User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)- The above now works as expected. - fatkodima 
- Properly release pinned connections with non joinable connections. - Fixes #52973 - When running system tests with transactional fixtures on, it could happen that the connection leased by the Puma thread wouldn't be properly released back to the pool, causing "Cannot expire connection, it is owned by a different thread" errors in later tests. - Jean Boussier 
- Make Float distinguish between - float4and- float8in PostgreSQL.- Fixes #52742 - Ryota Kitazawa, Takayuki Nagatomi 
- Fix an issue where - .left_outer_joinsused with multiple associations that have the same child association but different parents does not join all parents.- Previously, using - .left_outer_joinswith the same child association would only join one of the parents.- Now it will correctly join both parents. - Fixes #41498. - Garrett Blehm 
- Ensure ActiveRecord::Encryption.config is always ready before access. - Previously, - ::ActiveRecord::Encryptionconfiguration was deferred until- ::ActiveRecord::Basewas loaded. Therefore, accessing ActiveRecord::Encryption.config properties before- ::ActiveRecord::Basewas loaded would give incorrect results.- ::ActiveRecord::Encryptionnow has its own loading hook so that its configuration is set as soon as needed.- When - ::ActiveRecord::Baseis loaded, even lazily, it in turn triggers the loading of- ::ActiveRecord::Encryption, thus preserving the original behavior of having its config ready before any use of- ::ActiveRecord::Base.- Maxime Réty 
- Add - TimeZoneConverter#==method, so objects will be properly compared by their type, scale, limit & precision.- Address #52699. - Ruy Rocha 
Rails 7.2.1.2 (October 23, 2024)
- No changes.
Rails 7.2.1.1 (October 15, 2024)
- No changes.
Rails 7.2.1 (August 22, 2024)
- Fix detection for - enumcolumns with parallelized tests and PostgreSQL.- Rafael Mendonça França 
- Allow to eager load nested nil associations. - fatkodima 
- Fix swallowing ignore order warning when batching using - BatchEnumerator.- fatkodima 
- Fix memory bloat on the connection pool when using the Fiber - IsolatedExecutionState.- Jean Boussier 
- Restore inferred association class with the same modularized name. - Justin Ko 
- Fix - ActiveRecord::Base.inspectto properly explain how to load schema information.- Jean Boussier 
- Check invalid - enumoptions for the new syntax.- The options using - _prefix in the old syntax are invalid in the new syntax.- Rafael Mendonça França 
- Fix ActiveRecord::Encryption::EncryptedAttributeType#type to return actual cast type. - Vasiliy Ermolovich 
- Fix - create_tablewith- :auto_incrementoption for MySQL adapter.- fatkodima 
Rails 7.2.0 (August 09, 2024)
- Handle commas in Sqlite3 default function definitions. - Stephen Margheim 
- Fixes - validates_associatedraising an exception when configured with a singular association and having- index_nested_attribute_errorsenabled.- Martin Spickermann 
- The constant - ActiveRecord::ImmutableRelationhas been deprecated because we want to reserve that name for a stronger sense of "immutable relation". Please use- ::ActiveRecord::UnmodifiableRelationinstead.- Xavier Noria 
- Add condensed - #inspectfor- ConnectionPool,- AbstractAdapter, and- DatabaseConfig.- Hartley McGuire 
- Fixed a memory performance issue in Active Record attribute methods definition. - Jean Boussier 
- Define the new Active Support notification event - start_transaction.active_record.- This event is fired when database transactions or savepoints start, and complements - transaction.active_record, which is emitted when they finish.- The payload has the transaction ( - :transaction) and the connection (- :connection).- Xavier Noria 
- Fix an issue where the IDs reader method did not return expected results for preloaded associations in models using composite primary keys. - Jay Ang 
- The payload of - sql.active_recordActive Support notifications now has the current transaction in the- :transactionkey.- Xavier Noria 
- The payload of - transaction.active_recordActive Support notifications now has the transaction the event is related to in the- :transactionkey.- Xavier Noria 
- 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. - Xavier Noria 
- Fix inference of association model on nested models with the same demodularized name. - E.g. with the following setup: - class Nested::Post < ApplicationRecord has_one :post, through: :other end- Before, - #postwould infer the model as- Nested::Post, but now it correctly infers- Post.- Joshua Young 
- PostgreSQL - Cidr#change?detects the address prefix change.- Taketo Takashima 
- Change - BatchEnumerator#destroy_allto return the total number of affected rows.- Previously, it always returned - nil.- fatkodima 
- Support - touch_allin batches.- Post.in_batches.touch_all- fatkodima 
- Add support for - :if_not_existsand- :forceoptions to- create_schema.- fatkodima 
- Fix - index_errorshaving incorrect index in association validation errors.- lulalala 
- Add - index_errors: :nested_attributes_ordermode.- This indexes the association validation errors based on the order received by nested attributes setter, and respects the - reject_ifconfiguration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.- lulalala 
- Add - Rails.application.config.active_record.postgresql_adapter_decode_datesto opt out of decoding dates automatically with the postgresql adapter. Defaults to true.- Joé Dupuis 
- Association option - query_constraintsis deprecated in favor of- foreign_key.- Nikita Vasilevsky 
- Add - ENV["SKIP_TEST_DATABASE_TRUNCATE"]flag to speed up multi-process test runs on large DBs when all tests run within default transaction.- 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. - DHH 
- Added support for recursive common table expressions. - Post.with_recursive( post_and_replies: [ Post.where(id: 42), Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'), ] )- Generates the following SQL: - WITH RECURSIVE "post_and_replies" AS ( (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42) UNION ALL (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id) ) SELECT "posts".* FROM "posts"- ClearlyClaire 
- validate_constraintcan be called in a- change_tableblock.- ex: - change_table :products do |t| t.check_constraint "price > discounted_price", name: "price_check", validate: false t.validate_check_constraint "price_check" end- Cody Cutrer 
- PostgreSQLAdapternow decodes columns of type date to- Dateinstead of string.- Ex: - ActiveRecord::Base.connection .select_value("select '2024-01-01'::date").class #=> Date- Joé Dupuis 
- Strict loading using - :n_plus_one_onlydoes not eagerly load child associations.- With this change, child associations are no longer eagerly loaded, to match intended behavior and to prevent non-deterministic order issues caused by calling methods like - firstor- last. As- firstand- lastdon't cause an N+1 by themselves, calling child associations will no longer raise. Fixes #49473.- Before: - person = Person.find(1) person.strict_loading!(mode: :n_plus_one_only) person.posts.first # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError- After: - person = Person.find(1) person.strict_loading!(mode: :n_plus_one_only) person.posts.first # this is 1+1, not N+1 # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1; person.posts.first.firm # no longer raises- Reid Lynch 
- Allow - Sqlite3Adapterto use- sqlite3gem version- 2.x.- Mike Dalessio 
- Allow - ActiveRecord::Base#pluckto accept hash values.- # Before Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body") # After Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])- fatkodima 
- Raise an - ::ActiveRecord::ActiveRecordErrorerror when the MySQL database returns an invalid version string.- Kevin McPhillips 
- ActiveRecord::Base.transactionnow yields an- ::ActiveRecord::Transactionobject.- This allows to register callbacks on it. - Article.transaction do |transaction| article.update(published: true) transaction.after_commit do PublishNotificationMailer.with(article: article).deliver_later end end- Jean Boussier 
- Add - ActiveRecord::Base.current_transaction.- Returns the current transaction, to allow registering callbacks on it. - Article.current_transaction.after_commit do PublishNotificationMailer.with(article: article).deliver_later end- Jean Boussier 
- Add ActiveRecord.after_all_transactions_commit callback. - Useful for code that may run either inside or outside a transaction and needs to perform work after the state changes have been properly persisted. - def publish_article(article) article.update(published: true) ActiveRecord.after_all_transactions_commit do PublishNotificationMailer.with(article: article).deliver_later end end- In the above example, the block is either executed immediately if called outside of a transaction, or called after the open transaction is committed. - If the transaction is rolled back, the block isn't called. - Jean Boussier 
- Add the ability to ignore counter cache columns until they are backfilled. - Starting to use counter caches on existing large tables can be troublesome, because the column values must be backfilled separately of the column addition (to not lock the table for too long) and before the use of - :counter_cache(otherwise methods like- size/- any?/etc, which use counter caches internally, can produce incorrect results). People usually use database triggers or callbacks on child associations while backfilling before introducing a counter cache configuration to the association.- Now, to safely backfill the column, while keeping the column updated with child records added/removed, use: - class Comment < ApplicationRecord belongs_to :post, counter_cache: { active: false } end- While the counter cache is not "active", the methods like - size/- any?/etc will not use it, but get the results directly from the database. After the counter cache column is backfilled, simply remove the- { active: false }part from the counter cache definition, and it will now be used by the mentioned methods.- fatkodima 
- Retry known idempotent SELECT queries on connection-related exceptions. - SELECT queries we construct by walking the Arel tree and / or with known model attributes are idempotent and can safely be retried in the case of a connection error. Previously, adapters such as - TrilogyAdapterwould raise- ActiveRecord::ConnectionFailed: Trilogy::EOFErrorwhen encountering a connection error mid-request.- Adrianna Chang 
- Allow association's - foreign_keyto be composite.- query_constraintsoption was the only way to configure a composite foreign key by passing an- Array. Now it's possible to pass an Array value as- foreign_keyto achieve the same behavior of an association.- Nikita Vasilevsky 
- Allow association's - primary_keyto be composite.- Association's - primary_keycan be composite when derived from associated model- primary_keyor- query_constraints. Now it's possible to explicitly set it as composite on the association.- Nikita Vasilevsky 
- Add - config.active_record.permanent_connection_checkoutsetting.- Controls whether - ActiveRecord::Base.connectionraises an error, emits a deprecation warning, or neither.- ActiveRecord::Base.connectioncheckouts a database connection from the pool and keeps it leased until the end of the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there is available connections.- This configuration can be used to track down and eliminate code that calls - ActiveRecord::Base.connectionand migrate it to use- ActiveRecord::Base.with_connectioninstead.- The default behavior remains unchanged, and there is currently no plans to change the default. - Jean Boussier 
- Add dirties option to uncached. - This adds a - dirtiesoption to- ActiveRecord::Base.uncachedand- ActiveRecord::ConnectionAdapters::ConnectionPool#uncached.- When set to - true(the default), writes will clear all query caches belonging to the current thread. When set to- false, writes to the affected connection pool will not clear any query cache.- This is needed by Solid Cache so that cache writes do not clear query caches. - Donal McBreen 
- Deprecate - ActiveRecord::Base.connectionin favor of- .lease_connection.- The method has been renamed as - lease_connectionto better reflect that the returned connection will be held for the duration of the request or job.- This deprecation is a soft deprecation, no warnings will be issued and there is no current plan to remove the method. - Jean Boussier 
- Deprecate ActiveRecord::ConnectionAdapters::ConnectionPool#connection. - The method has been renamed as - lease_connectionto better reflect that the returned connection will be held for the duration of the request or job.- Jean Boussier 
- Expose a generic fixture accessor for fixture names that may conflict with - Minitest.- assert_equal "Ruby on Rails", web_sites(:rubyonrails).name assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name- Jean Boussier 
- Using - Model.query_constraintswith a single non-primary-key column used to raise as expected, but with an incorrect error message.- This has been fixed to raise with a more appropriate error message. - Joshua Young 
- Fix - has_oneassociation autosave setting the foreign key attribute when it is unchanged.- This behavior is also inconsistent with autosaving - belongs_toand can have unintended side effects like raising an- ::ActiveRecord::ReadonlyAttributeErrorwhen the foreign key attribute is marked as read-only.- Joshua Young 
- Remove deprecated behavior that would rollback a transaction block when exited using - return,- breakor- throw.- Rafael Mendonça França 
- Deprecate - Rails.application.config.active_record.commit_transaction_on_non_local_return.- Rafael Mendonça França 
- Remove deprecated support to pass - rewhereto- ActiveRecord::Relation#merge.- Rafael Mendonça França 
- Remove deprecated support to pass - deferrable: trueto- add_foreign_key.- Rafael Mendonça França 
- Remove deprecated support to quote - ::ActiveSupport::Duration.- Rafael Mendonça França 
- Remove deprecated - #quote_bound_value.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass.- Rafael Mendonça França 
- Remove deprecated support to apply - #connection_pool_list,- #active_connections?,- #clear_active_connections!,- #clear_reloadable_connections!,- #clear_all_connections!and- #flush_idle_connections!to the connections pools for the current role when the- roleargument isn't provided.- Rafael Mendonça França 
- Remove deprecated - #all_connection_pools.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::ConnectionAdapters::SchemaCache#data_sources.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::ConnectionAdapters::SchemaCache.load_from.- Rafael Mendonça França 
- Remove deprecated - #all_foreign_keys_valid?from database adapters.- Rafael Mendonça França 
- Remove deprecated support to passing coder and class as second argument to - serialize.- Rafael Mendonça França 
- Remove deprecated support to - ActiveRecord::Base#read_attribute(:id)to return the custom primary key value.- Rafael Mendonça França 
- Remove deprecated - TestFixtures.fixture_path.- Rafael Mendonça França 
- Remove deprecated behavior to support referring to a singular association by its plural name. - Rafael Mendonça França 
- Deprecate - Rails.application.config.active_record.allow_deprecated_singular_associations_name.- Rafael Mendonça França 
- Remove deprecated support to passing - SchemaMigrationand- InternalMetadataclasses as arguments to- ::ActiveRecord::MigrationContext.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::Migration.check_pending!method.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::LogSubscriber.runtimemethod.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::LogSubscriber.runtime=method.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::LogSubscriber.reset_runtimemethod.- Rafael Mendonça França 
- Remove deprecated support to define - explainin the connection adapter with 2 arguments.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::ActiveJobRequiredError.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::Base.clear_active_connections!.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::Base.clear_reloadable_connections!.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::Base.clear_all_connections!.- Rafael Mendonça França 
- Remove deprecated - ActiveRecord::Base.flush_idle_connections!.- Rafael Mendonça França 
- Remove deprecated - nameargument from- ActiveRecord::Base.remove_connection.- Rafael Mendonça França 
- Remove deprecated support to call - alias_attributewith non-existent attribute names.- Rafael Mendonça França 
- Remove deprecated - Rails.application.config.active_record.suppress_multiple_database_warning.- Rafael Mendonça França 
- Add - ::ActiveRecord::Encryption::MessagePackMessageSerializer.- Serialize data to the MessagePack format, for efficient storage in binary columns. - The binary encoding requires around 30% less space than the base64 encoding used by the default serializer. - Donal McBreen 
- Add support for encrypting binary columns. - Ensure encryption and decryption pass - Type::Binary::Dataaround for binary data.- Previously encrypting binary columns with the - ::ActiveRecord::Encryption::MessageSerializerincidentally worked for MySQL and SQLite, but not PostgreSQL.- Donal McBreen 
- Deprecated - ENV["SCHEMA_CACHE"]in favor of- schema_cache_pathin the database configuration.- Rafael Mendonça França 
- Add - ActiveRecord::Base.with_connectionas a shortcut for leasing a connection for a short duration.- The leased connection is yielded, and for the duration of the block, any call to - ActiveRecord::Base.connectionwill yield that same connection.- This is useful to perform a few database operations without causing a connection to be leased for the entire duration of the request or job. - Jean Boussier 
- Deprecate - config.active_record.warn_on_records_fetched_greater_thannow that- sql.active_recordnotification includes- :row_countfield.- Jason Nochlin 
- Fix an issue with - where.associatedlosing the current join type scope.- Example: - Post.left_joins(:).where.associated(:)- Previously, the - LEFT OUTER JOINwould be lost and converted to an- INNER JOIN.- Saleh Alhaddad 
- Fix an issue where - ::ActiveRecord::Encryptionconfigurations are not ready before the loading of Active Record models, when an application is eager loaded. As a result, encrypted attributes could be misconfigured in some cases.- Maxime Réty 
- Deprecate defining an - enumwith keyword arguments.- class Function > ApplicationRecord # BAD enum color: [:red, :blue], type: [:instance, :class] # GOOD enum :color, [:red, :blue] enum :type, [:instance, :class] end- Hartley McGuire 
- Add - config.active_record.validate_migration_timestampsoption for validating migration timestamps.- When set, validates that the timestamp prefix for a migration is no more than a day ahead of the timestamp associated with the current time. This is designed to prevent migrations prefixes from being hand-edited to future timestamps, which impacts migration generation and other migration commands. - Adrianna Chang 
- Properly synchronize - Mysql2Adapter#active?and- TrilogyAdapter#active?.- As well as - disconnect!and- verify!.- This generally isn't a big problem as connections must not be shared between threads, but is required when running transactional tests or system tests and could lead to a SEGV. - Jean Boussier 
- Support - :source_locationtag option for query log tags.- config.active_record. << :source_location- Calculating the caller location is a costly operation and should be used primarily in development (note, there is also a - config.active_record.verbose_query_logsthat serves the same purpose) or occasionally on production for debugging purposes.- fatkodima 
- Add an option to - ::ActiveRecord::Encryption::Encryptorto disable compression.- Allow compression to be disabled by setting - compress: false- class User encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false) end- Donal McBreen 
- Deprecate passing strings to ActiveRecord::Tasks::DatabaseTasks#cache_dump_filename. - A - ::ActiveRecord::DatabaseConfigurations::DatabaseConfigobject should be passed instead.- Rafael Mendonça França 
- Add - row_countfield to- sql.active_recordnotification.- This field returns the amount of rows returned by the query that emitted the notification. - This metric is useful in cases where one wants to detect queries with big result sets. - Marvin Bitterlich 
- Consistently raise an - ArgumentErrorwhen passing an invalid argument to a nested attributes association writer.- Previously, this would only raise on collection associations and produce a generic error on singular associations. - Now, it will raise on both collection and singular associations. - Joshua Young 
- Fix single quote escapes on default generated MySQL columns. - MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression. - Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression. - This would result in issues when importing the schema on a fresh instance of a MySQL database. - Now, the string will not be escaped and will be valid Ruby upon importing of the schema. - Yash Kapadia 
- Fix Migrations with versions older than 7.1 validating options given to - add_referenceand- t.references.- Hartley McGuire 
- Add - <role>_typesclass method to- ::ActiveRecord::DelegatedTypeso that the delegated types can be introspected.- JP Rosevear 
- Make - schema_dump,- query_cache,- replicaand- database_tasksconfigurable via- DATABASE_URL.- This wouldn't always work previously because boolean values would be interpreted as strings. - e.g. DATABASE_URL=postgres://localhost/foo?schema_dump=false now properly disable dumping the schema cache. - Mike Coutermarsh, Jean Boussier 
- Introduce ActiveRecord::Transactions::ClassMethods#set_callback. - It is identical to ActiveSupport::Callbacks::ClassMethods#set_callback but with support for - after_commitand- after_rollbackcallback options.- Joshua Young 
- Make - ::ActiveRecord::Encryption::Encryptoragnostic of the serialization format used for encrypted data.- Previously, the encryptor instance only allowed an encrypted value serialized as a - Stringto be passed to the message serializer.- Now, the encryptor lets the configured - message_serializerdecide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize- ::ActiveRecord::Encryption::Messageobjects using a type other than- String.- The default - ::ActiveRecord::Encryption::MessageSerializeralready ensures that only- Stringobjects are passed for deserialization.- Maxime Réty 
- Fix - encrypted_attribute?to take into account context properties passed to- encrypts.- Maxime Réty 
- The object returned by - explainnow responds to- pluck,- first,- last,- average,- count,- maximum,- minimum, and- sum. Those new methods run- EXPLAINon the corresponding queries:- User.all.explain.count # EXPLAIN SELECT COUNT(*) FROM `users` # ... User.all.explain.maximum(:id) # EXPLAIN SELECT MAX(`users`.`id`) FROM `users` # ...- Petrik de Heus 
- Fixes an issue where - validates_associated- :onoption wasn't respected when validating associated records.- Austen Madden, Alex Ghiculescu, Rafał Brize 
- Allow overriding SQLite defaults from - database.yml.- Any PRAGMA configuration set under the - pragmaskey in the configuration file takes precedence over Rails' defaults, and additional PRAGMAs can be set as well.- database: storage/development.sqlite3 timeout: 5000 pragmas: journal_mode: off temp_store: memory- Stephen Margheim 
- Remove warning message when running SQLite in production, but leave it unconfigured. - There are valid use cases for running SQLite in production. However, it must be done with care, so instead of a warning most users won't see anyway, it's preferable to leave the configuration commented out to force them to think about having the database on a persistent volume etc. - Jacopo Beschi, Jean Boussier 
- Add support for generated columns to the SQLite3 adapter. - Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite. This adds support for those to the SQLite3 adapter. - create_table :users do |t| t.string :name t.virtual :name_upper, type: :string, as: 'UPPER(name)' t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true end- Stephen Margheim 
- TrilogyAdapter: ignore - hostif- socketparameter is set.- This allows to configure a connection on a UNIX socket via - DATABASE_URL:- DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock- Jean Boussier 
- Make - assert_queries_count,- assert_no_queries,- assert_queries_match, and- assert_no_queries_matchassertions public.- To assert the expected number of queries are made, Rails internally uses - assert_queries_countand- assert_no_queries. To assert that specific SQL queries are made,- assert_queries_matchand- assert_no_queries_matchare used. These assertions can now be used in applications as well.- class ArticleTest < ActiveSupport::TestCase test "queries are made" do assert_queries_count(1) { Article.first } end test "creates a foreign key" do assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do @connection.add_foreign_key(:comments, :posts) end end end- Petrik de Heus, fatkodima 
- Fix - has_secure_tokencalls the setter method on initialize.- Abeid Ahmed 
- When using a - DATABASE_URL, allow for a configuration to map the protocol in the URL to a specific database adapter. This allows decoupling the adapter the application chooses to use from the database connection details set in the deployment environment.- # ENV['DATABASE_URL'] = "mysql://localhost/example_database" config.active_record.protocol_adapters.mysql = "trilogy" # will connect to MySQL using the trilogy adapter- Jean Boussier, Kevin McPhillips 
- In cases where MySQL returns - warning_countgreater than zero, but returns no warnings when the- SHOW WARNINGSquery is executed, ActiveRecord.db_warnings_action proc will still be called with a generic warning message rather than silently ignoring the warning(s).- Kevin McPhillips 
- DatabaseConfigurations#configs_foraccepts a symbol in the- nameparameter.- Andrew Novoselac 
- Fix - where(field: values)queries when- fieldis a serialized attribute (for example, when- fielduses- ActiveRecord::Base.serializeor is a JSON column).- João Alves 
- Make the output of ActiveRecord::Core#inspect configurable. - By default, calling - inspecton a record will yield a formatted string including just the- id.- Post.first.inspect #=> "#<Post id: 1>"- The attributes to be included in the output of - inspectcan be configured with ActiveRecord::Core#attributes_for_inspect.- Post.attributes_for_inspect = [:id, :title] Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"- With - attributes_for_inspectset to- :all,- inspectwill list all the record's attributes.- Post.attributes_for_inspect = :all Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"- In - developmentand- testmode,- attributes_for_inspectwill be set to- :allby default.- You can also call - full_inspectto get an inspection with all the attributes.- The attributes in - attribute_for_inspectwill also be used for- pretty_print.- Andrew Novoselac 
- Don't mark attributes as changed when reassigned to - Float::INFINITYor- -Float::INFINITY.- Maicol Bentancor 
- Support the - RETURNINGclause for MariaDB.- fatkodima, Nikolay Kondratyev 
- The SQLite3 adapter now implements the - supports_deferrable_constraints?contract.- Allows foreign keys to be deferred by adding the - :deferrablekey to the- foreign_keyoptions.- add_reference :person, :alias, foreign_key: { deferrable: :deferred } add_reference :alias, :person, foreign_key: { deferrable: :deferred }- Stephen Margheim 
- Add the - set_constraintshelper to PostgreSQL connections.- Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey Post.transaction do Post.connection.set_constraints(:deferred) p = Post.create!(user_id: -1) u = User.create! p.user = u p.save! end- Cody Cutrer 
- Include - ::ActiveModel::APIin- ::ActiveRecord::Base.- Sean Doyle 
- Ensure - #signed_idoutputs- url_safestrings.- Jason Meller 
- Add - nulls_lastand working- desc.nulls_firstfor MySQL.- Tristan Fellows 
- Allow for more complex hash arguments for - orderwhich mimics- wherein- ::ActiveRecord::Relation.- Topic.includes(:posts).order(posts: { created_at: :desc })- Myles Boone 
Please check [7-1-stable]) for previous changes.