In this articles series, I’ll try to cover all the issues that I had, when I was upgrading one of my Rails app from Ruby on Rails 3.2 to Ruby on Rails 4.0.

Preparations – What should we do before upgrading to Rails 4?

Upgrade your Ruby version at least to 1.9.3 (I would recommend 2.0)

Upgrade bundler

Upgrade your application to the most recent Rails 3.2 version

Check gems compatibility (you may want to be on edge with few gems (or use Rails 4 branches))

Write more tests if you don’t have a decent code coverage

The last point is the most important. If you don’t have a good code coverage level and you lack tests, upgrading from Rails 3.2 to Rails 4 might be a big problem.

Attributes protected and some other Rails 3 features

Rails team moved a lot of stuff from Rails core to gems. In order to make an upgrade smooth, probably the best solution is to add all the gems into Gemfile and then upgrade given functionalities one by one after successful Rails 4 migration:

Remember to set eager_load in all environments. If not, you’ll see following warning:

config.eager_load is set to nil. Please update your config/environments/*.rb files accordingly:
* development - set it to false
* test - set it to false (unless you use a tool that preloads your test environment)
* production - set it to true

If you don’t remove the auto_explain_threshold_in_second option, you’ll see following warning:

DEPRECATION WARNING: The Active Record auto explain feature has been removed.
To disable this message remove the `active_record.auto_explain_threshold_in_seconds`
option from the `config/environments/*.rb` config file.

filter_parameters

In Rails 3 filter_parameters setting was set up in application.rb. In Rails 4 there will be created an initializer for that (config/initializers/filter_parameters.rb):

Secret token (config/initializers/secret_token.rb)

The secret_key_base is not required but if you don’t add it, you’ll have a deprecation warning:

DEPRECATION WARNING: You didn't set config.secret_key_base.

Cookies from Rails 3 will be transformed automatically into Rails 4 format but be aware, that this won’t work the other way around, so if by any reason you’ll want to get back to Rails 3, all the user cookies will be unreadable.

In order to generate a random secret_key value, you can use rake task:

rake secret

This will just generate secret, you need to copy it to this initializer manually!

Rails.root + /config/application.rb

If you had any interactions with routes loading process you need to change config/routes in such a way:

config.paths['config/routes.rb'] # add .rb

Example:

# Load all the routes from routes directory
Dir["#{Rails.root}/config/routes/**/*.rb"].each do |route_file|
config.paths['config/routes.rb'] << route_file
end

Conclusion

If you have a decent code coverage level and you know what you’re doing, upgrade should not be a big problem. At this point, if you’re not using any fancy route settings, you should be able to at least start your application:

Sometimes we want to handle different parts of a single application from different domains. A good example of such an approach is when we have a scope containing our API. Wouldn’t it be great if it could be served from a different domain than the rest of the application? Of course yes! Approach like this (separating the API from the rest of the app) is used in several popular web applications. For example in Twitter. The app is under twitter.com and the API lies under the api.twitter.com url. When you have a smaller Rails app, probably you maintain the API-part and the user-part in one Rails project. The separate domains approach allows you to easily move to the two different apps, when the time comes.

So, how to limit access to the app parts based on the domain? Let’s use constraints. Let’s assume, that we have a scope called :api and the scope called :ui. Each scope represents a module in our app: