How I update project from Rails 3 to Rails 4

Hello my dear friends.

Work with large projects often requires repayment of the technical debts: update some libs, сode refactoring, etc. In my case I should move the project from rails 3 to rails 4. In this article I will tell how I did it.

Step 0: Tests!!!

First of all, you project must have huge test coverage. In my project we have 93.52% code covered by tests. Yep, it is hard. But without tests thinking about update of some libs or doing сode refactoring in your project will be the same as playing “Russian roulette” - maybe you will win, maybe no. So first of all, before making update for rails 4 you have to check code coverage in your project (simplecov very good library for this) and cover by tests missed parts.

Step 1: Ruby 1.9.3 or 2.0.0

Rails 4 requires Ruby 1.9.3 and recommends Ruby 2.0.0. Attempting to run Rails 4 with a Ruby version below 1.9.3 will cause syntax errors or runtime issues. So first of all you should migrate your project to new Ruby version. We have been using the last ruby 2.0.0 in this project, so we did not have such problem :)

Step 2: Strong_Parameters

First huge change in the rails 4 is strong_parameters. I began to change project by removing whitelist_attributes and migration to strong_parameters. We need to change some settings in our projects to do this. First of all, we have to add strong_parameters to Gemfile:

gem "strong_parameters"

Next changes will be in “config/application.rb” whitelist_attributes settings:

config.active_record.whitelist_attributes = false

And then add “strong_parameters.rb” file in “config/initializers” with this content:

ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

After this change you have to remove “attr_accessible” from models and use “strong_parameters” in controllers. Use the tests to verify that you migrated without problems in strong_parameters (I used tests in each step).

Step 3: Routes

Method “match” can be used only for routes, which should accept several types of requests (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS).

match 'subscriptions/:subscription_id' => 'news#create', via: [:post, :put, :patch]

But if you have something like this:

match '/terms' => 'site#terms'

you have to change it to a right type of the request:

get '/terms' => 'site#terms'

Again, check all changes by tests :)

Step 4: Gems

Migration of the rails 3 app to the rails 4 requires gem updates. Some gems in your Gemfile can be migrated to new version, which can work in both in rails 3 and in rails 4. For example, we will start with the migration of the devise gem. First of all, I read changelog of this gem to understand differences between versions and know what to change in migration. Check all by tests (also by manual check, tests do not guarantee 100% success) and select another gem for migration.

The “rails4_upgrade” gem helps to automate some of the processes required to the upgrade to the Rails 4. It add rake task to check old versions of gems:

$ bundle exec rake rails4:check_gems

Some of gems stopped to support rails 3 and support just rails 4. In this case better to read, what were changed in a gem in changelog and add migration notes, in case you have to do some work with this gem after update to rails 4.

Step 5: Change Rails version in Gemfile

Open Gemfile in a text editor and change the line that starts with gem ‘rails’ to:

gem 'rails', '~> 4.0.1.rc3'

Why did I use RC? Just because 4.0.0 have some bugs, which broke my app (my main problem was fixed by this pull request)

Rails 4 also depends on newer versions of gems that drive the asset pipeline (assets group must be removed):

gem 'sass-rails', '~> 4.0.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'

Rails 4 moves many features into gems that were previously shipped with Rails itself. You can found list of this gems on this page. In my case I need:

# used cache_page
gem 'actionpack-page_caching', '1.0.0'
# xml requests from some services
gem 'actionpack-xml_parser', '1.0.0'

After “bundle update rails” you should change your rails app. will help you very much with this . In my project I had to use this diff.

Finally, I continue to update gems, which work only with rails 4

Step 6: Fix fallen tests

No comments, just check your code and tests.


As you can see migration process even of the big rails project is not so complicated if you do it with clear migration plan. There is open source book upgradingtorails4, which can be very helpfull (I did this migration before this book was published).

That’s all folks! Thank you for reading till the end.


November 01 2013