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 .
- Preparations
- Ruby version
- Gems
- Config files (config/)
- Application code
- ActiveRecord
- ActionMailer
- Miscellaneous
- Next steps
1. Preparations
Before beginning with the upgrade process, we have some recommended preparations:
- Your Rails app should have the latest patch version 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 .
- Create a dual boot mechanism, the fastest way to do this is installing the handy gem next_rails .
For full details check out our article on How to Prepare Your App for a Rails Upgrade .
2. 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 .
3. 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
4. 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
5. Application code
a. ActiveRecord
- ActiveRecord <= 4.2 suppresses exceptions raised in the
after_commit
andafter_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
anddeliver!
are deprecated, in favor ofdeliver_now
anddeliver_now!
.
Before:
NotificationMailer.daily_summary(user).deliver
After:
NotificationMailer.daily_summary(user).deliver_now
6. Miscellaneous
respond_with
and the class-levelrespond_to
were removed from Rails 4.2 and moved to theresponders
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.
7. 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’re not on Rails 4.2 yet, we can help! Download our free eBook: The Complete Guide to Upgrade Rails .