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

推荐订阅源

Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
小众软件
小众软件
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
量子位
博客园_首页
T
Tailwind CSS Blog
The Cloudflare Blog
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
P
Proofpoint News Feed
aimingoo的专栏
aimingoo的专栏
Recent Announcements
Recent Announcements
T
The Blog of Author Tim Ferriss
D
Docker
Microsoft Azure Blog
Microsoft Azure 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
Zeitwerk integration in Rails 6 (Beta 2)
David Heinemeier Hansson · 2019-02-22 · via Ruby on Rails: Compress the complexity of modern web apps

Friday, February 22, 2019
Posted by fxn

The second beta of Rails 6 is about to ship, and includes Zeitwerk integration.

While Rails 6 final is going to have proper documentation about it, this post will help understanding this feature meanwhile.

Highlights

  • You can now robustly use constant paths in class and module definitions:

    # Autoloading in this class' body matches Ruby semantics now.
    class Admin::UsersController < ApplicationController
      # ...
    end
    
  • All known use cases of require_dependency have been eliminated.

  • Edge cases in which the autoloaded constant depended on execution order are gone.

  • Autoloading is thread-safe in general, not just for the currently supported use cases with explicit locks like web requests. For example, you can now write multi-threaded scripts to be run by bin/rails runner and they will autoload just fine.

Also, applications get some performance benefits for the same price:

  • Autoloading a constant no longer involves walking autoload paths looking for a relative match in the file system. Zeitwerk does one single pass and autoloads everything using absolute file names. In addition, that single pass descends into subdirectories lazily, only when the namespaces are used.

  • When an application is reloaded due to changes in the file system, code in the autoload paths of engines that were loaded as gems won’t be reloaded anymore.

  • Eager loading eager loads not only the application, but also the code of any gem that is managed by Zeitwerk.

Autoloading modes

Rails 6 ships with two autoloading modes: :zeitwerk and :classic. They are set using the new configuration point config.autoloader.

Zeitwerk mode is the default in Rails 6 for CRuby, automatically enabled by

load_defaults "6.0"

in config/application.rb.

Applications can opt-out putting

config.autoloader = :classic

after the line that loads the defaults.

State of the API

While a first API for Zeitwerk mode is converging, this is still a bit exploratory right now. Please, check the current documentation if your version of Rails is newer than 6.0.0.beta2.

Autoload paths

The configuration point for autoload paths remains config.autoload_paths, and if you push by hand to ActiveSupport::Dependencies.autoload_paths during application initialization, that will also work.

require_dependency

All known use cases of require_dependency have been eliminated. In principle, you should just delete all these calls in the code base. See also the next section about STIs.

STIs

Active Record needs to have STI hierarchies fully loaded in order to generate correct SQL. Preloading in Zeitwerk was designed for this use case:

# config/initializers/preload_vehicle_sti.rb

autoloader = Rails.autoloaders.main
sti_leaves = %w(car motorbike truck)

sti_leaves.each do |leaf|
  autoloader.preload("#{Rails.root}/app/models/#{leaf}.rb")
end

By preloading the leaves of the tree, autoloading will take care of the entire hierarchy upwards following superclasses.

These files are going to be preloaded on boot, and on each reload.

Rails.autoloaders

In Zeitwerk mode, Rails.autoloaders is an enumerable that has two Zeitwerk instances called main, and once. The former is the one managing your application, and the latter manages engines loaded as gems, as well as anything in the somewhat unknown config.autoload_once_paths (whose future is not bright). Rails reloads with main, and once is there just for autoloading and eager loading, but does not reload.

Those instances are accessible respectively as

Rails.autoloaders.main
Rails.autoloaders.once

but since Rails.autoloaders is an enumerable, there won’t be too many use cases for direct access, probably.

Inspecting autoloaders activity

If you want to see the autoloaders working, you can throw

Rails.autoloaders.logger = method(:puts)

to config/application.rb after the framework defaults have been set. In addition to a callable, Rails.autoloaders.logger= accepts also anything that responds to debug with arity 1, like regular loggers do.

If you want to see the activity of Zeitwerk for all instances in memory (both Rails’ and others that might be managing gems), you can set

Zeitwerk::Loader.default_logger = method(:puts)

at the top of config/application.rb, before Bundle.require.

Backwards incompatibility

  • For files below the standard concerns directories (like app/models/concerns), Concerns cannot be a namespace. That is, app/models/concerns/geolocatable.rb is expected to define Geolocatable, not Concerns::Geolocatable.

  • Once the application has booted, autoload paths are frozen.

  • Directories in ActiveSupport::Dependencies.autoload_paths that do not exist on boot are ignored. We are referring here to the actual elements of the array only, not to their subdirectories. New subdirectories of autoload paths that existed at boot are picked up just fine as always. (This may change for final.)

  • A file that defines a class or module that acts as a namespace, needs to define the class or module using the class and module keywords. For example, if you have app/models/hotel.rb defining the Hotel class, and app/models/hotel/pricing.rb defining a mixin for hotels, the Hotel class must be defined with class, you cannot do Hotel = Class.new { ... } or Hotel = Struct.new { ... } or anything like that. Those idioms are fine in classes and modules that do not act as namespaces.

  • A file should define only one constant in its namespace (but can define inner ones). So, if app/models/foo.rb defines Foo and also Bar, Bar won’t be reloaded, but reopened when Foo is reloaded. This is strongly discouraged in classic mode anyway though, the convention is to have one single main constant matching the file name. You can have inner constants, so Foo may define an auxiliary internal class Foo::Woo.