[EN] How I upgraded my pet project from Rails 7 to Rails 8 in 30 minutes
- Time: 10-15 min
- Level: Intermediate
- Code: Application
- Revision: Oct 30, 24
TL;DR - I have a custom/
folder in my project where I keep files that I change instead of modifying generated files. The only change in generated files is customization loading. As a result when I need to upgrade a project I overwrite default files with bin/rails new
and add a few require "custom/file.rb"
statements.
Since Rails 8 will be released soon I decided to test my custom application layout and upgrade prototype I use for my pet projects from Rails 7 to Rails 8. I will go over the whole process step by step and maybe customization that made it easy will become one you’d like to try yourself.
The only feature application has is an authentication with devise so I (almost) did not have any issues with app functionality or changes introduced in Rails 8.
Section I - Updating project files to Rails 8
- Change rails version in the
Gemfile
- gem "rails", "~> 7.1.3", ">= 7.1.3.4" + gem "rails", "~> 8.0.0.rc1"
- Delete
Gemfile.lock
- Uninstall all gems (
gem uninstall --all --force -x
) - Install bundler (
gem install bundler
) - Install rails (
bundle
) - Update project files (
rails new prototype -f -d postgresql -c tailwind
)- The command is one I used to generate project in the past. Depending
on the situation, you could also use
bin/rails app:update --force
- The command is one I used to generate project in the past. Depending
on the situation, you could also use
- Commit everything
Section II - Bringing back customization
At this point I couldn’t run the project because some files have been overwriten with default versions provided by the generator. So next I reviewed changes and put back customiztions. Fortunately my project has just a few files that have changes and changes are minimal.
While reviewing I saw changes like
- # Ignore all environment files (except templates).
+ # Ignore all environment files.
/.env*
- !/.env*.erb
and
# Throw-away build stage to reduce size of final image
- FROM base as build
+ FROM base AS build
that made my inner perfectionista quite happy :) (also an indicator that people do care)
Overall I had to change eleven files:
links don’t open changes in each file unfortunately, so please use the file tree on the left
- .gitignore
- .rubocop.yml
- Gemfile (I have puma commented out on line 12 for AWS ElasticBenstalk compatibility)
- app/controllers/application_controller.rb
- app/views/layouts/application.html.erb
- config/application.rb
- config/datbase.yml
- config/environments/development.rb
- config/environments/production.rb
- config/environments/test/rb
- custom/config/routes.rb
These changes introduced new gems so I had to run bundle
once more to
install them.
That’s all - I was able to start the server and saw the sign in UI.
Section III - Few final touches
One last part was to check if Rubocop checks and RSpec suite pass. I run
bin/rubocop -A .
to fix the first one and had to
change the test I have to make it pass.
Section IV - Custom project layout
Problem: Changes to generated project files interfere wit use of
bin/rails new yourprojectname
as an upgrade mechanism.
Idea: Changes to generated files have to be minimal in order to put them back easily.
Implementation: Have separate files with changes and load them in generated files.
In order to achieve the desired outcome (simple upgrade process) four mechanisms are used:
require "../file.rb"
- pain rubyeval_gemfile "../Gemfile"
- provided by the bundler gempaths["file.rb"] =
- provided by Railsinitializer "name", after: :callback do
- provided by Railsinherit_from: filename
- provided by rubocop gem
Whenever there is a need to change the generated file I
introduce new file where I add the change
and load a file with change from the original file. Naming convention I
use - customization file has the same name as the generated with
custom/
prefix. So custom configuration for .rubocop.yml
is in
custom/.rubocop.yml
etc.
Part of the customization resides in
custom/config/application.rb
which is required in config/application.rb
so these changes are preserved while project is upgraded and later
introduced again.
Summary
Separation of generated by default project files and customizations made upgrade process much simpler for me. Since customization is done with built-in tools it’s quite simple to implement and having the naming convention makes it easy to understand and follow.
Extra
While I was working on this post 8.0.0.rc2 was released and it took me just a few minutes to upgrade the project.
Revisions
- Oct 30, 24 - Initial post