Migrate every Rails 6.x service to Rails 7.1.
For each repository:
1. Update `Gemfile`:
- `gem "rails", "~> 7.1.0"`
- Bump `sprockets-rails`, `puma`, `bootsnap` to Rails 7-compatible versions
- Replace EOL gems: `paperclip` → ActiveStorage, `protected_attributes` → strong params
2. Apply the framework-default diffs that `bin/rails app:update` would generate
for Rails 7.1 to `config/application.rb`, `config/environments/*.rb`, and
`config/initializers/new_framework_defaults_7_1.rb`.
3. Switch autoloader to Zeitwerk:
- Set `config.autoloader = :zeitwerk` in `config/application.rb`
- Rename files and classes so they match Zeitwerk's naming convention
(snake_case filenames matching CamelCase constants, one constant per file)
4. Replace deprecated APIs:
- `update_attributes` → `update`
- `ActionController::Parameters#to_h` requires permit
- `ActiveRecord::Base.connection_config` → `connection_db_config`
5. Adopt Rails 7 defaults where safe: `config.load_defaults 7.1`. Override
specific defaults that would break existing behavior, with a TODO to revisit.
6. Update CI Ruby version (`.ruby-version`, `.github/workflows/*.yml`) to a
supported version (3.1+). The Problem
Rails majors aren't drop-in. Going from 6.x to 7.x touches the autoloader (Zeitwerk becomes the only option), default-config files (a new `new_framework_defaults_7_1.rb` initializer), the asset pipeline (Sprockets → optional Propshaft), and a thicket of deprecated APIs across ActiveRecord, ActionController, and ActiveSupport. Each repo needs Ruby bumped to a 3.x version, every gem audited for Rails 7 compatibility, and every classic-autoloader naming violation hunted down before the app will even boot.
Most Rails shops have between five and fifty Rails services, each with its own gem stack, its own legacy `config/application.rb` overrides, and its own subtle reliance on Rails 6 default behaviour. `bin/rails app:update` is interactive, conflict-prone, and produces a different diff on every repo. The classic outcome is one or two flagship apps upgraded with significant effort while the rest stagnate on Rails 6 indefinitely.
What Tidra Does
- Bumps
gem "rails"to the target 7.x version in eachGemfileand aligns Rails-adjacent gems (sprockets-rails,puma,bootsnap,selenium-webdriver) to compatible versions - Applies the
bin/rails app:updateframework-default diffs toconfig/application.rb,config/environments/*.rb, and the newnew_framework_defaults_7_1.rbinitializer - Switches the autoloader to Zeitwerk and renames files/classes to satisfy its naming convention (snake_case filenames matching CamelCase constants)
- Replaces deprecated APIs (
update_attributes→update,connection_config→connection_db_config,ActionController::Parameters#to_hpermit requirements) - Adopts
config.load_defaults 7.1and explicitly overrides individual defaults that would break existing behaviour, leaving TODOs for follow-up - Updates
.ruby-versionand.github/workflows/*.ymlto a supported Ruby (3.1+) and runs the test suite to surface remaining breakages
Before & After
Customization Tips
- Target Rails version: Pick 7.0 vs 7.1 explicitly. 7.1 includes async query support and the trilogy adapter; 7.0 is a smaller delta from 6.1 and lower-risk for older apps.
- Zeitwerk strictness: Apps with many
require_dependencycalls or non-standard file layouts may need to start in:classicmode under Rails 7, then migrate to Zeitwerk in a follow-up. - Asset pipeline: Decide between Sprockets (default) and Propshaft. Propshaft is simpler but breaks any app that relies on Sprockets preprocessors (Sass, ERB-in-asset).
- Test coverage gate: Require RSpec/minitest green plus a manual smoke test on a deployed staging environment, Rails defaults changes often manifest as subtle runtime behaviour, not test failures.