Upgrading to Rails 4.0.2 and Ruby 2.1

Upgrading to Rails 4 and Ruby 2 on Heroku. This is a B2B application so we don’t get tons of traffic, but it is a critical reporting and financial application used by our customers frequently.

The Stack

1
2
3
4
5
Cloud platform: Heroku
 Rails 3.2.13
 Ruby 1.9.3
 Postgresql
 devise (2.2.3)

Upgraded to Rails 4.0.3 Ruby 2.1 devise (3.2.2)

The Upgrade

Review Ryan Bates Railscast http://railscasts.com/episodes/415-upgrading-to-rails-4

  • Rails4 dropped support for “assets” group in the Gemfile removed grouping from Gemfile

  • Run bundle outdated and upgrade outdated gems A few gems that were outdated needed to be upgraded, but did not cause any major issue.

  • Rails4 strong parameters This required an to update all controllers and replace params[] with a private method that specified the attributes of the model passed.

Before:

1
2
3
    def create
      @payee = @account.build_payee(params[:payee])
    end

After:

1
2
3
4
5
6
7
    def create
      @payee = @account.build_payee(payee_params)
    end
    private
    def payee_params
      params.require(:payee).permit(:name, :street_address, :city, :state, :zip_code, :country)
    end
  • We use devise for authentication, therefore we had to update the application controller to support strong parameters https://github.com/plataformatec/devise#strong-parameters

    1
    2
    3
    4
    5
    6
    before_filter :configure_permitted_parameters, if: :devise_controller?
    protected
    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :password_confirmation, :name, :account_id, :current_password) }
      devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :name, :account_id, :current_password) }
    end
    

After the changes run,

1
    $ bundle install 

and then start server.

1
    $ rails s 

The Issues

The server started but there were several issues.

  1. Session issue: Solved by changing the sessionstore from cookiestore to activerecordstore as recommneded by searching on stackoverflow

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Processing by HomeController#index as HTML
    Completed 500 Internal Server Error in 4ms
    
    NoMethodError (undefined method `each_with_object' for #<String:0x007fe40519d368>):
      actionpack (4.0.2) lib/action_dispatch/request/session.rb:175:in `stringify_keys'
      actionpack (4.0.2) lib/action_dispatch/request/session.rb:170:in `load!'
      actionpack (4.0.2) lib/action_dispatch/request/session.rb:160:in `load_for_read!'
      actionpack (4.0.2) lib/action_dispatch/request/session.rb:86:in `[]'
      warden (1.2.3) lib/warden/session_serializer.rb:30:in `fetch'
      warden (1.2.3) lib/warden/proxy.rb:212:in `user'
    

    http://stackoverflow.com/questions/17655744/rails-4-0-rake-dbsessionscreate http://stackoverflow.com/questions/21862717/session-cookie-issue-undefined-method-each-with-object-upgrading-to-rails-4-a/21864722

    Add the Gem

    1
      gem 'activerecord-session_store', github: 'rails/activerecord-session_store'
    

    also change session_store.rb file

    Before:

    1
    2
      Reports::Application.config.session_store :cookie_store, key: '_reports_session'
      Reports::Application.config.session_store :cache_store
    

    After:

    1
      Reports::Application.config.session_store :active_record_store
    
  2. Minitest issue: Then the server did not start because of issue below.

    After upgrading to rails 4.0.3 - Could not find ‘minitest’ (~> 5.1) I am using rbenv so it was not clear to me why this failed. Eventually, ran bundle clean to clear out old gems and it worked. http://stackoverflow.com/questions/21867197/after-upgrading-to-rails-4-0-3-could-not-find-minitest-5-1/21867632#21867632

    → bundle clean –force → bundle update → rails s => Booting Thin => Rails 4.0.3 application starting in development on http://0.0.0.0:3000 => Run rails server -h for more startup options => Ctrl-C to shutdown server

  3. All rspecs passed successfully, phew!!

  4. However, several cucumber tests failed with this error.

    1
    rails, undefined 'raw' method 
    

I couldn’t find the root cause of this error, however I traced it to the line we were using to display flash errors. This was using simple_format to display error messages to the user

1
  flash[:error] = simple_format(@import.errors.full_messages.join "\n")

Eventually, i just tried removing simple_format, and it worked!!!

1
  flash[:error] = @import.errors.full_messages.join "\n"

All tests run successfully!

Deployment to Heroku

We start deployment with a Backup of Prod DB, Deploy to Staging, Fix issues and then deploy to production. Only two issue were discovered.

  1. No assets getting displayed on heroku

Had to set this to true # Don’t fallback to assets pipeline if a precompiled asset is missed config.assets.compile = true

Not sure if this is the best solution, we don’t have a lot of images, so I decided to do this for now.

  1. Some of the ui-icons in jquery-ui were not displaying.

We had checked in the jquery-ui ui-lightness theme into the rails assets pipeline. Removed this file and added the following two gems.

1
2
gem 'jquery-ui-rails'
gem 'jquery-ui-themes'

Then updated application.css with *= require jquery.ui.all *= require jquery-ui/ui-lightness

and application.js with //= require jquery.ui.all

All tests run. Deployed to production. Did a spot check of the UI to make sure everything looks good, and it’s live. If you have suggestions or feedback I would love to hear.

Thanks for reading.

“All’s fair in love and war…and learning. Use whatever tactics you can to learn no matter how silly or how much of a cheat they may seem.” - https://twitter.com/nanobeep