OmbuLabs Blog

The Lean Software Boutique

Upgrade Rails from 4.1 to 4.2

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

This article will cover the most important aspects that you need to know to get your Ruby on Rails application from version 4.1 to 4.2.

  1. Ruby version
  2. Gems
  3. Config files (config/)
  4. Application code
    1. ActiveRecord
    2. ActionMailer
  5. Miscellaneous
  6. Next steps

1. Ruby version

Rails 4.2 requires Ruby 1.9.3 or later, and Ruby 2.0 (or newer) is preferred according to the official upgrade guide.

2. Gems

If you're using RSpec 2, you'll need to migrate to RSpec 3, since RSpec 2 doesn't officially support Rails 4.2. To make this process easier, you can update to RSpec 2.99, which will print a bunch of deprecation warnings at the end of the test run, and you'll need to fix these before updating to RSpec 3. For more information, check out their official upgrade guide.

You can also use the awesome Transpec to automate the RSpec 2 to 3 upgrade process.

Once you're on Rails 4.2, you will be able to remove the Timecop gem if you're using it, and replace it with new test helper methods travel, travel_to and travel_back. See: TimeHelpers

3. Config files

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

As an alternative, check out RailsDiff, which provides an overview of the changes in a basic Rails app between 4.1.x and 4.2.x (or any other source/target versions).

After upgrading to Rails 4.2 for an application that needs to run in development on port 80, I came across an unexpected problem due to a change in Rack. Rails now listens on localhost instead of 0.0.0.0. You will run into the same problem in case you need to access your Rails server from a different machine. To work around it, you need to start your server by binding to 0.0.0.0 by using:

rails server -b 0.0.0.0 -p 80

Alternatively, you can try the solution here to avoid providing -b 0.0.0.0 when you start the server. If you're using Foreman and run into this problem, you can edit your Procfile's web entry so that it reads:

web: bundle exec rails s -b 0.0.0.0

4. Application code

a. ActiveRecord

  • ActiveRecord <= 4.2 suppresses exceptions raised in the after_commit and after_rollback callbacks by default. They are rescued and printed on the log, and they don't propagate. You can opt into raising these exceptions now by adding the following configuration:
config.active_record.raise_in_transactional_callbacks = true

Starting from ActiveRecord 5.0, these exceptions are always raised regardless of this setting, so you should opt into it and update your code accordingly.

See: https://github.com/rails/rails/pull/16537

  • If you pass an object to #find, you will now run into the following deprecation warning:
DEPRECATION WARNING: You are passing an instance of ActiveRecord::Base to `find`.
Please pass the id of the object by calling `.id`.

You will need to change your .find calls to pass an id instead of an object.

Before:

Comment.find(comment)

After:

Comment.find(comment.id)

The same goes for #exists? calls, if you pass an object as a parameter for it, you will need to provide an id instead.

b. ActionMailer

  • deliver and deliver! are deprecated, in favor of deliver_now and deliver_now!.

Before:

NotificationMailer.daily_summary(user).deliver

After:

NotificationMailer.daily_summary(user).deliver_now

5. Miscellaneous

  • respond_with and the class-level respond_to were removed from Rails 4.2 and moved to the responders gem.

If you're using these in your controllers, you will need to add:

gem 'responders', '~> 2.0'

to your Gemfile.

  • Rails' HTML sanitizer was rewritten to use the more secure Loofah gem. As a result, your expected sanitized output might be slightly different for some inputs. If you experience problems with it, you can restore the behavior by adding:
gem 'rails-deprecated_sanitizer'

to your Gemfile. It will only be supported for Rails 4.2, so it's recommended that you do not do this and stick with the new default HTML sanitizer.

6. Next steps

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

If you don't have the time to upgrade your Rails app, check out our Ruby on Rails upgrade service: FastRuby.io