Ruby on Rails
Rails 6.1 to 7 Upgrade Guide: Zeitwerk, Cookie Rotation and the Path to 7.2
Many business applications still run on Rails 6.1, which no longer receives security fixes. Getting to a supported version means passing through 7.0, 7.1 and 7.2, and the first of those steps contains the changes that most often break production: the autoloader, the digest used for cookies and cache keys, and the JavaScript tooling. This guide covers what to prepare and the mistakes that log users out or empty caches.
The version path and Ruby requirements
Upgrade one minor version at a time: 6.1 to 7.0, then 7.1, then 7.2. Rails 7.0 and 7.1 require Ruby 2.7.0 or newer, and Rails 7.2 requires Ruby 3.1.0 or newer, so plan a Ruby upgrade before the last step and deploy it on its own.
Before touching the Gemfile, make deprecation warnings fail the test suite on 6.1 and fix them. Every warning you leave behind becomes an error a version later.
Zeitwerk is mandatory
Rails 7.0 removes the classic autoloader: applications must run in zeitwerk mode, and the config.autoloader setter no longer exists. Apps that already switched in 6.x usually have nothing to do. Apps still on classic mode should switch first, on 6.1, and run bin/rails zeitwerk:check until it passes.
The usual problems are file names that do not match the constant they define, acronyms such as API or HTML that need inflection rules, and code in lib that relied on loose naming. Fix them while still on 6.1, where the change is isolated.
SHA256 for cookies and cache keys
Rails 7.0 changes the default digest of the key generator from SHA1 to SHA256. That key generator signs and encrypts cookies, so enabling the new default without preparation invalidates existing sessions and logs every user out.
The official approach is a cookie rotator: keep reading cookies created with SHA1 while writing new ones with SHA256, and remove the rotator after the old cookies have expired. The digest used by ActiveSupport::Digest also moves to SHA256, which changes cache keys and ETags, so expect a cold cache right after the switch and schedule it outside peak hours.
Other changes that bite
These are smaller, but they show up in real applications.
- button_to now renders a patch form when you pass a persisted Active Record object; check buttons that expected a POST.
- request.content_type now returns the full header including the charset; use media_type when you only need the MIME type.
- Sprockets becomes optional: declare sprockets-rails explicitly if your asset pipeline depends on it.
- Webpacker is retired; existing apps can keep it during the upgrade, but plan the move to jsbundling-rails or importmap-rails as a separate project.
A safe rollout
Keep config.load_defaults on the old version, upgrade the framework, and enable the new defaults one at a time from the generated new_framework_defaults file, deploying between changes. Treat the cookie digest and cache digest as their own deploys with monitoring. Once the app is stable on 7.2, the next step is our Rails 7 to 8 guide.
Key takeaways
- Go 6.1 → 7.0 → 7.1 → 7.2, and upgrade Ruby to 3.1+ before 7.2.
- Switch to Zeitwerk on 6.1 and run bin/rails zeitwerk:check.
- Rotate cookies before adopting SHA256 or every user gets logged out.
- Expect cache keys to change and enable new defaults one by one.
Related
Want to review your case with context?
Share the codebase, workflow, or systems involved and the result you need. We will use the call to decide a practical next step.