Did you ever wish you could upgrade your Rails applications without doing it all at once? This would make everything much easier, right?
With next_rails, a toolkit to upgrade Rails applications, turn your wish into reality. While Rails upgrades tend to be manageable in small applications, many issues are often arising in larger applications due to upstream changes like the removal of deprecated features. next_rails makes the whole upgrade process easier to manage by allowing you to gradually change your code. Let’s start!
next_rails is a gem and you should add it in your Gemfile under the development group. Do it manually or with this command:
bundle add next_rails --group=development
Once next_rails is installed, you set it up with
next --init. This command
slightly changes your Gemfile while also creating Gemfile.next, a symlink to
your Gemfile. The following lines are added to your Gemfile:
def next? File.basename(__FILE__) == "Gemfile.next" end
The last step to setup next_rails is to add a
if...else statement to your
Gemfile under the newly introduced
next? method. This replaces the usual
gem 'rails' line found in every Gemfile of a Rails application, so don’t
forget to delete that line too.
if next? # This is the next Rails version your application will run gem 'rails', '~> 6.1' else # This is the Rails version your application currently runs gem 'rails', '~> 6.0' end
To run Bundler with the next Rails version, you can prefix any Bundler
next. Let’s execute
next bundle install, this will generate
Gemfile.next.lock with all gems listed in your Gemfile, but unlike
Gemfile.lock, it will point to the next Rails version as listed in the
if...else statement above. Another command example would be
next bundle exec rails s to start your Rails application with the next Rails version.
In the directory lib located at the root of your Rails application, define a
# lib/rails_version.rb module RailsVersion def self.is_6_1? Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR == 1 end end
With this module, you can then check if the application is currently running with the next Rails version. It can be in models, controllers, etc…
class Bicycle def repair 'The bicycle is all fixed up!' end end
…is adapted for the next Rails version:
class Bicycle def repair # Code for the next Rails version return 'Everything is repaired!' if RailsVersion.is_6_1? # Code for the current Rails version 'The bicycle is all fixed up!' end end
Adapting code for the next Rails version doesn’t have to be complicated. A
guard clause or a
if...else statement should be enough in most cases. If
needed, you could also write a separate method like this:
class Bicycle def repair # Code for the next Rails version return repair_6_1 if RailsVersion.is_6_1? # Code for the current Rails version 'The bicycle is all fixed up!' end def repair_6_1 # Do whatever needs to be done for the next Rails version end end
You can safely upgrade the Rails version in the Gemfile once all issues arising from the next Rails version have been addressed:
if next? gem 'rails', '~> 6.1' else # Now the same version as above gem 'rails', '~> 6.1' end
The code for the newly upgraded Rails version is kept and the rest is removed.
class Bicycle def repair # Code for next Rails version return 'Everything is repaired!' if RailsVersion.is_6_1? # Code for current Rails version 'The bicycle is all fixed up!' end end
…is changed to:
class Bicycle def repair 'Everything is repaired!' end end
The version of Rails and other gems tracked in Gemfile.next.lock have to be updated from time to time to follow the dependency updates happening on the default Gemfile.lock. This is how you can achieve this:
Overwrite Gemfile.next.lock with a copy of Gemfile.lock:
cp Gemfile.lock Gemfile.next.lock
Inside your development environment, update the Rails version:
next bundle update rails
Create a pull request with the changes or commit them to a branch, this depends on your project.
This is it, you’re set to use next_rails in your Rails applications. Let me know how it went for you by sending me a message on the Contact Me page. Constructive feedback is always welcomed!