Active Support
-
Remove deprecated passing a Time object to
Time#since
.Rafael Mendonça França
-
Remove deprecated
Benchmark.ms
method. It is now defined in thebenchmark
gem.Rafael Mendonça França
-
Remove deprecated addition for
Time
instances withActiveSupport::TimeWithZone
.Rafael Mendonça França
-
Remove deprecated support for
to_time
to preserve the system local time. It will now always preserve the receiver
timezone.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_reported
error messages.The event name in failure messages now uses
.inspect
(e.g.,name: "user.created"
)
to matchassert_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.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
NameError
whenclass_attribute
is defined on instance singleton classes.Previously, calling
class_attribute
on an instance's singleton class would raise
aNameError
when accessing the attribute through the instance.object = MyClass.new object.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.class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber def notification(event) emit_event("my.notification", data: 1) end end
Adrianna Chang
-
ActiveSupport::FileUpdateChecker
does not depend onTime.now
to prevent unecessary reloads with time travel test helpersJan Grodowski
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).
has_secure_password reset_token: { expires_in: 1.hour }
Jevin Sew, Abeid Ahmed
Active Record
-
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 thestored: true
option is explicitly specified on PostgreSQL 18+.create_table :users do |t| t.string :name t.virtual :lower_name, type: :string, as: "LOWER(name)", stored: false t.virtual :name_length, type: :integer, as: "LENGTH(name)" end
Yasuo Honda
-
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.Mikey Gough, Hartley McGuire
-
Add structured events for Active Record:
active_record.strict_loading_violation
active_record.sql
Gannon McGibbon
-
Add support for integer shard keys.
# Now accepts symbols as shard keys. ActiveRecord::Base.connects_to(shards: { 1: { writing: :primary_shard_one, reading: :primary_shard_one }, 2: { writing: :primary_shard_two, reading: :primary_shard_two}, }) ActiveRecord::Base.connected_to(shard: 1) do # .. end
Nony Dutton
-
Add
ActiveRecord::Base.only_columns
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
incancel_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
Action View
-
The BEGIN template annotation/comment was previously printed on the same line as the following element. We now insert a newline inside the comment so it spans two lines without adding visible whitespace to the HTML output to enhance readability.
Before:
<!-- BEGIN /Users/siaw23/Desktop/rails/actionview/test/fixtures/actionpack/test/greeting.html.erb --><p>This is grand!</p>
After:
<!-- BEGIN /Users/siaw23/Desktop/rails/actionview/test/fixtures/actionpack/test/greeting.html.erb --><p>This is grand!</p>
Emmanuel Hayford
-
Add structured events for Action View:
action_view.render_template
action_view.render_partial
action_view.render_layout
action_view.render_collection
action_view.render_start
Gannon McGibbon
-
Fix label with
for
option not getting prefixed by formnamespace
valueAbeid Ahmed, Hartley McGuire
-
Add
fetchpriority
to Link headers to match HTML generated bypreload_link_tag
.Guillermo Iguaran
Action Pack
-
Add link-local IP ranges to
ActionDispatch::RemoteIp
default proxies.Link-local addresses (
169.254.0.0/16
for IPv4 andfe80::/10
for IPv6)
are now included in the default trusted proxy list, similar to private IP ranges.Adam Daniels
-
remote_ip
will no longer ignore IPs in X-Forwarded-For headers if they
are accompanied by port information.Duncan Brown, Prevenios Marinos, Masafumi Koba, Adam Daniels
-
Add
action_dispatch.verbose_redirect_logs
setting that logs where redirects were called from.Similar to
active_record.verbose_query_logs
andactive_job.verbose_enqueue_logs
, this adds a line in your logs that shows where a redirect was called from.Example:
Redirected to http://localhost:3000/posts/1 ↳ app/controllers/posts_controller.rb:32:in `block (2 levels) in create'
Dennis Paagman
-
Add engine route filtering and better formatting in
bin/rails routes
.Allow engine routes to be filterable in the routing inspector, and
improve formatting of engine routing output.Before:
> bin/rails routes -e engine_only No routes were found for this grep pattern. For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html.
After:
> bin/rails routes -e engine_only Routes for application: No routes were found for this grep pattern. For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html. Routes for Test::Engine: Prefix Verb URI Pattern Controller#Action engine GET /engine_only(.:format) a#b
Dennis Paagman, Gannon McGibbon
-
Add structured events for Action Pack and Action Dispatch:
action_dispatch.redirect
action_controller.request_started
action_controller.request_completed
action_controller.callback_halted
action_controller.rescue_from_handled
action_controller.file_sent
action_controller.redirected
action_controller.data_sent
action_controller.unpermitted_parameters
action_controller.fragment_cache
Adrianna Chang
-
URL helpers for engines mounted at the application root handle
SCRIPT_NAME
correctly.Fixed an issue where
SCRIPT_NAME
is not applied to paths generated for routes in an engine
mounted at "/".Mike Dalessio
-
Update
ActionController::Metal::RateLimiting
to support passing method names to:by
and:with
class SignupsController < ApplicationController rate_limit to: 10, within: 1.minute, with: :redirect_with_flash private def redirect_with_flash redirect_to root_url, alert: "Too many requests!" end end
Sean Doyle
-
Optimize
ActionDispatch::Http::URL.build_host_url
when protocol is included in host.When using URL helpers with a host that includes the protocol (e.g.,
{ host: "https://example.com" }
),
skip unnecessary protocol normalization and string duplication since the extracted protocol is already
in the correct format. This eliminates 2 string allocations per URL generation and provides a ~10%
performance improvement for this case.Joshua Young, Hartley McGuire
-
Allow
action_controller.logger
to be disabled by setting it tonil
orfalse
instead of always defaulting toRails.logger
.Roberto Miranda
Active Job
-
Add structured events for Active Job:
active_job.enqueued
active_job.bulk_enqueued
active_job.started
active_job.completed
active_job.retry_scheduled
active_job.retry_stopped
active_job.discarded
active_job.interrupt
active_job.resume
active_job.step_skipped
active_job.step_started
active_job.step
Adrianna Chang
Action Mailer
-
Add structured events for Action Mailer:
action_mailer.delivered
action_mailer.processed
Gannon McGibbon
Action Cable
- No changes.
Active Storage
-
Add structured events for Active Storage:
active_storage.service_upload
active_storage.service_download
active_storage.service_streaming_download
active_storage.preview
active_storage.service_delete
active_storage.service_delete_prefixed
active_storage.service_exist
active_storage.service_url
active_storage.service_mirror
Gannon McGibbon
-
Allow analyzers and variant transformer to be fully configurable
# ActiveStorage.analyzers can be set to an empty array: config.active_storage.analyzers = [] # => ActiveStorage.analyzers = [] # or use custom analyzer: config.active_storage.analyzers = [ CustomAnalyzer ] # => ActiveStorage.analyzers = [ CustomAnalyzer ]
If no configuration is provided, it will use the default analyzers.
You can also disable variant processor to remove warnings on startup about missing gems.
config.active_storage.variant_processor = :disabled
zzak, Alexandre Ruban
Action Mailbox
- No changes.
Action Text
-
De-couple
@rails/actiontext/attachment_upload.js
fromTrix.Attachment
Implement
@rails/actiontext/index.js
with adirect-upload:progress
event
listeners andPromise
resolution.Sean Doyle
-
Capture block content for form helper methods
<%= rich_textarea_tag :content, nil do %> <h1>hello world</h1> <% end %> <!-- <input type="hidden" name="content" id="trix_input_1" value="<h1>hello world</h1>"/><trix-editor … --> <%= rich_textarea :message, :content, input: "trix_input_1" do %> <h1>hello world</h1> <% end %> <!-- <input type="hidden" name="message[content]" id="trix_input_1" value="<h1>hello world</h1>"/><trix-editor … --> <%= form_with model: Message.new do |form| %> <%= form.rich_textarea :content do %> <h1>hello world</h1> <% end %> <% end %> <!-- <form action="/messages" accept-charset="UTF-8" method="post"><input type="hidden" name="message[content]" id="message_content_trix_input_message" value="<h1>hello world</h1>"/><trix-editor … -->
Sean Doyle
-
Generalize
:rich_text_area
Capybara selectorPrepare for more Action Text-capable WYSIWYG editors by making
:rich_text_area
rely on the presence of[role="textbox"]
and
[contenteditable]
HTML attributes rather than a<trix-editor>
element.Sean Doyle
Railties
-
Suggest
bin/rails action_text:install
from Action Dispatch error pageSean Doyle
-
Remove deprecated
STATS_DIRECTORIES
.Rafael Mendonça França
-
Remove deprecated
bin/rake stats
command.Rafael Mendonça França
-
Remove deprecated
rails/console/methods.rb
file.Rafael Mendonça França
-
Don't generate system tests by default.
Rails scaffold generator will no longer generate system tests by default. To enable this pass
--system-tests=true
or generate them withbin/rails generate system_test name_of_test
.Eileen M. Uchitelle
-
Optionally skip bundler-audit.
Skips adding the
bin/bundler-audit
&config/bundler-audit.yml
if the gem is not installed whenbin/rails app:update
runs.Passes an option to
--skip-bundler-audit
when new apps are generated & adds that same option to the--minimal
generator flag.Jill Klang
-
Show engine routes in
/rails/info/routes
as well.Petrik de Heus
-
Exclude
asset_path
configuration from Kamaldeploy.yml
for API applications.API applications don't serve assets, so the
asset_path
configuration indeploy.yml
is not needed and can cause 404 errors on in-flight requests. The asset_path is now
only included for regular Rails applications that serve assets.Saiqul Haq
-
Reverted the incorrect default
config.public_file_server.headers
config.If you created a new application using Rails
8.1.0.beta1
, make sure to regenerate
config/environments/production.rb
, or to manually edit theconfig.public_file_server.headers
configuration to just be:# Cache assets for far-future expiry since they are all digest stamped. config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
Jean Boussier
Guides
- No changes.