Upgrade Rails from 5.0 to 5.1

Upgrade Rails from 5.0 to 5.1

This article is part of our Upgrade Rails series. To see more of them, click here opens a new window .

This article will cover the most important aspects that you need to know to get your Ruby on Rails opens a new window application from version 5.0 opens a new window to 5.1 opens a new window .

  1. Preparations
  2. Ruby version
  3. Gems
  4. Config files
  5. Application code
  6. ActiveRecord
  7. Controllers
  8. Testing
  9. Next steps

1. Preparations

Before beginning with the upgrade process, we have some recommended preparations:

  • Your Rails app should have the latest patch version opens a new window before you move to the next major/minor version.
  • You should have at least 80% test coverage unless you have a dedicated QA team.
  • Follow a Git flow workflow to actively manage at least two environments: staging and production.
  • Check your Gemfile.lock for incompatibilities by using RailsBump opens a new window .
  • Create a dual boot mechanism, the fastest way to do this is installing the handy gem next_rails opens a new window .

For full details check out our article on How to Prepare Your App for a Rails Upgrade opens a new window .

2. Ruby version

Like Rails 5.0, Rails 5.1 opens a new window requires Ruby 2.2.2 opens a new window or later.

If you want to know more about the Ruby versions that you could use, check out our Ruby & Rails Compatibility Table opens a new window .

3. Gems

Make sure the gems you use are compatible with Rails 5.1, you can check this using RailsBump opens a new window .

If you can’t find the gem in RailsBump, you could try using next_rails to find incompatibilities in your dependencies:

gem install next_rails
bundle_report compatibility --rails-version=5.1.0

If that does not work, you’ll need to manually check the GitHub page for the project to find out its status. In case you own the gem, you’ll need to make sure it supports Rails 5.1 and if it doesn’t, update it.

4. Config files

Rails includes the rails app:update task opens a new window . You can use this task as a guideline as explained thoroughly in this post opens a new window .

You might run into an error trying to run that command:

$ bundle exec rails app:update
rails aborted!
LoadError: cannot load such file -- rails/commands/server
/Users/etagwerker/.rvm/gems/ruby-2.4.9@ombu/gems/bootsnap-1.4.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:34:in `require'
/Users/etagwerker/.rvm/gems/ruby-2.4.9@ombu/gems/activesupport-5.1.7/lib/active_support/dependencies.rb:292:in `block in require'
/Users/etagwerker/.rvm/gems/ruby-2.4.9@ombu/gems/activesupport-5.1.7/lib/active_support/dependencies.rb:258:in `load_dependency'
/Users/etagwerker/.rvm/gems/ruby-2.4.9@ombu/gems/activesupport-5.1.7/lib/active_support/dependencies.rb:292:in `require'
/Users/etagwerker/Projects/ombulabs/ombushop/config/application.rb:5:in `<main>'

If that is the case, you will need to change this require statement:

require 'rails/commands/server'

To:

require 'rails/commands/server/server_command'

As an alternative, check out RailsDiff opens a new window , which provides an overview of the changes in a basic Rails app between 5.0.x and 5.1.x (or any other source/target versions). Always target your upgrade to the latest patch version (e.g: 5.1.6 instead of 5.1.0).

Some assets configuration changes you’ll have to do on your config/environments/{development, test, production}.rb files are:

Before:

config.serve_static_files = false
config.static_cache_control = "public, max-age=3600"

After:

config.public_file_server.enabled = false
config.public_file_server.headers = {
  'Cache-Control' => "public, max-age=3600"
}

5. Application code

5.1. ActiveRecord

  • The raise_in_transactional_callbacks option is now removed. It was already deprecated and covered in a previous upgrade opens a new window .

  • Also removed was use_transactional_fixtures, which was replaced by opens a new window use_transactional_tests.

  • ActiveRecord::Base#uniq was removed, it was deprecated in Rails 5.0 and has been replaced by #distinct. Check out https://github.com/rails/rails/pull/20198 for the discussion.

  • The ordering of association statements is now significant. In particular, you can no longer declare a has_many :through association before declaring the association that implements the through. You must declare the joined model first.

This will no longer work:

  has_many :posts, :through => :authors
  has_many :authors

Change To:

has_many :authors
has_many :posts, :through => :authors
  • If you are using a before_destroy callback, you now must explicitly throw :abort

Previously, a before_destroy callback could return false to abort the operation but now rails requires you to throw :abort to stop the operation

5.2. Controllers

  • Before Rails 5.1, conditions in filters could be invoked using strings. They now have to be symbols:

Before

  before_action :authenticate_user!, unless: 'has_project_guest_id'

After:

  before_action :authenticate_user!, unless: :has_project_guest_id
  • All *_filter methods are now called *_action:

These methods were actually already deprecated in Rails 5.0, and Rails 5.1 removes support for *_filter usage, so you should be using *_action.

Before:

skip_before_filter :authenticate_user!
before_filter :authenticate_user!
after_filter :do_something

After:

skip_before_action :authenticate_user!
before_action :authenticate_user!
after_action :do_something
  • render no longer supports :text and :nothing arguments.

Instead of :text you now have to use :plain. And in cases where the controller renders :nothing, you should now use the head method to send a bodyless response. example: head :ok will answer the request with a 200 response, without a body.

  • additionally render also no longer accepts nothing: true.

Using head :ok is an effective alternative and so is body: nil.

6. Testing

  • Parameters in controller tests now need a params key:

Rails 5.0 had already deprecated this behavior, and Rails 5.1 drops support for passing parameters without using keyword arguments. This change is necessary even if you’re using RSpec:

Before:

expect { post :create, params }.to change(Project, :count).by(1)

After:

expect { post :create, params: params }.to change(Project, :count).by(1)

7. Next steps

If you successfully followed all of these steps, you should now be running Rails 5.1! Do you have any other useful tips or recommendations? Share them with us in the comments section.

If you’re not on Rails 5.1 yet, we can help! Download our free eBook: The Complete Guide to Upgrade Rails opens a new window .

Get the book