惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MongoDB | Blog
MongoDB | Blog
B
Blog
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
博客园 - Franky
V
V2EX
IT之家
IT之家
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
F
Fortinet All Blogs
I
InfoQ
云风的 BLOG
云风的 BLOG
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog

Ruby on Rails: Compress the complexity of modern web apps

Safer to_i coercion, custom to_fs formats, and more! This Week in Rails: May 16, 2026 This Week in Rails: May 8, 2026 This Week in Rails: May 1, 2026 Active Record gets better every week Great big Rails World 2026 update: CFP, Corporate Support tickets, workshops Query command for database queries and more Explicit query: and body: kwargs for integration tests and more! Speedup ActiveRecord::LogSubscriber#sql_color and more! This Week in Rails: March 27, 2026 Rails Versions 8.0.5 and 8.1.3 have been released! Rails Versions 7.2.3.1, 8.0.4.1, and 8.1.2.1 have been released! This Week in Rails: March 20, 2026 Validate URI scheme in Action Text and more This Week in Rails: March 6, 2026 Planning Center is the newest Rails Foundation Contributing member Action Text gets Markdown conversion, editor links in devcontainers, and more! BARRA seeks Rails developer Joe Agliozzo is looking for a Rails developer The rise of lighttpd as the alternative web server When longer is better and more is more Snowdevil: First e-tailer on Rails Natural selection for frameworks in Ruby vs Java Address book tutorial in Portuguese Becoming a better programmer with Rails 10 Things Every Java Programmer Should Know About Ruby Really Getting Started in Rails Off the Treadmill, Onto the Rails Rails 0.9.5: A world of fixes and tweaks Rich clients with Rails and XUL
Rails 8.1: Job continuations, structured events, local CI
David Heinemeier Hansson · 2025-10-22 · via Ruby on Rails: Compress the complexity of modern web apps

Wednesday, October 22, 2025
Posted by rafaelfranca

Rails 8.1 represents the work of over 500 contributors across 2500 commits since our last major release. After some weeks of people trying the betas and releases candidates, we are excited to share the final release.

This release shows the stability of Rails, with applications like Shopify and HEY running it in production already for months.

Here are a few of the highlights:

Active Job Continuations

Long-running jobs can now be broken into discrete steps that allow execution to continue from the last completed step rather than the beginning after a restart. This is especially helpful when doing deploys with Kamal, which will only give job-running containers thirty seconds to shut down by default.

Example:

class ProcessImportJob < ApplicationJob
  include ActiveJob::Continuable

  def perform(import_id)
    @import = Import.find(import_id)

    # block format
    step :initialize do
      @import.initialize
    end

    # step with cursor, the cursor is saved when the job is interrupted
    step :process do |step|
      @import.records.find_each(start: step.cursor) do |record|
        record.process
        step.advance! from: record.id
      end
    end

    # method format
    step :finalize
  end

  private
    def finalize
      @import.finalize
    end
end

Active Job Continuations was lead by Donal McBreen from 37signals.

Structured Event Reporting

The default logger in Rails is great for human consumption, but less ideal for post-processing. The new Event Reporter provides a unified interface for producing structured events in Rails applications:

Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")

It supports adding tags to events:

Rails.event.tagged("graphql") do
  # Event includes tags: { graphql: true }
  Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
end

As well as context:

# 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:

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

Structured Event Reporting was lead by Adrianna Chang from Shopify.

Local CI

Developer machines have gotten incredibly quick with loads of cores, which make them great local runners of even relatively large test suites. The HEY test suite of over 30,000 assertions used to take over 10 minutes to run in the cloud when counting coordination, image building, and parallelized running. Now it runs locally on a Framework Desktop AMD Linux machine in just 1m 23s and an M4 Max in 2m 22s.

This makes getting rid of a cloud-setup for all of CI not just feasible but desirable for many small-to-mid-sized applications, and Rails has therefore added a default CI declaration DSL, which is defined in config/ci.rb and run by bin/ci. It looks like this:

CI.run do
  step "Setup", "bin/setup --skip-server"
  step "Style: Ruby", "bin/rubocop"

  step "Security: Gem audit", "bin/bundler-audit"
  step "Security: Importmap vulnerability audit", "bin/importmap audit"
  step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
  step "Tests: Rails", "bin/rails test"
  step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant"

  # Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.
  if success?
    step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
  else
    failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
  end
end

The optional integration with gh ensures that PRs must be signed off by a passing CI run in order to be eligible to be merged.

The local CI work was lead by Jeremy Daer from 37signals.

Markdown Rendering

Markdown has become the lingua franca of AI, and Rails has embraced this adoption by making it easier to respond to markdown requests and render them directly:

class Page
  def to_markdown
    body
  end
end

class PagesController < ActionController::Base
  def show
    @page = Page.find(params[:id])

    respond_to do |format|
      format.html
      format.md { render markdown: @page }
    end
  end
end

Command-line Credentials Fetching

Kamal can now easily grab its secrets from the encrypted Rails credentials store for deploys. This makes it a low-fi alternative to external secret stores that only needs the master key available to work:

# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)

Work by Matthew Nguyen from Shopify and Jean Boussier.

Deprecated Associations

Active Record associations can now be marked as being deprecated:

class Author < ApplicationRecord
  has_many :posts, deprecated: true
end

With that, usage of the posts association will be reported. This includes explicit API calls like

author.posts
author.posts = ...

and others, as well as indirect usage like

author.preload(:posts)

usage via nested attributes, and more.

Three reporting modes are supported (:warn, :raise, and :notify), and backtraces can be enabled or disabled, though you always get the location of the reported usage regardless. Defaults are :warn mode and disabled backtraces.

Upstreamed by Xavier Noria while consulting for Gusto.

Registry-Free Kamal Deployments

Kamal no longer needs a remote registry, like Docker Hub or GHCR, to do basic deploys. By default, Kamal 2.8 will now use a local registry for simple deploys. For large-scale deploys, you’ll still want to use a remote registry, but this makes it easier to get started and see your first Hello World deployment in the wild.

And Everything Else

With 2500 commits since the last release, there’s a ton of fixes, minor features, and improvements included in Rails 8.1 as well. Please have a look at the CHANGELOG files for details.