What Is New in Ruby on Rails 7.1
| Category | Highlights |
|---|---|
| New Features | Dockerfile generation, ActiveRecord::Base.normalizes, ActiveRecord::Base.generates_token_for, perform_all_later, composite primary keys, Trilogy adapter, ActiveSupport::MessagePack, config.autoload_lib, async query methods, strict locals, response.parsed_body enhancements |
| Improvements | Bulk job enqueuing optimization, async query API, pattern-matching support for JSON/HTML responses, ActionView::TestCase.register_parser, enhanced lib autoloading |
| Deprecations | bin/rails secrets:setup removed, default X-Download-Options header removed, Rails.application.secrets deprecated, secrets:show/edit deprecated, Rails::Generators::Testing::Behaviour renamed |
| Breaking Changes | Removal of bin/rails secrets:setup command and X-Download-Options header may break legacy scripts and security policies |
How can I get a ready-to-run Docker setup for a new Rails 7.1 app?
Rails 7.1 now scaffolds Dockerfiles automatically when you run rails new.
- The generated
Dockerfilebuilds a minimal Ruby image with your app code. - A
docker-compose.ymlis also added for easy service orchestration. - These files are intended for production deployment, not for local development.
# Build and run the container
docker build -t myapp .
docker volume create app-storage
docker run --rm -it -v app-storage:/rails/storage -p 3000:3000 \
--env RAILS_MASTER_KEY=<your-config-master-key> myapp
# Open a console inside the container
docker run --rm -it -v app-storage:/rails/storage \
--env RAILS_MASTER_KEY=<your-config-master-key> myapp console
For multi-platform images, use docker buildx as shown in the generated README.
What new ActiveRecord helpers help keep data clean and secure in Rails 7.1?
Rails 7.1 introduces normalizes and generates_token_for macros on ActiveRecord::Base.
normalizesautomatically sanitizes attribute values on assignment and when used in queries.generates_token_forcreates purpose-specific, expirable tokens that can embed record data for one-time actions.
class User < ApplicationRecord
normalizes :email, with: ->(e){ e.strip.downcase }
normalizes :phone, with: ->(p){ p.delete("^0-9").delete_prefix("1") }
generates_token_for :password_reset, expires_in: 15.minutes do
password_salt&.last(10)
end
end
# Normalization in action
User.create(email: " [email protected]\n").email # => "[email protected]"
# Token usage
token = user.generate_token_for(:password_reset)
User.find_by_token_for(:password_reset, token) # => user
These helpers reduce boilerplate and make security-critical logic declarative.
How do I enqueue a batch of background jobs with a single call in Rails 7.1?
The new ActiveJob.perform_all_later method lets you push many jobs at once without triggering per-job callbacks.
- Pass an array of job instances or a list of arguments.
- Adapters that support
enqueue_all(e.g., Sidekiq) will use bulk push for optimal performance. - A distinct
enqueue_all.active_jobevent is emitted for monitoring.
# Enqueue two jobs directly
ActiveJob.perform_all_later(MyJob.new("hello", 42), MyJob.new("world", 0))
# Enqueue a dynamic batch
user_ids = User.pluck(:id)
jobs = user_ids.map { |id| NotifyUserJob.new(user_id: id) }
ActiveJob.perform_all_later(jobs)
This method is especially useful for data-migration scripts or bulk email campaigns.
Which async query methods and composite primary key support should I adopt in Rails 7.1?
Rails 7.1 adds a family of async_* query helpers and native composite primary key handling.
async_count,async_sum,async_average, etc., return anActiveRecord::Promisethat resolves when you callvalue.- Composite primary keys are inferred from the schema and work with
#reload,#update, and association foreign keys via thequery_constraintsmacro.
# Asynchronous count
promise = Post.where(published: true).async_count
# Do other work ...
published = promise.value # => integer count
# Composite primary key example
class TravelRoute < ApplicationRecord
query_constraints :origin, :destination
end
class TravelRouteReview < ApplicationRecord
belongs_to :travel_route,
query_constraints: [:travel_route_origin, :travel_route_destination]
end
Use async helpers for heavy aggregates and composite keys for join tables that lack a single id column.
Frequently Asked Questions
Do I need to change my existing Docker workflow when upgrading to Rails 7.1?
Most teams can keep their current Docker commands; the generated Dockerfile is an optional starter for new projects.
How does the normalizes macro interact with model validations?
Normalization runs before validations, so cleaned values are what the validators see.
Can perform_all_later be used with the Sidekiq adapter?
Yes, Sidekiq supports enqueue_all, so perform_all_later will push jobs in bulk.
Are async query methods safe inside a database transaction?
Async methods execute outside the transaction scope, so they should be called after the transaction commits.
What should I replace the removed bin/rails secrets:setup command with?
Use rails credentials:edit to manage encrypted secrets instead of the old secrets:setup command.
How do I enable MessagePack serialization for Rails cookies?
Set config.action_dispatch.cookies_serializer = :message_pack in the application configuration.