Ruby on Rails - May 2025
Hey everyone — Sajjad Umar here with the May edition of Ruby on Rails Monthly! ☀️
The year’s moving fast, and May brings more momentum across the Rails ecosystem. From community projects and updates to thoughtful articles and improvements in the framework, there's plenty worth your attention. Let’s dive into what’s been happening in the world of Rails this month!
Our Proud Partners
Rails World - Sold Out
It was lightning quick! Rails World sold out fast this year, but don’t worry — all sessions will be recorded and shared on YouTube. The Opening and Closing Keynotes will be available right away, with the rest of the talks following shortly after.
The New Rails Application Template Guide PR is open for Review
The goal of this PR is to update the Rails Application Template Guide. In the process of updating this guide, it made sense to merge its content into the Generators Guide, which already had a section about Templates. The scope of this PR is the Rails Application Template sections (the rest of the existing Generators Guide will be updated later on).
Add your valuable review here.
New Rails Event - Rails at Scale
A gathering for engineers solving big challenges with Ruby on Rails.
Rails at Scale is a day of open discussion about scaling Rails applications. It’s where engineers working on high-performance, high-traffic systems can connect and exchange insights, best practices, and hard-earned lessons.
The Rails at Scale Summit will take place the day before Rails World on Sept 3. It is an all day event, followed by a happy hour for attendees.
Get all the details here.
Buzzsprout - Rails World Podcast Program
Buzzsprout is once again sponsoring the Rails World Podcast program!
Podcasts chosen for this program will have access to a dedicated, podcast recording booth at Rails World and access to 800+ attendees and 24 speakers to interview for their show. The podcasters agree to record at least one episode on site including a shoutout during the episode to Buzzsprout as a sponsor.
If you're interested in applying for the Podcast Program, please fill out the form here.
Defer ActiveJob enqueue callbacks until after commit when enqueue_after_transaction_commit enabled
Active Job’s around_enqueue callbacks are deferred until after the database transaction commits, but only when the enqueue_after_transaction_commit option is enabled. This ensures that job enqueue logic, including handling Sidekiq connectivity issues, occurs only after a successful transaction commit, preventing premature job execution.
Added affected_rows to ActiveRecord::Result
For database adapters that do not support insert RETURNING, the result for insert_all and upsert_all does not provide any information on the rows that has been affected. Adding affected_rows to the result allows this information to be accessed similar to the return value of other bulk operations (like delete_all and update_all).
This PR adds an affected_rows reader for the result. Database specific adapters would provide the value as a keyword arg when the result is initialized (often in cast_result).
Droped vendored Trix files in favor of the action_text-trix gem
Currently Trix is vendored in Rails, meaning that when bug fixes or security patches are released, application developers cannot easily update to the latest Trix without waiting for a Rails release.
This PR drops vendored Trix files in favor of the action_text-trix gem, which itself vendors just the Trix assets. This gem will be maintained by the Trix maintainers at 37signals.
Only load from cgi what is required for Ruby 3.5 compatibility
In Ruby 3.5 most of the cgi gem will be removed (bundled gem). Only the various escape/unescape methods will be retained by default, which is luckily the only ones that rails actually uses.
Practically, requiring cgi will still work, it just emits a warning (and other things like CGI::Cookie obviously won't be available).
Here is more detail on this topic and you can check the PR here.
Added support for Cache-Control request directives
This Pull Request changes the following:
This enhancement allows Rails applications to better integrate with HTTP caching mechanisms and provides more control over how requests interact with cached resources.
Enabled passing retryable SqlLiterals to #where
Previously, retryable SqlLiterals passed to #where would lose their retryability because both #build_where_clause and WhereClause would wrap them in non-retryable SqlLiterals.
To fix this problem, this commit updates #build_where_clause to check for SqlLiterals and updates WhereClause to assume that any predicate passed in will already be wrapped.
Use TRUE and FALSE for more SQLite queries
A previous commit updated the SQLite Arel visitor to use TRUE and FALSE literals instead of 1 and 0 for True and False Arel Nodes.
This commit takes the change further by making SQLite quote true and false values as TRUE and FALSE instead of 1 and 0. This additionally required adding support for DEFAULT TRUE and DEFAULT FALSE SQLite column definitions (which is more correct in case someone made TRUE or FALSE the default value of a column using default: -> { "TRUE" }, etc).
Made the executor hooks in AR::QueryCache private
API docs show the executor hooks in ActiveRecord::QueryCache and their installer. These should be private, they are not supposed to be callable or overridden by external code.
The patch also groups the hooks to ease making sense of this class, just like the connection pool does.
Rescued connection related errors in MemCacheStore#read_multi_entries
This Pull Request has been created because Rails is not managing network blips when reading multiple values from Memcached.
Recommended by LinkedIn
This Pull Request changes MemCacheStore to swallow various connection exceptions when reading multiple values. The class already does this for every other read and write method, read_multi_entries was the only one not implementing the behavior.
selenium-webdriver 4.32.0 is now supported
This pull request supports selenium-webdriver 4.32.0 that sets remote.active-protocols => 1.
Implemented ability to opt out of parallel database hooks
Preivously, you could append your own hooks to parallel tests, but there was no way to skip the Rails database parallelization hooks. There may be cases where you want to implement your own database handling, so this allows you to implement all of that in a parallelize_setup block without having Rails create any databases for you.
To skip Rails database parallelization when running parallel tests you can set it in the parallelize caller:
parallelize(workers: 10, parallelize_databases: false)
Or in your application config:
config.active_support.parallelize_test_databases = false
This is set to true by default.
Set default for primary keys in insert_all/upsert_all
In MySQL/SQLite, when a null value for a primary key gets passed into an insert, the auto increment will automatically set the value. However, in Postgres, a null value for a primary key will raise a PG::NotNullViolation. This limits the ability to update and insert new records in one bulk upsert.
Book.upsert_all [
{ id: 1, name: "New edition" },
{ id: nil, name: "New edition 2" },
{ id: nil, name: "New edition 3" },
]
When determining the value to insert, this PR set the value to default_insert_value if the attribute was the primary key and the value is nil. This would translate to Arel.sql("DEFAULT") for Postgres but remain nil for some adapters like MySQL as primary key columns are auto increment columns.
Added public API for before_fork_hook in parallel testing
Previously there was no public API implemented for the before_fork_hook when using parallel testing. Applications may want to perform actions before fork, and we should provide an API for it like we did for setup and teardown.
This PR adds the public API for before_fork_hook.
Added --reset option to bin/setup
DHH-This makes it easier to zero out a database and load seeds during development.
Added assert_in_body/assert_not_in_body
DHH - As a simple encapsulation of checking a response body for a piece of text without having to go through a heavy-duty DOM operation.
Added a load hook for ActiveRecord::DatabaseConfigurations
Rails does not offer a way to use an initializer to register a database config handler before database tasks are defined.
Ensure all railties tests require strict_warnings
This prevents warnings from getting merged without being notified about them.
Pass existing connection to #arel in #to_sql
Improves the performance of update_all and delete_all queries that include GROUP BY or HAVING.
Action Cable: Allow setting nil as subscription connection identifier for Redis
If you use Google Cloud Memorystore or another platform that blocks the command CLIENT SETNAME in Redis, previously you needed to overwrite the Redis connection factory. With this change, you can set the id of the connection to nil in the configuration.
Improve leap years counting performance in distance_of_time_in_words
The distance_of_time_in_words function can lead to a denial of service if the given from_time and to_time arguments are far apart. This PR replaces the concerning code with a constant calculation.
Allowed to configure maximum cache key sizes
This pull request adds the possibility to configure the maximum size for cache keys. 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::RedisCacheStore allowed up to 1kb cache keys before truncation, which is now reduced to 250 bytes. This is how you can set it:
config.cache_store = :redis_cache_store, { max_key_size: 64 }
This Article is published on:
And that is it for this month. I will be back with more updates next month!
Keep supporting ✌🏻