You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix JSONGemCoderEncoder to correctly serialize custom object hash keys.
When hash keys are custom objects whose as_json returns a Hash,
the encoder now calls to_s on the original key object instead of
on the as_json result.
Silence Dalli 4.0+ warning when using ActiveSupport::Cache::MemCacheStore.
zzak
Active Model
Fix Ruby 4.0 delegator warning when calling inspect on attributes.
Hammad Khan
Fix NoMethodError when deserialising Type::Integer objects marshalled under Rails 8.0.
The performance optimisation that replaced @range with @max/@min
broke Marshal compatibility. Objects serialised under 8.0 (with @range)
and deserialised under 8.1 (expecting @max/@min) would crash with undefined method '<=' for nil because Marshal.load restores instance
variables without calling initialize.
Edward Woodcock
Active Record
Fix insert_all and upsert_all log message when called on anonymous classes.
Gabriel Sobrinho
Respect ActiveRecord::SchemaDumper.ignore_tables when dumping SQLite virtual tables.
Hans Schnedlitz
Restore previous instrumenter after execute_or_skip
FutureResult#execute_or_skip replaces the thread's instrumenter with an EventBuffer to collect events published during async query execution.
If the global async executor is saturated and the caller_runs fallback
executes the task on the calling thread, we need to make sure the previous
instrumenter is restored or the stale EventBuffer would stay in place and
permanently swallow all subsequent sql.active_record notifications on
that thread.
Rosa Gutierrez
Bump the minimum PostgreSQL version to 9.5, due to usage of array_position function.
Ivan Kuchin
Fix Ruby 4.0 delegator warning when calling inspect on ActiveRecord::Type::Serialized.
Hammad Khan
Fix support for table names containing hyphens.
Evgeniy Demin
Fix column deduplication for SQLite3 and PostgreSQL virtual (generated) columns.
Column#== and Column#hash now account for virtual? so that the Deduplicable registry does not treat a generated column and a regular
column with the same name and type as identical. Previously, if a
generated column was registered first, a regular column on a different
table could be deduplicated to the generated instance, silently
excluding it from INSERT/UPDATE statements.
Jay Huber
Fix PostgreSQL schema dumping to handle schema-qualified table names in foreign_key references that span different schemas.
before
add_foreign_key "hst.event_log_attributes", "hst.event_logs" # emits correctly because they're in the same schema (hst)
add_foreign_key "hst.event_log_attributes", "hst.usr.user_profiles", column: "created_by_id" # emits hst.user.* when user.* is expected
DiskService#path_for now raises an InvalidKeyError when passed keys with dot segments (".",
".."), or if the resolved path is outside the storage root directory.
#path_for also now consistently raises InvalidKeyError if the key is invalid in any way, for
example containing null bytes or having an incompatible encoding. Previously, the exception
raised may have been ArgumentError or Encoding::CompatibilityError.
DiskController now explicitly rescues InvalidKeyError with appropriate HTTP status codes.
Prevent glob injection in DiskService#delete_prefixed.
Escape glob metacharacters in the resolved path before passing to Dir.glob.
Note that this change breaks any existing code that is relying on delete_prefixed to expand
glob metacharacters. This change presumes that is unintended behavior (as other storage services
do not respect these metacharacters).
Make delegate and delegate_missing_to work in BasicObject subclasses.
Rafael Mendonça França
Fix Inflectors when using a locale that fallbacks to :en.
Said Kaldybaev
Fix ActiveSupport::TimeWithZone#as_json to consistently return UTF-8 strings.
Previously the returned string would sometime be encoded in US-ASCII, which in
some cases may be problematic.
Now the method consistently always return UTF-8 strings.
Jean Boussier
Fix TimeWithZone#xmlschema when wrapping a DateTime instance in local time.
Previously it would return an invalid time.
Dmytro Rymar
Implement LocalCache strategy on ActiveSupport::Cache::MemoryStore. The memory store
needs to respond to the same interface as other cache stores (e.g. ActiveSupport::NullStore).
Mikey Gough
Fix ActiveSupport::Inflector.humanize with international characters.
Fix strict locals parsing to handle multiline definitions.
Said Kaldybaev
Fix content_security_policy_nonce error in mailers when using content_security_policy_nonce_auto setting.
The content_security_policy_nonce helper is provided by ActionController::ContentSecurityPolicy, and it relies on request.content_security_policy_nonce. Mailers lack both the module and the request object.
Jarrett Lusso
Action Pack
Add config.action_controller.live_streaming_excluded_keys to control execution state sharing in ActionController::Live.
When using ActionController::Live, actions are executed in a separate thread that shares
state from the parent thread. This new configuration allows applications to opt-out specific
state keys that should not be shared.
This is useful when streaming inside a connected_to block, where you may want
the streaming thread to use its own database connection context.
Fix IpSpoofAttackError message to include Forwarded header content.
Without it, the error message may be misleading.
zzak
Active Job
Fix ActiveJob.perform_all_later to respect job_class.enqueue_after_transaction_commit.
Previously, perform_all_later would enqueue all jobs immediately, even if
they had enqueue_after_transaction_commit = true. Now it correctly defers
jobs with this setting until after transaction commits, matching the behavior
of perform_later.
OuYangJinTing
Fix using custom serializers with ActiveJob::Arguments.serialize when ActiveJob::Base hasn't been loaded.
Hartley McGuire
Action Mailer
No changes.
Action Cable
No changes.
Active Storage
Restore ADC when signing URLs with IAM for GCS
ADC was previously used for automatic authorization when signing URLs with IAM.
Now it is again, but the auth client is memoized so that new credentials are only
requested when the current ones expire. Other auth methods can now be used
instead by setting the authorization on ActiveStorage::Service::GCSService#iam_client.
This is safer than setting Google::Apis::RequestOptions.default.authorization
because it only applies to Active Storage and does not affect other Google API
clients.
Justin Malčić
Action Mailbox
No changes.
Action Text
No changes.
Railties
Skip all system test files on app generation.
Eileen M. Uchitelle
Fix db:system:change to correctly update Dockerfile base packages.
Josiah Smith
Fix devcontainer volume mount when app name differs from folder name.
Rafael Mendonça França
Fixed the rails notes command to properly extract notes in CSS files.
David White
Fixed the default Dockerfile to properly include the vendor/ directory during bundle install.
Standardize event name formatting in assert_event_reported error messages.
The event name in failure messages now uses .inspect (e.g., name: "user.created")
to match assert_events_reported and provide type clarity between strings and symbols.
This only affects tests that assert on the failure message format itself.
George Ma
Fix Enumerable#sole to return the full tuple instead of just the first element of the tuple.
Olivier Bellone
Fix parallel tests hanging when worker processes die abruptly.
Previously, if a worker process was killed (e.g., OOM killed, kill -9) during parallel
test execution, the test suite would hang forever waiting for the dead worker.
Fix NameError when class_attribute is defined on instance singleton classes.
Previously, calling class_attribute on an instance's singleton class would raise
a NameError when accessing the attribute through the instance.
object=MyClass.newobject.singleton_class.class_attribute:foo,default: "bar"object.foo# previously raised NameError, now returns "bar"
Joshua Young
Introduce ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting
to enable event reporter debug mode in tests.
The previous way to enable debug mode is by using #with_debug on the
event reporter itself, which is too verbose. This new helper will help
clear up any confusion on how to test debug events.
Gannon McGibbon
Add ActiveSupport::StructuredEventSubscriber for consuming notifications and
emitting structured event logs. Events may be emitted with the #emit_event
or #emit_debug_event methods.
ActiveSupport::FileUpdateChecker does not depend on Time.now to prevent unecessary reloads with time travel test helpers
Jan Grodowski
Add ActiveSupport::Cache::Store#namespace= and #namespace.
Can be used as an alternative to Store#clear in some situations such as parallel
testing.
Nick Schwaderer
Create parallel_worker_id helper for running parallel tests. This allows users to
know which worker they are currently running in.
Nick Schwaderer
Make the cache of ActiveSupport::Cache::Strategy::LocalCache::Middleware updatable.
If the cache client at Rails.cache of a booted application changes, the corresponding
mounted middleware needs to update in order for request-local caches to be setup properly.
Otherwise, redundant cache operations will erroneously hit the datastore.
Gannon McGibbon
Add assert_events_reported test helper for ActiveSupport::EventReporter.
This new assertion allows testing multiple events in a single block, regardless of order:
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
end
```
As well as context:
```ruby
All events will contain context: {request_id: "abc123", shop_id: 456}
Rails.event.set_context(request_id: "abc123", shop_id: 456)
```
Events are emitted to subscribers. Applications register subscribers to
control how events are serialized and emitted. Subscribers must implement
an `#emit` method, which receives the event hash:
```ruby
class LogSubscriber
def emit(event)
payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
source_location = event[:source_location]
log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
Rails.logger.info(log)
end
end
```
*Adrianna Chang*
Make ActiveSupport::Logger#freeze-friendly.
Joshua Young
Make ActiveSupport::Gzip.compress deterministic based on input.
ActiveSupport::Gzip.compress used to include a timestamp in the output,
causing consecutive calls with the same input data to have different output
if called during different seconds. It now always sets the timestamp to 0
so that the output is identical for any given input.
Rob Brackett
Given an array of Thread::Backtrace::Location objects, the new method ActiveSupport::BacktraceCleaner#clean_locations returns an array with the
clean ones:
Filters and silencers receive strings as usual. However, the path
attributes of the locations in the returned array are the original,
unfiltered ones, since locations are immutable.
Xavier Noria
Improve CurrentAttributes and ExecutionContext state managment in test cases.
Previously these two global state would be entirely cleared out whenever calling
into code that is wrapped by the Rails executor, typically Action Controller or
Active Job helpers:
Now re-entering the executor properly save and restore that state.
Jean Boussier
The new method ActiveSupport::BacktraceCleaner#first_clean_location
returns the first clean location of the caller's call stack, or nil.
Locations are Thread::Backtrace::Location objects. Useful when you want to
report the application-level location where something happened as an object.
Xavier Noria
FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.
Ermolaev Andrey, zzak
The new method ActiveSupport::BacktraceCleaner#first_clean_frame returns
the first clean frame of the caller's backtrace, or nil. Useful when you
want to report the application-level frame where something happened as a
string.
Xavier Noria
Always clear CurrentAttributes instances.
Previously CurrentAttributes instance would be reset at the end of requests.
Meaning its attributes would be re-initialized.
This is problematic because it assume these objects don't hold any state
other than their declared attribute, which isn't always the case, and
can lead to state leak across request.
Now CurrentAttributes instances are abandoned at the end of a request,
and a new instance is created at the start of the next request.
Jean Boussier, Janko Marohnić
Add public API for before_fork_hook in parallel testing.
Introduces a public API for calling the before fork hooks implemented by parallel testing.
parallelize_before_forkdo
perform an action before test processes are forked
end
```
*Eileen M. Uchitelle*
Implement ability to skip creating parallel testing databases.
With parallel testing, Rails will create a database per process. If this isn't
desirable or you would like to implement databases handling on your own, you can
now turn off this default behavior.
To skip creating a database per process, you can change it via the parallelize method:
When reporting an error, the error context middleware will be called with the reported error
and base execution context. The stack may mutate the context hash. The mutated context will
then be passed to error subscribers. Middleware receives the same parameters as ErrorReporter#report.
Andrew Novoselac, Sam Schmidt
Change execution wrapping to report all exceptions, including Exception.
If a more serious error like SystemStackError or NoMemoryError happens,
the error reporter should be able to report these kinds of exceptions.
Gannon McGibbon
ActiveSupport::Testing::Parallelization.before_fork_hook allows declaration of callbacks that
are invoked immediately before forking test workers.
Mike Dalessio
Allow the #freeze_time testing helper to accept a date or time argument.
Time.current# => Sun, 09 Jul 2024 15:34:49 EST -05:00freeze_timeTime.current + 1.daysleep1Time.current# => Mon, 10 Jul 2024 15:34:49 EST -05:00
Joshua Young
ActiveSupport::JSON now accepts options
It is now possible to pass options to ActiveSupport::JSON:
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 CASCADE foreign 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_integrity inside a transaction, but PRAGMA foreign_keys cannot 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_integrity now 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
Add replicas to test database parallelization setup.
Setup and configuration of databases for parallel testing now includes replicas.
This fixes an issue when using a replica database, database selector middleware,
and non-transactional tests, where integration tests running in parallel would select
the base test database, i.e. db_test, instead of the numbered parallel worker database,
i.e. db_test_{n}.
Adam Maas
Support virtual (not persisted) generated columns on PostgreSQL 18+
PostgreSQL 18 introduces virtual (not persisted) generated columns,
which are now the default unless the stored: true option is explicitly specified on PostgreSQL 18+.
Optimize schema dumping to prevent duplicate file generation.
ActiveRecord::Tasks::DatabaseTasks.dump_all now tracks which schema files
have already been dumped and skips dumping the same file multiple times.
This improves performance when multiple database configurations share the
same schema dump path.
Similar in use case to ignored_columns but listing columns to consider rather than the ones
to ignore.
Can be useful when working with a legacy or shared database schema, or to make safe schema change
in two deploys rather than three.
Anton Kandratski
Use PG::Connection#close_prepared (protocol level Close) to deallocate
prepared statements when available.
To enable its use, you must have pg >= 1.6.0, libpq >= 17, and a PostgreSQL
database version >= 17.
Hartley McGuire, Andrew Jackson
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
Fix time attribute dirty tracking with timezone conversions.
Time-only attributes now maintain a fixed date of 2000-01-01 during timezone conversions,
preventing them from being incorrectly marked as changed due to date shifts.
This fixes an issue where time attributes would be marked as changed when setting the same time value
due to timezone conversion causing internal date shifts.
Prateek Choudhary
Skip calling PG::Connection#cancel in cancel_any_running_query
when using libpq >= 18 with pg < 1.6.0, due to incompatibility.
Rollback still runs, but may take longer.
Yasuo Honda, Lars Kanis
Don't add id_value attribute alias when attribute/column with that name already exists.
Rob Lewis
Remove deprecated :unsigned_float and :unsigned_decimal column methods for MySQL.
Rafael Mendonça França
Remove deprecated :retries option for the SQLite3 adapter.
Rafael Mendonça França
Introduce new database configuration options keepalive, max_age, and min_connections -- and rename pool to max_connections to match.
There are no changes to default behavior, but these allow for more specific
control over pool behavior.
Matthew Draper, Chris AtLee, Rachael Wright-Munn
Move LIMIT validation from query generation to when limit() is called.
Hartley McGuire, Shuyang
Add ActiveRecord::CheckViolation error class for check constraint violations.
Ryuta Kamizono
Add ActiveRecord::ExclusionViolation error class for exclusion constraint violations.
When an exclusion constraint is violated in PostgreSQL, the error will now be raised
as ActiveRecord::ExclusionViolation instead of the generic ActiveRecord::StatementInvalid,
making it easier to handle these specific constraint violations in application code.
This follows the same pattern as other constraint violation error classes like RecordNotUnique for unique constraint violations and InvalidForeignKey for
foreign key constraint violations.
Ryuta Kamizono
Attributes filtered by filter_attributes will now also be filtered by filter_parameters
so sensitive information is not leaked.
Jill Klang
Add connection.current_transaction.isolation API to check current transaction's isolation level.
Returns the isolation level if it was explicitly set via the isolation: parameter
or through ActiveRecord.with_transaction_isolation_level, otherwise returns nil.
Nested transactions return the parent transaction's isolation level.
User.transaction(isolation: :serializable) do
User.connection.current_transaction.isolation # => :serializable
end
Returns nil when isolation not explicitly set
User.transaction do
User.connection.current_transaction.isolation # => nil
end
Nested transactions inherit parent's isolation
User.transaction(isolation: :read_committed) do
User.transaction do
User.connection.current_transaction.isolation # => :read_committed
end
end
```
*Kir Shatrov*
Fix #merge with #or or #and and a mixture of attributes and SQL strings resulting in an incorrect query.
Optimize Active Record batching further when using ranges.
Tested on a PostgreSQL table with 10M records and batches of 10k records, the generation
of relations for the 1000 batches was 4.8x faster (6.8s vs. 1.4s), used 900x
less bandwidth (180MB vs. 0.2MB) and allocated 45x less memory (490MB vs. 11MB).
Maxime Réty, fatkodima
Include current character length in error messages for index and table name length validations.
Joshua Young
Add rename_schema method for PostgreSQL.
T S Vallender
Implement support for deprecating associations:
has_many:posts,deprecated: true
With that, Active Record will report any usage of the posts association.
Three reporting modes are supported (:warn, :raise, and :notify), and
backtraces can be enabled or disabled. Defaults are :warn mode and
disabled backtraces.
Please, check the docs for further details.
Xavier Noria
PostgreSQL adapter create DB now supports locale_provider and locale.
Bengt-Ove Hollaender
Use ntuples to populate row_count instead of count for Postgres
Jonathan Calvert
Fix checking whether an unpersisted record is include?d in a strictly
loaded has_and_belongs_to_many association.
Hartley McGuire
Add ability to change transaction isolation for all pools within a block.
This functionality is useful if your application needs to change the database
transaction isolation for a request or action.
Calling ActiveRecord.with_transaction_isolation_level(level) {} in an around filter or
middleware will set the transaction isolation for all pools accessed within the block,
but not for the pools that aren't.
This works with explicit and implicit transactions:
ActiveRecord.with_transaction_isolation_level(:read_committed)doTag.transactiondo# opens a transaction explicitlyTag.create!endend
ActiveRecord.with_transaction_isolation_level(:read_committed)doTag.create!# opens a transaction implicitlyend
Eileen M. Uchitelle
Raise ActiveRecord::MissingRequiredOrderError when order dependent finder methods (e.g. #first, #last) are
called without order values on the relation, and the model does not have any order columns (implicit_order_column, query_constraints, or primary_key) to fall back on.
This change will be introduced with a new framework default for Rails 8.1, and the current behavior of not raising
an error has been deprecated with the aim of removing the configuration option in Rails 8.2.
:class_name is now invalid in polymorphic belongs_to associations.
Reason is :class_name does not make sense in those associations because
the class name of target records is dynamic and stored in the type column.
Existing polymorphic associations setting this option can just delete it.
While it did not raise, it had no effect anyway.
Xavier Noria
Add support for multiple databases to db:migrate:reset.
Joé Dupuis
Add affected_rows to ActiveRecord::Result.
Jenny Shen
Enable passing retryable SqlLiterals to #where.
Hartley McGuire
Set default for primary keys in insert_all/upsert_all.
Previously in Postgres, updating and inserting new records in one upsert wasn't possible
due to null primary key values. nil primary key values passed into insert_all/upsert_all
are now implicitly set to the default insert value specified by adapter.
Jenny Shen
Add a load hook active_record_database_configurations for ActiveRecord::DatabaseConfigurations
Mike Dalessio
Use TRUE and FALSE for SQLite queries with boolean columns.
Hartley McGuire
Bump minimum supported SQLite to 3.23.0.
Hartley McGuire
Allow allocated Active Records to lookup associations.
Previously, the association cache isn't setup on allocated record objects, so association
lookups will crash. Test frameworks like mocha use allocate to check for stubbable instance
methods, which can trigger an association lookup.
Gannon McGibbon
Encryption now supports support_unencrypted_data: true being set per-attribute.
Previously this only worked if ActiveRecord::Encryption.config.support_unencrypted_data == true.
Now, if the global config is turned off, you can still opt in for a specific attribute.
class User < ActiveRecord::Base
encrypts :name, support_unencrypted_data: false # only supports encrypted data
encrypts :email # supports encrypted or unencrypted data
end
```
```ruby
class User < ActiveRecord::Base
encrypts :name, support_unencrypted_data: true # supports encrypted or unencrypted data
encrypts :email # only supports encrypted data
end
```
*Alex Ghiculescu*
Model generator no longer needs a database connection to validate column types.
Mike Dalessio
Allow signed ID verifiers to be configurable via Rails.application.message_verifiers
Prior to this change, the primary way to configure signed ID verifiers was
to set signed_id_verifier on each model class:
And if the developer did not set signed_id_verifier, a verifier would be
instantiated with a secret derived from secret_key_base and the following
options:
Thus it was cumbersome to rotate configuration for all verifiers.
This change defines a new Rails config: [config.active_record.use_legacy_signed_id_verifier][].
The default value is :generate_and_verify, which preserves the previous
behavior. However, when set to :verify, signed ID verifiers will use
configuration from Rails.application.message_verifiers (specifically, Rails.application.message_verifiers["active_record/signed_id"]) to
generate and verify signed IDs, but will also verify signed IDs using the
older configuration.
To avoid complication, the new behavior only applies when signed_id_verifier_secret
is not set on a model class or any of its ancestors. Additionally, signed_id_verifier_secret is now deprecated. If you are currently setting signed_id_verifier_secret on a model class, you can set signed_id_verifier
instead:
BEFORE
Post.signed_id_verifier_secret = "my secret"
AFTER
Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
```
To ease migration, `signed_id_verifier` has also been changed to behave as a
`class_attribute` (i.e. inheritable), but _only when `signed_id_verifier_secret`
is not set_:
```ruby
ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
Post.signed_id_verifier_secret = "my secret" # => deprecation warning
Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
```
Note, however, that it is recommended to eventually migrate from
model-specific verifiers to a unified configuration managed by
`Rails.application.message_verifiers`. `ActiveSupport::MessageVerifier#rotate`
can facilitate that transition. For example:
```ruby
BEFORE
Generate and verify signed Post IDs using Post-specific configuration
When specifying structure_load_flags with a postgres adapter, the flags
were appended to the default flags, instead of prepended.
This caused issues with flags not being taken into account by postgres.
Alice Loeser
Allow bypassing primary key/constraint addition in implicit_order_column
When specifying multiple columns in an array for implicit_order_column, adding nil as the last element will prevent appending the primary key to order
conditions. This allows more precise control of indexes used by
generated queries. It should be noted that this feature does introduce the risk
of API misbehavior if the specified columns are not fully unique.
Issy Long
Allow setting the schema_format via database configuration.
primary:
schema_format: ruby
Useful for multi-database setups when apps require different formats per-database.
T S Vallender
Support disabling indexes for MySQL v8.0.0+ and MariaDB v10.6.0+
MySQL 8.0.0 added an option to disable indexes from being used by the query
optimizer by making them "invisible". This allows the index to still be maintained
and updated but no queries will be permitted to use it. This can be useful for adding
new invisible indexes or making existing indexes invisible before dropping them
to ensure queries are not negatively affected.
See https://dev.mysql.com/blog-archive/mysql-8-0-invisible-indexes/ for more details.
Active Record now supports this option for MySQL 8.0.0+ and MariaDB 10.6.0+ for
index creation and alteration where the new index option enabled: true/false can be
passed to column and index methods as below:
Respect implicit_order_column in ActiveRecord::Relation#reverse_order.
Joshua Young
Add column types to ActiveRecord::Result for SQLite3.
Andrew Kane
Raise ActiveRecord::ReadOnlyError when pessimistically locking with a readonly role.
Joshua Young
Fix using the SQLite3Adapter's dbconsole method outside of a Rails application.
Hartley McGuire
Fix migrating multiple databases with ActiveRecord::PendingMigration action.
Gannon McGibbon
Enable automatically retrying idempotent association queries on connection
errors.
Hartley McGuire
Add allow_retry to sql.active_record instrumentation.
This enables identifying queries which queries are automatically retryable on connection errors.
Hartley McGuire
Better support UPDATE with JOIN for Postgresql and SQLite3
Previously when generating update queries with one or more JOIN clauses,
Active Record would use a sub query which would prevent to reference the joined
tables in the SET clause, for instance:
This is now supported as long as the relation doesn't also use a LIMIT, ORDER or GROUP BY clause. This was supported by the MySQL adapter for a long time.
Jean Boussier
Introduce a before-fork hook in ActiveSupport::Testing::Parallelization to clear existing
connections, to avoid fork-safety issues with the mysql2 adapter.
PoolConfig no longer keeps a reference to the connection class.
Keeping a reference to the class caused subtle issues when combined with reloading in
development. Fixes #54343.
Mike Dalessio
Fix SQL notifications sometimes not sent when using async queries.
Post.async_countActiveSupport::Notifications.subscribed(->(*){"Will never reach here"})doPost.countend
In rare circumstances and under the right race condition, Active Support notifications
would no longer be dispatched after using an asynchronous query.
This is now fixed.
Edouard Chin
Eliminate queries loading dumped schema cache on Postgres
Improve resiliency by avoiding needing to open a database connection to load the
type map while defining attribute methods at boot when a schema cache file is
configured on PostgreSQL databases.
James Coleman
ActiveRecord::Coder::JSON can be instantiated
Options can now be passed to ActiveRecord::Coder::JSON when instantiating the coder. This allows:
Deprecate using insert_all/upsert_all with unpersisted records in associations.
Using these methods on associations containing unpersisted records will now
show a deprecation warning, as the unpersisted records will be lost after
the operation.
Nick Schwaderer
Make column name optional for index_exists?.
This aligns well with remove_index signature as well, where
index name doesn't need to be derived from the column names.
Ali Ismayiliov
Change the payload name of sql.active_record notification for eager
loading from "SQL" to "#{model.name} Eager Load".
zzak
Enable automatically retrying idempotent #exists? queries on connection
errors.
Hartley McGuire, classidied
Deprecate usage of unsupported methods in conjunction with update_all:
update_all will now print a deprecation message if a query includes either WITH, WITH RECURSIVE or DISTINCT statements. Those were never supported and were ignored
when generating the SQL query.
An error will be raised in a future Rails release. This behavior will be consistent
with delete_all which currently raises an error for unsupported statements.
Edouard Chin
The table columns inside schema.rb are now sorted alphabetically.
Previously they'd be sorted by creation order, which can cause merge conflicts when two
branches modify the same table concurrently.
John Duff
Introduce versions formatter for the schema dumper.
It is now possible to override how schema dumper formats versions information inside the structure.sql file. Currently, the versions are simply sorted in the decreasing order.
Within large teams, this can potentially cause many merge conflicts near the top of the list.
Now, the custom formatter can be provided with a custom sorting logic (e.g. by hash values
of the versions), which can greatly reduce the number of conflicts.
fatkodima
Serialized attributes can now be marked as comparable.
A not rare issue when working with serialized attributes is that the serialized representation of an object
can change over time. Either because you are migrating from one serializer to the other (e.g. YAML to JSON or to msgpack),
or because the serializer used subtly changed its output.
One example is libyaml that used to have some extra trailing whitespaces, and recently fixed that.
When this sorts of thing happen, you end up with lots of records that report being changed even though
they aren't, which in the best case leads to a lot more writes to the database and in the worst case lead to nasty bugs.
The solution is to instead compare the deserialized representation of the object, however Active Record
can't assume the deserialized object has a working == method. Hence why this new functionality is opt-in.
Fix MySQL default functions getting dropped when changing a column's nullability.
Bastian Bartmann
SQLite extensions can be configured in config/database.yml.
The database configuration option extensions: allows an application to load SQLite extensions
when using sqlite3 >= v2.4.0. The array members may be filesystem paths or the names of
modules that respond to .to_path:
development:
adapter: sqlite3extensions:
- SQLean::UUID # module name responding to `.to_path`
- .sqlpkg/nalgeon/crypto/crypto.so # or a filesystem path
- <%= AppExtensions.location %> # or ruby code returning a path
A new configuration option, class_name:, is introduced to config.active_record.shard_selector to allow an application to specify the abstract connection
class to be switched by the shard selection middleware. The default class is ActiveRecord::Base.
For example, this configuration te
✂ Note
PR body was truncated to here.
Configuration
📅 Schedule: (UTC)
Branch creation
At any time (no schedule defined)
Automerge
At any time (no schedule defined)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
If you want to rebase/retry this PR, check this box
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore gem/actionpack@8.1.3. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: gem activerecord is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore gem/activerecord@8.1.3. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: gem activerecord is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore gem/activerecord@8.1.3. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: gem activesupport is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore gem/activesupport@8.1.3. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Unpopular packages may have less maintenance and contain other problems.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore gem/action_text-trix@2.1.19. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
"~> 7.0.0"→"~> 8.1.0"Release Notes
rails/rails (rails)
v8.1.3: 8.1.3Compare Source
Active Support
Fix
JSONGemCoderEncoderto correctly serialize custom object hash keys.When hash keys are custom objects whose
as_jsonreturns a Hash,the encoder now calls
to_son the original key object instead ofon the
as_jsonresult.Before:
hash = {CustomKey.new(123) => "value"}
hash.to_json # => {"{:id=>123}":"value"}
After:
hash.to_json # => {"custom_123":"value"}
Dan Sharp
Fix inflections to better handle overlapping acronyms.
Said Kaldybaev
Silence Dalli 4.0+ warning when using
ActiveSupport::Cache::MemCacheStore.zzak
Active Model
Fix Ruby 4.0 delegator warning when calling inspect on attributes.
Hammad Khan
Fix
NoMethodErrorwhen deserialisingType::Integerobjects marshalled under Rails 8.0.The performance optimisation that replaced
@rangewith@max/@minbroke Marshal compatibility. Objects serialised under 8.0 (with
@range)and deserialised under 8.1 (expecting
@max/@min) would crash withundefined method '<=' for nilbecauseMarshal.loadrestores instancevariables without calling
initialize.Edward Woodcock
Active Record
Fix
insert_allandupsert_alllog message when called on anonymous classes.Gabriel Sobrinho
Respect
ActiveRecord::SchemaDumper.ignore_tableswhen dumping SQLite virtual tables.Hans Schnedlitz
Restore previous instrumenter after
execute_or_skipFutureResult#execute_or_skipreplaces the thread's instrumenter with anEventBufferto collect events published during async query execution.If the global async executor is saturated and the
caller_runsfallbackexecutes the task on the calling thread, we need to make sure the previous
instrumenter is restored or the stale
EventBufferwould stay in place andpermanently swallow all subsequent
sql.active_recordnotifications onthat thread.
Rosa Gutierrez
Bump the minimum PostgreSQL version to 9.5, due to usage of
array_positionfunction.Ivan Kuchin
Fix Ruby 4.0 delegator warning when calling inspect on ActiveRecord::Type::Serialized.
Hammad Khan
Fix support for table names containing hyphens.
Evgeniy Demin
Fix column deduplication for SQLite3 and PostgreSQL virtual (generated) columns.
Column#==andColumn#hashnow account forvirtual?so that theDeduplicableregistry does not treat a generated column and a regularcolumn with the same name and type as identical. Previously, if a
generated column was registered first, a regular column on a different
table could be deduplicated to the generated instance, silently
excluding it from INSERT/UPDATE statements.
Jay Huber
Fix PostgreSQL schema dumping to handle schema-qualified table names in foreign_key references that span different schemas.
before
after
Action View
Fix encoding errors for string locals containing non-ASCII characters.
Kataoka Katsuki
Fix collection caching to only forward
expires_inargument if explicitly set.Pieter Visser
Action Pack
Active Job
Action Mailer
Action Cable
Active Storage
Fix
ActiveStorage::Blobcontent type predicate methods to handlenil.Daichi KUDO
Action Mailbox
Action Text
Railties
Add
libvipsto generatedci.ymlConditionally adds
libvipstoci.yml.Steve Polito
Guides
v8.1.2.1: 8.1.2.1Compare Source
Active Support
Reject scientific notation in NumberConverter
[CVE-2026-33176]
Jean Boussier
Fix
SafeBuffer#%to preserve unsafe status[CVE-2026-33170]
Jean Boussier
Improve performance of NumberToDelimitedConverter
[CVE-2026-33169]
Jean Boussier
Active Model
Active Record
Action View
Skip blank attribute names in tag helpers to avoid generating invalid HTML.
[CVE-2026-33168]
Mike Dalessio
Action Pack
Fix possible XSS in DebugExceptions middleware
[CVE-2026-33167]
John Hawthorn
Active Job
Action Mailer
Action Cable
Active Storage
Filter user supplied metadata in DirectUploadController
[CVE-2026-33173]
Jean Boussier
Configurable maxmimum streaming chunk size
Makes sure that byte ranges for blobs don't exceed 100mb by default.
Content ranges that are too big can result in denial of service.
[CVE-2026-33174]
Gannon McGibbon
Limit range requests to a single range
[CVE-2026-33658]
Jean Boussier
Prevent path traversal in
DiskService.DiskService#path_fornow raises anInvalidKeyErrorwhen passed keys with dot segments (".",".."), or if the resolved path is outside the storage root directory.
#path_foralso now consistently raisesInvalidKeyErrorif the key is invalid in any way, forexample containing null bytes or having an incompatible encoding. Previously, the exception
raised may have been
ArgumentErrororEncoding::CompatibilityError.DiskControllernow explicitly rescuesInvalidKeyErrorwith appropriate HTTP status codes.[CVE-2026-33195]
Mike Dalessio
Prevent glob injection in
DiskService#delete_prefixed.Escape glob metacharacters in the resolved path before passing to
Dir.glob.Note that this change breaks any existing code that is relying on
delete_prefixedto expandglob metacharacters. This change presumes that is unintended behavior (as other storage services
do not respect these metacharacters).
[CVE-2026-33202]
Mike Dalessio
Action Mailbox
Action Text
Railties
Guides
v8.1.2: 8.1.2Compare Source
Active Support
Make
delegateanddelegate_missing_towork in BasicObject subclasses.Rafael Mendonça França
Fix Inflectors when using a locale that fallbacks to
:en.Said Kaldybaev
Fix
ActiveSupport::TimeWithZone#as_jsonto consistently return UTF-8 strings.Previously the returned string would sometime be encoded in US-ASCII, which in
some cases may be problematic.
Now the method consistently always return UTF-8 strings.
Jean Boussier
Fix
TimeWithZone#xmlschemawhen wrapping aDateTimeinstance in local time.Previously it would return an invalid time.
Dmytro Rymar
Implement LocalCache strategy on
ActiveSupport::Cache::MemoryStore. The memory storeneeds to respond to the same interface as other cache stores (e.g.
ActiveSupport::NullStore).Mikey Gough
Fix
ActiveSupport::Inflector.humanizewith international characters.Jose Luis Duran
Active Model
Active Record
Fix counting cached queries in
ActiveRecord::RuntimeRegistry.fatkodima
Fix merging relations with arel equality predicates with null relations.
fatkodima
Fix SQLite3 schema dump for non-autoincrement integer primary keys.
Previously,
schema.rbshould incorrectly restore that table with an auto incrementingprimary key.
Chris Hasiński
Fix PostgreSQL
schema_search_pathnot being reapplied afterreset!orreconnect!.The
schema_search_pathconfigured indatabase.ymlis now correctlyreapplied instead of falling back to PostgreSQL defaults.
Tobias Egli
Restore the ability of enum to be foats.
In Rails 8.1.0, enum values are eagerly validated, and floats weren't expected.
Said Kaldybaev
Ensure batched preloaded associations accounts for klass when grouping to avoid issues with STI.
zzak, Stjepan Hadjic
Fix
ActiveRecord::SoleRecordExceeded#recordto return the relation.This was the case until Rails 7.2, but starting from 8.0 it
started mistakenly returning the model class.
Jean Boussier
Improve PostgreSQLAdapter resilience to Timeout.timeout.
Better handle asynchronous exceptions being thrown inside
the
reconnect!method.This may fixes some deep errors such as:
Jean Boussier
Fix structured events for Active Record was not being emitted.
Yuji Yaginuma
Fix
eager_loadwhen loadinghas_manyassocations with composite primary keys.This would result in some records being loaded multiple times.
Martin-Alexander
Action View
Fix
file_fieldto join mime types with a comma when provided as ArrayNow behaves likes:
Bogdan Gusiev
Fix strict locals parsing to handle multiline definitions.
Said Kaldybaev
Fix
content_security_policy_nonceerror in mailers when usingcontent_security_policy_nonce_autosetting.The
content_security_policy_nonce helperis provided byActionController::ContentSecurityPolicy, and it relies onrequest.content_security_policy_nonce. Mailers lack both the module and the request object.Jarrett Lusso
Action Pack
Add
config.action_controller.live_streaming_excluded_keysto control execution state sharing in ActionController::Live.When using ActionController::Live, actions are executed in a separate thread that shares
state from the parent thread. This new configuration allows applications to opt-out specific
state keys that should not be shared.
This is useful when streaming inside a
connected_toblock, where you may wantthe streaming thread to use its own database connection context.
By default, all keys are shared.
Eileen M. Uchitelle
Fix
IpSpoofAttackErrormessage to includeForwardedheader content.Without it, the error message may be misleading.
zzak
Active Job
Fix
ActiveJob.perform_all_laterto respectjob_class.enqueue_after_transaction_commit.Previously,
perform_all_laterwould enqueue all jobs immediately, even ifthey had
enqueue_after_transaction_commit = true. Now it correctly defersjobs with this setting until after transaction commits, matching the behavior
of
perform_later.OuYangJinTing
Fix using custom serializers with
ActiveJob::Arguments.serializewhenActiveJob::Basehasn't been loaded.Hartley McGuire
Action Mailer
Action Cable
Active Storage
Restore ADC when signing URLs with IAM for GCS
ADC was previously used for automatic authorization when signing URLs with IAM.
Now it is again, but the auth client is memoized so that new credentials are only
requested when the current ones expire. Other auth methods can now be used
instead by setting the authorization on
ActiveStorage::Service::GCSService#iam_client.This is safer than setting
Google::Apis::RequestOptions.default.authorizationbecause it only applies to Active Storage and does not affect other Google API
clients.
Justin Malčić
Action Mailbox
Action Text
Railties
Skip all system test files on app generation.
Eileen M. Uchitelle
Fix
db:system:changeto correctly update Dockerfile base packages.Josiah Smith
Fix devcontainer volume mount when app name differs from folder name.
Rafael Mendonça França
Fixed the
rails notescommand to properly extract notes in CSS files.David White
Fixed the default Dockerfile to properly include the
vendor/directory duringbundle install.Zhong Sheng
Guides
v8.1.1: 8.1.1Compare Source
Active Support
Active Model
Active Record
Action View
Respect
remove_hidden_field_autocompleteconfig in form builderhidden_field.Rafael Mendonça França
Action Pack
Allow methods starting with underscore to be action methods.
Disallowing methods starting with an underscore from being action methods
was an unintended side effect of the performance optimization in
207a254.Fixes #55985.
Rafael Mendonça França
Active Job
Only index new serializers.
Jesse Sharps
Action Mailer
Action Cable
Active Storage
Action Mailbox
Action Text
Railties
Do not assume and force SSL in production by default when using Kamal, to allow for out of the box Kamal deployments.
It is still recommended to assume and force SSL in production as soon as you can.
Jerome Dalbert
Guides
v8.1.0: 8.1.0Compare Source
Active Support
Remove deprecated passing a Time object to
Time#since.Rafael Mendonça França
Remove deprecated
Benchmark.msmethod. It is now defined in thebenchmarkgem.Rafael Mendonça França
Remove deprecated addition for
Timeinstances withActiveSupport::TimeWithZone.Rafael Mendonça França
Remove deprecated support for
to_timeto preserve the system local time. It will now always preserve the receivertimezone.
Rafael Mendonça França
Deprecate
config.active_support.to_time_preserves_timezone.Rafael Mendonça França
Standardize event name formatting in
assert_event_reportederror messages.The event name in failure messages now uses
.inspect(e.g.,name: "user.created")to match
assert_events_reportedand provide type clarity between strings and symbols.This only affects tests that assert on the failure message format itself.
George Ma
Fix
Enumerable#soleto return the full tuple instead of just the first element of the tuple.Olivier Bellone
Fix parallel tests hanging when worker processes die abruptly.
Previously, if a worker process was killed (e.g., OOM killed,
kill -9) during paralleltest execution, the test suite would hang forever waiting for the dead worker.
Joshua Young
Add
config.active_support.escape_js_separators_in_json.Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.
Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
Étienne Barrié, Jean Boussier
Fix
NameErrorwhenclass_attributeis defined on instance singleton classes.Previously, calling
class_attributeon an instance's singleton class would raisea
NameErrorwhen accessing the attribute through the instance.Joshua Young
Introduce
ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reportingto enable event reporter debug mode in tests.
The previous way to enable debug mode is by using
#with_debugon theevent reporter itself, which is too verbose. This new helper will help
clear up any confusion on how to test debug events.
Gannon McGibbon
Add
ActiveSupport::StructuredEventSubscriberfor consuming notifications andemitting structured event logs. Events may be emitted with the
#emit_eventor
#emit_debug_eventmethods.Adrianna Chang
ActiveSupport::FileUpdateCheckerdoes not depend onTime.nowto prevent unecessary reloads with time travel test helpersJan Grodowski
Add
ActiveSupport::Cache::Store#namespace=and#namespace.Can be used as an alternative to
Store#clearin some situations such as paralleltesting.
Nick Schwaderer
Create
parallel_worker_idhelper for running parallel tests. This allows users toknow which worker they are currently running in.
Nick Schwaderer
Make the cache of
ActiveSupport::Cache::Strategy::LocalCache::Middlewareupdatable.If the cache client at
Rails.cacheof a booted application changes, the correspondingmounted middleware needs to update in order for request-local caches to be setup properly.
Otherwise, redundant cache operations will erroneously hit the datastore.
Gannon McGibbon
Add
assert_events_reportedtest helper forActiveSupport::EventReporter.This new assertion allows testing multiple events in a single block, regardless of order:
George Ma
Add
ActiveSupport::TimeZone#standard_namemethod.Old way
New way
Add Structured Event Reporter, accessible via
Rails.event.The Event Reporter provides a unified interface for producing structured events in Rails
applications:
It supports adding tags to events:
Event includes tags: { graphql: true }
All events will contain context: {request_id: "abc123", shop_id: 456}
Make
ActiveSupport::Logger#freeze-friendly.Joshua Young
Make
ActiveSupport::Gzip.compressdeterministic based on input.ActiveSupport::Gzip.compressused to include a timestamp in the output,causing consecutive calls with the same input data to have different output
if called during different seconds. It now always sets the timestamp to
0so that the output is identical for any given input.
Rob Brackett
Given an array of
Thread::Backtrace::Locationobjects, the new methodActiveSupport::BacktraceCleaner#clean_locationsreturns an array with theclean ones:
Filters and silencers receive strings as usual. However, the
pathattributes of the locations in the returned array are the original,
unfiltered ones, since locations are immutable.
Xavier Noria
Improve
CurrentAttributesandExecutionContextstate managment in test cases.Previously these two global state would be entirely cleared out whenever calling
into code that is wrapped by the Rails executor, typically Action Controller or
Active Job helpers:
Now re-entering the executor properly save and restore that state.
Jean Boussier
The new method
ActiveSupport::BacktraceCleaner#first_clean_locationreturns the first clean location of the caller's call stack, or
nil.Locations are
Thread::Backtrace::Locationobjects. Useful when you want toreport the application-level location where something happened as an object.
Xavier Noria
FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.
Ermolaev Andrey, zzak
The new method
ActiveSupport::BacktraceCleaner#first_clean_framereturnsthe first clean frame of the caller's backtrace, or
nil. Useful when youwant to report the application-level frame where something happened as a
string.
Xavier Noria
Always clear
CurrentAttributesinstances.Previously
CurrentAttributesinstance would be reset at the end of requests.Meaning its attributes would be re-initialized.
This is problematic because it assume these objects don't hold any state
other than their declared attribute, which isn't always the case, and
can lead to state leak across request.
Now
CurrentAttributesinstances are abandoned at the end of a request,and a new instance is created at the start of the next request.
Jean Boussier, Janko Marohnić
Add public API for
before_fork_hookin parallel testing.Introduces a public API for calling the before fork hooks implemented by parallel testing.
perform an action before test processes are forked
Implement ability to skip creating parallel testing databases.
With parallel testing, Rails will create a database per process. If this isn't
desirable or you would like to implement databases handling on your own, you can
now turn off this default behavior.
To skip creating a database per process, you can change it via the
parallelizemethod:or via the application configuration:
Eileen M. Uchitelle
Allow to configure maximum cache key sizes
When the key exceeds the configured limit (250 bytes by default), it will be truncated and
the digest of the rest of the key appended to it.
Note that previously
ActiveSupport::Cache::RedisCacheStoreallowed up to 1kb cache keys beforetruncation, which is now reduced to 250 bytes.
fatkodima
Use
UNLINKcommand instead ofDELinActiveSupport::Cache::RedisCacheStorefor non-blocking deletion.Aron Roh
Add
Cache#read_counterandCache#write_counterAlex Ghiculescu
Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports
Captures all reported errors from within the block that match the given
error class.
Andrew Novoselac
Introduce ActiveSupport::ErrorReporter#add_middleware
When reporting an error, the error context middleware will be called with the reported error
and base execution context. The stack may mutate the context hash. The mutated context will
then be passed to error subscribers. Middleware receives the same parameters as
ErrorReporter#report.Andrew Novoselac, Sam Schmidt
Change execution wrapping to report all exceptions, including
Exception.If a more serious error like
SystemStackErrororNoMemoryErrorhappens,the error reporter should be able to report these kinds of exceptions.
Gannon McGibbon
ActiveSupport::Testing::Parallelization.before_fork_hookallows declaration of callbacks thatare invoked immediately before forking test workers.
Mike Dalessio
Allow the
#freeze_timetesting helper to accept a date or time argument.Joshua Young
ActiveSupport::JSONnow accepts optionsIt is now possible to pass options to
ActiveSupport::JSON:matthaigh27
ActiveSupport::Testing::NotificationAssertions'sassert_notificationnow matches against payload subsets by default.Previously the following assertion would fail due to excess key vals in the notification payload. Now with payload subset matching, it will pass.
Additionally, you can now persist a matched notification for more customized assertions.
Nicholas La Roux
Deprecate
String#mb_charsandActiveSupport::Multibyte::Chars.These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
aware. There is no legitimate reasons to need these APIs today.
Jean Boussier
Deprecate
ActiveSupport::ConfigurableSean Doyle
nil.to_query("key")now returnskey.Previously it would return
key=, preventing round tripping withRack::Utils.parse_nested_query.Erol Fornoles
Avoid wrapping redis in a
ConnectionPoolwhen usingActiveSupport::Cache::RedisCacheStoreif the:redisoption is already a
ConnectionPool.Joshua Young
Alter
ERB::Util.tokenizeto return :PLAIN token with full input string when string doesn't contain ERB tags.Martin Emde
Fix a bug in
ERB::Util.tokenizethat causes incorrect tokenization when ERB tags are preceded by multibyte characters.Martin Emde
Add
ActiveSupport::Testing::NotificationAssertionsmodule to help with testingActiveSupport::Notifications.Nicholas La Roux, Yishu See, Sean Doyle
ActiveSupport::CurrentAttributes#attributesnow will return a new hash object on each call.Previously, the same hash object was returned each time that method was called.
fatkodima
ActiveSupport::JSON.encodesupports CIDR notation.Previously:
After this change:
Taketo Takashima
Make
ActiveSupport::FileUpdateCheckerfaster when checking many file-extensions.Jonathan del Strother
Active Model
Add
reset_token: { expires_in: ... }option tohas_secure_password.Allows configuring the expiry duration of password reset tokens (default remains 15 minutes for backwards compatibility).
Jevin Sew, Abeid Ahmed
Add
except_on:option for validation callbacks.Ben Sheldon
Backport
ActiveRecord::NormalizationtoActiveModel::Attributes::NormalizationSean Doyle
Active Record
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 alldata 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, butPRAGMA 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 insteadof 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
Add replicas to test database parallelization setup.
Setup and configuration of databases for parallel testing now includes replicas.
This fixes an issue when using a replica database, database selector middleware,
and non-transactional tests, where integration tests running in parallel would select
the base test database, i.e.
db_test, instead of the numbered parallel worker database,i.e.
db_test_{n}.Adam Maas
Support virtual (not persisted) generated columns on PostgreSQL 18+
PostgreSQL 18 introduces virtual (not persisted) generated columns,
which are now the default unless the
stored: trueoption is explicitly specified on PostgreSQL 18+.Yasuo Honda
Optimize schema dumping to prevent duplicate file generation.
ActiveRecord::Tasks::DatabaseTasks.dump_allnow tracks which schema fileshave already been dumped and skips dumping the same file multiple times.
This improves performance when multiple database configurations share the
same schema dump path.
Mikey Gough, Hartley McGuire
Add structured events for Active Record:
active_record.strict_loading_violationactive_record.sqlGannon McGibbon
Add support for integer shard keys.
Now accepts symbols as shard keys.
..
Add
ActiveRecord::Base.only_columnsSimilar in use case to
ignored_columnsbut listing columns to consider rather than the onesto ignore.
Can be useful when working with a legacy or shared database schema, or to make safe schema change
in two deploys rather than three.
Anton Kandratski
Use
PG::Connection#close_prepared(protocol level Close) to deallocateprepared statements when available.
To enable its use, you must have pg >= 1.6.0, libpq >= 17, and a PostgreSQL
database version >= 17.
Hartley McGuire, Andrew Jackson
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
Fix time attribute dirty tracking with timezone conversions.
Time-only attributes now maintain a fixed date of 2000-01-01 during timezone conversions,
preventing them from being incorrectly marked as changed due to date shifts.
This fixes an issue where time attributes would be marked as changed when setting the same time value
due to timezone conversion causing internal date shifts.
Prateek Choudhary
Skip calling
PG::Connection#cancelincancel_any_running_querywhen using libpq >= 18 with pg < 1.6.0, due to incompatibility.
Rollback still runs, but may take longer.
Yasuo Honda, Lars Kanis
Don't add
id_valueattribute alias when attribute/column with that name already exists.Rob Lewis
Remove deprecated
:unsigned_floatand:unsigned_decimalcolumn methods for MySQL.Rafael Mendonça França
Remove deprecated
:retriesoption for the SQLite3 adapter.Rafael Mendonça França
Introduce new database configuration options
keepalive,max_age, andmin_connections-- and renamepooltomax_connectionsto match.There are no changes to default behavior, but these allow for more specific
control over pool behavior.
Matthew Draper, Chris AtLee, Rachael Wright-Munn
Move
LIMITvalidation from query generation to whenlimit()is called.Hartley McGuire, Shuyang
Add
ActiveRecord::CheckViolationerror class for check constraint violations.Ryuta Kamizono
Add
ActiveRecord::ExclusionViolationerror class for exclusion constraint violations.When an exclusion constraint is violated in PostgreSQL, the error will now be raised
as
ActiveRecord::ExclusionViolationinstead of the genericActiveRecord::StatementInvalid,making it easier to handle these specific constraint violations in application code.
This follows the same pattern as other constraint violation error classes like
RecordNotUniquefor unique constraint violations andInvalidForeignKeyforforeign key constraint violations.
Ryuta Kamizono
Attributes filtered by
filter_attributeswill now also be filtered byfilter_parametersso sensitive information is not leaked.
Jill Klang
Add
connection.current_transaction.isolationAPI to check current transaction's isolation level.Returns the isolation level if it was explicitly set via the
isolation:parameteror through
ActiveRecord.with_transaction_isolation_level, otherwise returnsnil.Nested transactions return the parent transaction's isolation level.
Returns nil when no transaction
Returns explicitly set isolation level
Returns nil when isolation not explicitly set
Nested transactions inherit parent's isolation
Fix
#mergewith#oror#andand a mixture of attributes and SQL strings resulting in an incorrect query.Before:
After:
Joshua Young
Make schema dumper to account for
ActiveRecord.dump_schemaswhen dumping in:rubyformat.fatkodima
Add
:touchoption toupdate_column/update_columnsmethods.Will update :updated_at/:updated_on alongside :nice column.
Will update :updated_at/:updated_on alongside :last_ip column
Optimize Active Record batching further when using ranges.
Tested on a PostgreSQL table with 10M records and batches of 10k records, the generation
of relations for the 1000 batches was
4.8xfaster (6.8svs.1.4s), used900xless bandwidth (
180MBvs.0.2MB) and allocated45xless memory (490MBvs.11MB).Maxime Réty, fatkodima
Include current character length in error messages for index and table name length validations.
Joshua Young
Add
rename_schemamethod for PostgreSQL.T S Vallender
Implement support for deprecating associations:
With that, Active Record will report any usage of the
postsassociation.Three reporting modes are supported (
:warn,:raise, and:notify), andbacktraces can be enabled or disabled. Defaults are
:warnmode anddisabled backtraces.
Please, check the docs for further details.
Xavier Noria
PostgreSQL adapter create DB now supports
locale_providerandlocale.Bengt-Ove Hollaender
Use ntuples to populate row_count instead of count for Postgres
Jonathan Calvert
Fix checking whether an unpersisted record is
include?d in a strictlyloaded
has_and_belongs_to_manyassociation.Hartley McGuire
Add ability to change transaction isolation for all pools within a block.
This functionality is useful if your application needs to change the database
transaction isolation for a request or action.
Calling
ActiveRecord.with_transaction_isolation_level(level) {}in an around filter ormiddleware will set the transaction isolation for all pools accessed within the block,
but not for the pools that aren't.
This works with explicit and implicit transactions:
Eileen M. Uchitelle
Raise
ActiveRecord::MissingRequiredOrderErrorwhen order dependent finder methods (e.g.#first,#last) arecalled without
ordervalues on the relation, and the model does not have any order columns (implicit_order_column,query_constraints, orprimary_key) to fall back on.This change will be introduced with a new framework default for Rails 8.1, and the current behavior of not raising
an error has been deprecated with the aim of removing the configuration option in Rails 8.2.
Joshua Young
:class_nameis now invalid in polymorphicbelongs_toassociations.Reason is
:class_namedoes not make sense in those associations becausethe class name of target records is dynamic and stored in the type column.
Existing polymorphic associations setting this option can just delete it.
While it did not raise, it had no effect anyway.
Xavier Noria
Add support for multiple databases to
db:migrate:reset.Joé Dupuis
Add
affected_rowstoActiveRecord::Result.Jenny Shen
Enable passing retryable SqlLiterals to
#where.Hartley McGuire
Set default for primary keys in
insert_all/upsert_all.Previously in Postgres, updating and inserting new records in one upsert wasn't possible
due to null primary key values.
nilprimary key values passed intoinsert_all/upsert_allare now implicitly set to the default insert value specified by adapter.
Jenny Shen
Add a load hook
active_record_database_configurationsforActiveRecord::DatabaseConfigurationsMike Dalessio
Use
TRUEandFALSEfor SQLite queries with boolean columns.Hartley McGuire
Bump minimum supported SQLite to 3.23.0.
Hartley McGuire
Allow allocated Active Records to lookup associations.
Previously, the association cache isn't setup on allocated record objects, so association
lookups will crash. Test frameworks like mocha use allocate to check for stubbable instance
methods, which can trigger an association lookup.
Gannon McGibbon
Encryption now supports
support_unencrypted_data: truebeing set per-attribute.Previously this only worked if
ActiveRecord::Encryption.config.support_unencrypted_data == true.Now, if the global config is turned off, you can still opt in for a specific attribute.
ActiveRecord::Encryption.config.support_unencrypted_data = true
ActiveRecord::Encryption.config.support_unencrypted_data = false
Model generator no longer needs a database connection to validate column types.
Mike Dalessio
Allow signed ID verifiers to be configurable via
Rails.application.message_verifiersPrior to this change, the primary way to configure signed ID verifiers was
to set
signed_id_verifieron each model class:And if the developer did not set
signed_id_verifier, a verifier would beinstantiated with a secret derived from
secret_key_baseand the followingoptions:
Thus it was cumbersome to rotate configuration for all verifiers.
This change defines a new Rails config: [
config.active_record.use_legacy_signed_id_verifier][].The default value is
:generate_and_verify, which preserves the previousbehavior. However, when set to
:verify, signed ID verifiers will useconfiguration from
Rails.application.message_verifiers(specifically,Rails.application.message_verifiers["active_record/signed_id"]) togenerate and verify signed IDs, but will also verify signed IDs using the
older configuration.
To avoid complication, the new behavior only applies when
signed_id_verifier_secretis not set on a model class or any of its ancestors. Additionally,
signed_id_verifier_secretis now deprecated. If you are currently settingsigned_id_verifier_secreton a model class, you can setsigned_id_verifierinstead:
BEFORE
AFTER
BEFORE
AFTER
BEFORE
Generate and verify signed Post IDs using Post-specific configuration
AFTER
Generate and verify signed Post IDs using the unified configuration
Fall back to Post-specific configuration when verifying signed IDs
Prepend
extra_flagsin postgres'structure_loadWhen specifying
structure_load_flagswith a postgres adapter, the flagswere appended to the default flags, instead of prepended.
This caused issues with flags not being taken into account by postgres.
Alice Loeser
Allow bypassing primary key/constraint addition in
implicit_order_columnWhen specifying multiple columns in an array for
implicit_order_column, addingnilas the last element will prevent appending the primary key to orderconditions. This allows more precise control of indexes used by
generated queries. It should be noted that this feature does introduce the risk
of API misbehavior if the specified columns are not fully unique.
Issy Long
Allow setting the
schema_formatvia database configuration.Useful for multi-database setups when apps require different formats per-database.
T S Vallender
Support disabling indexes for MySQL v8.0.0+ and MariaDB v10.6.0+
MySQL 8.0.0 added an option to disable indexes from being used by the query
optimizer by making them "invisible". This allows the index to still be maintained
and updated but no queries will be permitted to use it. This can be useful for adding
new invisible indexes or making existing indexes invisible before dropping them
to ensure queries are not negatively affected.
See https://dev.mysql.com/blog-archive/mysql-8-0-invisible-indexes/ for more details.
MariaDB 10.6.0 also added support for this feature by allowing indexes to be "ignored"
in queries. See https://mariadb.com/kb/en/ignored-indexes/ for more details.
Active Record now supports this option for MySQL 8.0.0+ and MariaDB 10.6.0+ for
index creation and alteration where the new index option
enabled: true/falsecan bepassed to column and index methods as below:
Merve Taner
Respect
implicit_order_columninActiveRecord::Relation#reverse_order.Joshua Young
Add column types to
ActiveRecord::Resultfor SQLite3.Andrew Kane
Raise
ActiveRecord::ReadOnlyErrorwhen pessimistically locking with a readonly role.Joshua Young
Fix using the
SQLite3Adapter'sdbconsolemethod outside of a Rails application.Hartley McGuire
Fix migrating multiple databases with
ActiveRecord::PendingMigrationaction.Gannon McGibbon
Enable automatically retrying idempotent association queries on connection
errors.
Hartley McGuire
Add
allow_retrytosql.active_recordinstrumentation.This enables identifying queries which queries are automatically retryable on connection errors.
Hartley McGuire
Better support UPDATE with JOIN for Postgresql and SQLite3
Previously when generating update queries with one or more JOIN clauses,
Active Record would use a sub query which would prevent to reference the joined
tables in the
SETclause, for instance:This is now supported as long as the relation doesn't also use a
LIMIT,ORDERorGROUP BYclause. This was supported by the MySQL adapter for a long time.Jean Boussier
Introduce a before-fork hook in
ActiveSupport::Testing::Parallelizationto clear existingconnections, to avoid fork-safety issues with the mysql2 adapter.
Fixes #41776
Mike Dalessio, Donal McBreen
PoolConfig no longer keeps a reference to the connection class.
Keeping a reference to the class caused subtle issues when combined with reloading in
development. Fixes #54343.
Mike Dalessio
Fix SQL notifications sometimes not sent when using async queries.
In rare circumstances and under the right race condition, Active Support notifications
would no longer be dispatched after using an asynchronous query.
This is now fixed.
Edouard Chin
Eliminate queries loading dumped schema cache on Postgres
Improve resiliency by avoiding needing to open a database connection to load the
type map while defining attribute methods at boot when a schema cache file is
configured on PostgreSQL databases.
James Coleman
ActiveRecord::Coder::JSONcan be instantiatedOptions can now be passed to
ActiveRecord::Coder::JSONwhen instantiating the coder. This allows:matthaigh27
Deprecate using
insert_all/upsert_allwith unpersisted records in associations.Using these methods on associations containing unpersisted records will now
show a deprecation warning, as the unpersisted records will be lost after
the operation.
Nick Schwaderer
Make column name optional for
index_exists?.This aligns well with
remove_indexsignature as well, whereindex name doesn't need to be derived from the column names.
Ali Ismayiliov
Change the payload name of
sql.active_recordnotification for eagerloading from "SQL" to "#{model.name} Eager Load".
zzak
Enable automatically retrying idempotent
#exists?queries on connectionerrors.
Hartley McGuire, classidied
Deprecate usage of unsupported methods in conjunction with
update_all:update_allwill now print a deprecation message if a query includes eitherWITH,WITH RECURSIVEorDISTINCTstatements. Those were never supported and were ignoredwhen generating the SQL query.
An error will be raised in a future Rails release. This behavior will be consistent
with
delete_allwhich currently raises an error for unsupported statements.Edouard Chin
The table columns inside
schema.rbare now sorted alphabetically.Previously they'd be sorted by creation order, which can cause merge conflicts when two
branches modify the same table concurrently.
John Duff
Introduce versions formatter for the schema dumper.
It is now possible to override how schema dumper formats versions information inside the
structure.sqlfile. Currently, the versions are simply sorted in the decreasing order.Within large teams, this can potentially cause many merge conflicts near the top of the list.
Now, the custom formatter can be provided with a custom sorting logic (e.g. by hash values
of the versions), which can greatly reduce the number of conflicts.
fatkodima
Serialized attributes can now be marked as comparable.
A not rare issue when working with serialized attributes is that the serialized representation of an object
can change over time. Either because you are migrating from one serializer to the other (e.g. YAML to JSON or to msgpack),
or because the serializer used subtly changed its output.
One example is libyaml that used to have some extra trailing whitespaces, and recently fixed that.
When this sorts of thing happen, you end up with lots of records that report being changed even though
they aren't, which in the best case leads to a lot more writes to the database and in the worst case lead to nasty bugs.
The solution is to instead compare the deserialized representation of the object, however Active Record
can't assume the deserialized object has a working
==method. Hence why this new functionality is opt-in.Jean Boussier
Fix MySQL default functions getting dropped when changing a column's nullability.
Bastian Bartmann
SQLite extensions can be configured in
config/database.yml.The database configuration option
extensions:allows an application to load SQLite extensionswhen using
sqlite3>= v2.4.0. The array members may be filesystem paths or the names ofmodules that respond to
.to_path:Mike Dalessio
ActiveRecord::Middleware::ShardSelectorsupports granular database connection switching.A new configuration option,
class_name:, is introduced toconfig.active_record.shard_selectorto allow an application to specify the abstract connectionclass to be switched by the shard selection middleware. The default class is
ActiveRecord::Base.For example, this configuration te
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.