rails-load-defaults
Rails load_defaults Upgrade Skill
This skill guides the incremental upgrade of config.load_defaults in a Rails
application. The process walks through each config introduced in a new Rails
version, one at a time, so the user can test each change in isolation.
Overview
When a Rails app has a load_defaults version lower than its Rails version,
there are framework default configs that need to be adopted. This skill:
- Detects the current
load_defaultsversion - Determines the next target version
- Generates the
new_framework_defaults_X_Y.rbinitializer with all configs commented - Walks through each config one by one, analyzing the codebase to recommend values
- Waits for the user to test/commit each change before moving to the next
- Consolidates into
config/application.rbwhen all configs are done
Step 1: Detect Current State
Read config/application.rb and look for:
config.load_defaults X.Y
Also check if a config/initializers/new_framework_defaults_*.rb file already
exists (the user may be mid-upgrade).
Report to the user:
- Current
load_defaultsversion - Current Rails version (from Gemfile.lock)
- Which version transitions are needed (e.g., 6.1 → 7.0 → 7.1 → 7.2)
Step 2: Load Version Config Reference
Read the appropriate config reference file for the target version:
- 5.0:
configs/5_0.yml - 5.1:
configs/5_1.yml - 5.2:
configs/5_2.yml - 6.0:
configs/6_0.yml - 6.1:
configs/6_1.yml - 7.0:
configs/7_0.yml - 7.1:
configs/7_1.yml - 7.2:
configs/7_2.yml
Each config file contains entries organized into tiers with lookup patterns and decision trees for each config.
Step 3: Create the Initializer File
If no new_framework_defaults_X_Y.rb exists yet, copy the template from
the templates/ directory into the app's config/initializers/:
- 5.0: Copy
templates/new_framework_defaults_5_0.rb→config/initializers/new_framework_defaults_5_0.rb - 5.1: Copy
templates/new_framework_defaults_5_1.rb→config/initializers/new_framework_defaults_5_1.rb - 5.2: Copy
templates/new_framework_defaults_5_2.rb→config/initializers/new_framework_defaults_5_2.rb - 6.0: Copy
templates/new_framework_defaults_6_0.rb→config/initializers/new_framework_defaults_6_0.rb - 6.1: Copy
templates/new_framework_defaults_6_1.rb→config/initializers/new_framework_defaults_6_1.rb - 7.0: Copy
templates/new_framework_defaults_7_0.rb→config/initializers/new_framework_defaults_7_0.rb - 7.1: Copy
templates/new_framework_defaults_7_1.rb→config/initializers/new_framework_defaults_7_1.rb - 7.2: Copy
templates/new_framework_defaults_7_2.rb→config/initializers/new_framework_defaults_7_2.rb
These templates contain the exact canonical Rails initializer with all configs
commented out, matching what rails app:update would generate. Always use
the template rather than generating from scratch — this ensures the comments,
formatting, and config ordering match the Rails source.
Step 4: Iterative Config Walkthrough
Process configs in order from safest (Tier 1) to those needing analysis (Tier 2).
For each config:
4a. Analyze the Codebase
Run the lookup patterns defined in the config reference:
- Use
grep -rorfindto search for the patterns listed - Check the specific files/directories indicated
- Apply the decision tree to determine the recommended value
4b. Present Recommendation
Tell the user:
- What the config does (old behavior → new behavior)
- What you found in their codebase
- Your recommended value and why
- Risk level (low/medium/high)
4c. Apply the Change
Once the user agrees:
- Uncomment the config line in the initializer file
- Set the value (either the new default or the override value)
4d. Wait for User
Stop and wait. The user will:
- Commit and push the change
- Run CI or manually test
- Come back to confirm success or report failure
If the change broke something:
- Re-comment the config line or set it to the old value
- Note it as needing investigation
- Move to the next config
4e. Handle application_rb_only Configs
Some configs are marked application_rb_only in the version reference YAML.
These cannot go in the initializer file and must be tested directly in
config/application.rb.
During the iterative walkthrough, when you reach these configs:
- Add them explicitly in
config/application.rb(after the existingload_defaultsline) so they can be tested in isolation - Mark them with a comment so they're easy to find during consolidation:
config.load_defaults 6.1
# TESTING load_defaults 7.0 — remove during consolidation if using new default
config.active_support.cache_format_version = 7.0
- Wait for the user to test/commit as with any other config
4f. Track Progress
Keep track of which configs have been processed by reading the initializer file. Commented lines = pending. Uncommented lines = done.
For application_rb_only configs, track them by looking for the
# TESTING load_defaults comments in config/application.rb.
Step 5: Consolidation
When all configs in the initializer have been uncommented and tested:
-
Delete the
config/initializers/new_framework_defaults_X_Y.rbfile -
Update
config.load_defaultsinconfig/application.rbto the new version -
CRITICAL: For any configs where you kept the OLD behavior/value (i.e., did not adopt the new default), you MUST add explicit overrides in
config/application.rbafter theload_defaultsline. If you skip this, settingload_defaultsto the new version will silently switch those configs to their new default values — undoing your deliberate decision to keep the old behavior.Each config entry in the version reference YAML includes an
old_defaultfield. Use that value for the override.
config.load_defaults 7.0
# Override: kept old behavior because CSS targets input[type=submit] from button_to
config.action_view.button_to_generates_button_tag = false
# Override: kept old behavior because app uses namespaced UUIDs as stored identifiers
config.active_support.use_rfc4122_namespaced_uuids = false
-
Remove
application_rb_onlyconfigs that use the NEW default. During testing (Step 4e), these were added explicitly inconfig/application.rbwith# TESTING load_defaultscomments. Now thatload_defaultsis set to the new version, the new defaults are already implied — keeping them is redundant. Remove them.Only keep
application_rb_onlyconfigs if you chose the OLD value:
config.load_defaults 7.0
# load_defaults 7.0 already sets cache_format_version = 7.0,
# so do NOT explicitly set it here. Just remove the testing line.
# Override: kept old behavior because [reason]
config.active_support.disable_to_s_conversion = false
- Remind the user to commit and do a final round of testing.
Step 6: Next Version
If more version transitions are needed, start again at Step 2 with the next version.
Important Notes
- Never rush through configs. Each one gets its own commit and test cycle.
- Some configs have notes saying they must go in
config/application.rb(not the initializer). Flag these clearly and handle them during consolidation. - When the decision tree says "if unsure, keep the old default" — do that. It's always safer to be conservative.
- The user's testing (CI, manual QA) is the ultimate arbiter. The codebase analysis is guidance, not gospel.