This Week in Rails

December 13, 2025

'Tis the season for contributing to Rails

Hi, it’s Claudio Baccigalupo. So many improvements to the Rails codebase this week!
If you are also looking to contribute, there are several documentation PRs open for community review. Oh and we also have some Rails World 2026 updates! And now, let’s get to the PR-esents 🎁

ActiveStorage immediate variants
Attachment variants gain the process: :immediately option:
has_one_attached :avatar_with_immediate do |attachable|
  attachable.variant :thumb, resize_to_limit: [4, 4], process: :immediately
end

def validate_avatar_dimensions
  if avatar.metadata[:width] < 200 || avatar.metadata[:height] < 200
    errors.add(:avatar, "must be at least 200x200")
  end
end


Immediate variant processing and blob analysis use local files directly instead of re-downloading after upload. Applies when attaching uploadable io, not when attaching an existing Blob.

Deprecate PreviewImageJob
PreviewImageJob is no longer called by Rails and is now officially deprecated.

Add SVG renderer
Define a to_svg method on your model and render SVG directly in your controller:
respond_to do |format|
  format.html
  format.svg { render svg: @page }
end


Yield the transaction for Model#with_lock
ActiveRecord::Base#with_lock now yields the transaction the same way that transaction does:
person.with_lock do |transaction|
  transaction.after_commit { puts "hello" }
end


Enable debug events by default
The use case is primarily for test or when using framework libraries outside of Rails. In these cases, we shouldn’t assume debug events need to be obfuscated.

Respect config.log_level to emit debug events
Using RAILS_LOG_LEVEL=debug in production will now work as expected.

Add structured event for open redirects
Applications with config.action_controller.action_on_open_redirect = :notify automatically get a structured log event rather than having to configure their own subscriber to the Active Support Notification.

Fix ERB strict locals spanning multiple lines
ERB partials with the locals: magic comment on multiple lines will now work without issues, even when the closing parenthesis is on a new line:
<%# locals: (arg_1:,
             arg_2: nil,
             arg_3: []) %>


Combine tag content supplied via both parameter and block
A snuppet of code such as tag.div("Hello ") { "World" } would just return <div>World</div>. With this fix, it’s going to return <div>Hello World</div>.

Allow schema_dump configuration to be an absolute path
ActiveRecord::Tasks::DatabaseTasks.schema_dump_path now supports absolute paths to specifyi the schema dump database configuration.

Make flaky parallel tests easier to diagnose
Rails assigns tests to workers in round-robin order so the same --seed and worker count will result in the same sequence of tests running on each worker increasing the odds of reproducing test failures caused by test interdependence.

Register file extensions for rails stats
Rails::CodeStatistics gains a register_extension method to for adding file extensions to be included when generating code analytics with rails stats.

Fix Inflections.instance_or_fallback to properly find :en fallback
The pluralize helper will now respect fallback to :en for custom locales.

Wrap console command with an executor by default
This can be disabled with -w or --skip_executor, same as runner.

Extract ActionText::Editor base class and ActionText::TrixEditor adapter
The aim is to provide a single, extensible entrypoint for third-party editors to integrate with Action Text.

Validate RemoteImage URLs
Within Action Text, RemoteImage.from_node now validates the URL before creating a RemoteImage object in order to avoid a potential ActionView::Template::Error when the image is rendered.

We had 32 contributors to the Rails codebase this past week. You can view the whole list of changes here. Until next time!

About This Week in Rails

Your weekly inside scoop of interesting commits, pull requests and more from Rails.