IMPORTANT: Do NOT run rails app:update as it overwrites files without considering local customizations. Instead, follow this selective merge process:
9.1: Detect Local Customizations
Before any upgrade, identify files with local customizations:
# Check for uncommitted changes
git status
# List config files that differ from a fresh Rails app# These are the files we need to be careful with
git diff HEAD --name-only -- config/ bin/ public/
Create a mental list of files in these categories:
Custom config files: Files with project-specific settings (i18n, mailer, etc.)
Modified bin scripts: Scripts with custom behavior (bin/dev with foreman, etc.)
Standard files: Files that haven't been customized
9.2: Analyze Required Changes from Railsdiff
Based on the railsdiff output from Step 6, categorize each changed file:
Category
Action
Example
New files
Create directly
config/initializers/new_framework_defaults_X_Y.rb
Unchanged locally
Safe to overwrite
public/404.html (if not customized)
Customized locally
Manual merge needed
config/application.rb, bin/dev
Comment-only changes
Usually skip
Minor comment updates in config files
9.3: Create Upgrade Plan
Present the user with a clear upgrade plan:
## Upgrade Plan: Rails X.Y.Z → A.B.C
### New Files (will be created):
- config/initializers/new_framework_defaults_A_B.rb
- bin/ci (new CI script)
### Safe to Update (no local customizations):
- public/400.html
- public/404.html
- public/500.html
### Needs Manual Merge (local customizations detected):
- config/application.rb
└─ Local: i18n configuration
└─ Rails: [describe new Rails changes if any]
- config/environments/development.rb
└─ Local: letter_opener mailer config
└─ Rails: [describe new Rails changes]
- bin/dev
└─ Local: foreman + Procfile.dev setup
└─ Rails: changed to simple ruby script
### Skip (comment-only or irrelevant changes):
- config/puma.rb (only comment changes)
9.4: Execute Upgrade Plan
After user confirms the plan:
For New Files:
Create them directly using the content from railsdiff or by extracting from a fresh Rails app:
# Generate a temporary fresh Rails app to extract new filescd /tmp && rails new rails_template --skip-git --skip-bundle
# Then copy needed files
Or use the Rails generator for specific files:
bin/rails app:update:configs # Only updates config files, still interactive
For Safe Updates:
Overwrite these files as they have no local customizations.
For Manual Merges:
For each file needing merge, show the user:
Current local version (their customizations)
New Rails default (from railsdiff)
Suggested merged version that:
Keeps all local customizations
Adds only essential new Rails functionality
Removes deprecated settings
Example merge for config/application.rb:
# KEEP local customizations:
config.i18n.available_locales = [:de, :en]
config.i18n.default_locale = :de
config.i18n.fallbacks = [:en]
# ADD new Rails 8.1 settings if needed:# (usually none required - new defaults come via new_framework_defaults file)