Upgrading Rails from 2.1.2 to 2.3.5

I recently had to upgrade the rails installation of the project I’m working on, so just thought I would document what steps I took to make that happen since upgrading can be a pain and I found tutorials out there to be very helpful in getting the code up and running again.

So I had to upgrade some gems that our project used. Your list will probably be different, but here are some of the upgraded gems:

  • rails 2.3.5: sudo gem install rails --version 2.3.5. Also changed RAILS_GEM_VERSION to equal ‘2.3.5’ in config/environment.rb and ran the rake rails:update command
  • rack 1.0.1: sudo gem install rack --version 1.0.1
  • haml 2.2.20: sudo gem install haml --version 2.2.20

I also upgraded various plugins, which are listed below:

  • active_scaffold: script/plugin install git://github.com/activescaffold/active_scaffold.git
  • rspec: script/plugin install git://github.com/dchelimsky/rspec-rails.git
  • rspec-rails: script/plugin install git://github.com/dchelimsky/rspec-rails.git
  • state_select: script/plugin install git://github.com/sprsquish/state_select.git
  • rails_widgets: script/plugin install git://github.com/paolodona/rails-widgets.git
  • skinny_spec: script/plugin install git://github.com/rsl/skinny_spec.git

For RSpec, I had to take a few extra steps to get all the specs working again. I updated the rspec.rake file with “script/generate rspec”, and overwrote everything while merging in custom additions to our spec/spec_helper.rb. I also had to hack the FlashHash class in my spec helper because apparently (at least in rspec 1.3.0) the flash in controller specs gets cleared before the tests get access to it. So, to work around that in the tests we can just disable to clearing mechanism like so:

ActionController::Flash::FlashHash.class_eval do
  def sweep; nil; end
end

Also for RSpec, I had to patch the skinny_spec plugin (which I don’t really like, but some of the tests in the app still use it) so it would guess the proper instance variable name for some of it’s magical validation expectations:

LuckySneaks::CommonSpecHelpers.module_eval do
  def instance_for(name)
    instance_variable_get("@#{name.to_s.underscore.split('/').last}")
  end
end

I also tried to update attachment_fu, but something was not working as it should have, so I just reverted back to the version we were using before (not sure which one :-) and monkey-patched the only part that was bombing which was the attachment_attributes_valid? method:

Technoweenie::AttachmentFu::InstanceMethods.module_eval do
  def attachment_attributes_valid?
    [:size, :content_type].each do |attr_name|
      enum = attachment_options[attr_name]
      unless enum.nil? || enum.include?(send(attr_name)
        errors.add(attr_name,
          I18n.translate("activerecord.errors.messages.inclusion", attr_name => enum)
        )
      end
    end
  end
end

That was it for all of our dependencies that were failing from the upgrade. A few other minor things that needed to be changed were formatted route methods (removed all “formatted_blah_path(:rss)” routes in favor of the non-deprecated “blah_path(:format => :rss)” format). Also had to change all the ActionView::Base#truncate methods to use the proper method signature with the :limit and :omission options.

The last bit that changed from 2.1.2 to 2.3.5 was rack request handling. In this current project we are allowing multiple file uploads using SWFUpload and had hacked CGI::Session to work with the Flash uploads, but rack now allows us to properly intercept the request and do the things we needed to do to make session handling work properly. A complete writeup can be found here.

So, that was it for upgrading dependencies. That being said, after all that was done I still had about 100 failing tests because of the ways some of our application-specific extensions to ActiveRecord, ActionController, etc, were implemented. So don’t think that just getting all your dependencies upgraded will fix all your problems.

Happy coding!

Posted by Steve on Tuesday, February 23, 2010

Post a comment


(required, but not displayed)

(optional)