Maintaining a Legacy Rails App
April 5th, 2011
Last night I deployed a new release of a Rails app.
Having deployed apps built with Rails 3 or at the very least Rails 2 apps using Bundler, the experience of deploying a Rails 2.3.5 app left me with a keen desire to at least bring this app up to Rails 2.3.11 with Bundler.
One of the delights of last night’s deployment was having to update RubyGems on the target machine. Usually this is as simple as:
gem update --system
That is, unless you are forced to upgrade to a specific, old release of RubyGems. Being at Rails 2.3.5 with this app, we were in this situation.
Speaking of “not exactly state of the art”, the version of Ruby on the target machine is Ruby Enterprise Edition 1.8.6.
Obviously, the preferred option would be to upgrade to Ruby 1.9.2 and Rails 3.0.5 forthwith.
However, it’s not my money that will be funding the upgrade. First steps first. I’m aiming for the following path:
- Rails 2.3.11 with Bundler and latest compatible gems.
- Ruby 1.9.2
- Rails 3.0.5
Wish me luck!
Upgrading to Rails 3
February 27th, 2011
Introduction
It was long overdue.
Rails 3.0.5 is out and I’ve finally bitten the bullet and upgraded this site to Rails 3 and Ruby 1.9.2. The site had its genesis back in mid-2007 as I was preparing to start my own business. Since 2008 the codebase hasn’t received much love. Indeed, I have only published articles here in dribs and drabs over the last couple of years.
So, as I embarked on this upgrade, I was aware that it also represented an opportunity to clean up some of my code as well as update third party libraries.
What follows is a story of how the upgrade unfolded including some decisions I made along the way and some lessons I learned.
Ruby 1.9.2
My initial intention was to just upgrade the app to use Ruby 1.9.2 and attack the Rails 3 upgrade later. However, as I soon found out, getting the app to work on Ruby 1.9 wasn’t as easy as I had anticipated. Sure, using RVM it was easy to change to using Ruby 1.9.2 in development. I also chose to move to Bundler even though my intention was to stay at Rails 2.3 for now.
However, I quickly discovered that not all the plugins I was using had been upgraded to run on Ruby 1.9.
Syntax Highlighting Adventures
Back in 2008 when I implemented syntax code highlighting I chose to use the tm_syntax_highlighting plugin, which is based on Ultraviolet. Unfortunately, the original tm_syntax_highlighting plugin is not supported on Ruby 1.9. There is a gem derived from it that claims to support Ruby 1.9 but I failed to get this to work.
I had a look at the suggestions from Ryan Bates and, because I had been using a solution based on Ultraviolet, I considered using Harsh but soon found that it was not supported on Ruby 1.9.
At this point I decided to go the whole hog and upgrade to Rails 3. As for supporting syntax highlighting, I ended up switching to use CodeRay.
Rails 3 Here I Come
First point of call for anybody embarking on a Rails 3 upgrade has to be Jeremy McAnally’s Rails 3 Upgrade Handbook. This invaluable resource not only guides you through using the official “rails upgrade” tool but explains how to make the most of the improvements in Rails 3.
So I methodically worked my way through the upgrade to the point where I was able to start and use the Rails console. This was a real milestone but I still had much to do before I could consider my upgrade complete.
Time to jettison old plugins
When I attempted to get the app running via a browser it quickly became evident that it was high time I jettisoned some ancient plugins.
Chief of these was the acts_as_authenticated plugin. Yes, I did say ancient. I’m aware that Devise is a favoured authentication solution for Rails 3. However, having had success in other projects with Authlogic, I chose to use it in the interests of expediency.
Another old plugin that needed replacing was acts_as_taggable_on_steroids. The acts_as_taggable_on gem proved to be an effective replacement for this with minimal changes required.
The final old plugin to be jettisoned was akismetor, which I replaced with the Rakismet gem.
Some comments about testing
I haven’t said anything about automated tests to this point. That is quite simply because I haven’t touched them. I know I should but, since this is a relatively small app that really only affects me, I decided to bypass automated testing in favour of completing the upgrade quickly. Some may scold me for this decision but I couldn’t justify the effort to myself. I’ll come back and get the automated tests working again later.
Note: If this was a larger app for a customer I would be far less inclined to bypass the task of ensuring that the automated tests work before considering the upgrade complete.
Reflections
I’m glad I’ve taken the time to upgrade this app to Rails 3 and Ruby 1.9.2. It has given me the chance to:
- replace old plugins with more recent gems;
- take advantage of Bundler;
- practice upgrading to Rails 3;
- position the app for further code improvements courtesy of Rails 3 and Ruby 1.9.
And, of course, now I can say that I have upgraded an old Rails app to Rails 3!
RVM, Bundler and Ruby Tracker
August 11th, 2010
Lightning Talk at rorosyd
Here are the slides from a lightning talk I gave at rorosyd last night. Having found RVM, Bundler and Ruby Tracker to be a useful set of tools this year, I thought I’d take the opportunity to share my experiences. And, as I mentioned during the talk, kudos to Mikel Lindsaar for his blog post earlier this year which alerted me to the power of creating a .rvmrc file.
Inspirations for a Ruby DSL
September 6th, 2009
Recently, during discussions with a client about reducing the amount of boilerplate coding that recurs from time to time in the project, the idea of developing a Domain Specific Language (DSL) arose. If you’re wondering what a DSL is, here is what Martin Fowler has to say. Or, you may prefer this cheeky piece from Dr Nic Williams.
I’ve been intrigued by DSLs for some time but not had the motivation to develop one until now.
In preparation, I’ve gathered a list of resources for writing a DSL in Ruby.
Tutorials
- Russ Olsen’s two part article
- Chapter 16 on DSLs in Russ Olsen’s “Design Patterns in Ruby” book
- Mischa Fierer’s three part article about writing a clean Ruby DSL
Examples
- Pete Yandell’s machinist
- Javan Makhmali’s whenever, which provides a clean Ruby syntax for defining cron jobs
- Ben Schwarz’s smoke (also see this video)
- Marcus Crafter’s sprinkle (also see this presentation)
- Cucumber, the behaviour driven development DSL
I’m happy with that list of resources but if anyone has any other suggestions please feel free to comment.
My next challenge is to think about the problem domain and design an elegant syntax.
Impressed with Prawn for PDF Generation
April 5th, 2009
I’ve been aware of Prawn, the Ruby PDF generation library for some time. Today was the first occasion I had an opportunity to utilise it and I was delighted with how easy it was to use.
My Ruby application needed to generate some tabular PDF reports so I installed the prawn gem and, with a little help from the examples on the Prawn home page and the core and layout documentation, I was off and running.
An example of using prawn via a rake task follows:
require 'rubygems' require 'prawn' require 'prawn/layout' namespace :report do desc "Generate top 10 points getters report" task :top10 => :environment do Prawn::Document.generate("reports/top10.pdf") do font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf" font_size 14 text "Top 10 Points Getters" text " " # fetch two-dimensional array of data for the table data = Player.top10_data table data, :font_size => 9, :position => :center, :headers => ["#", "Player", "Points"], :row_colors => ["ffffff", "eeeeee"] end end end
Generating the report was then as simple as running:
rake report:top10
I’m looking forward to using other features of Prawn such as image embedding and content positioning. At the time of writing prawn itself is version 0.4.1 and prawn-layout is 0.1.0. Hopefully James Healy, an Australian noted as “instrumental to the forward development of the library”, is coming to Railscamp 5 next month. Then I can pick his brains about what other features are in the pipeline.
Automated Testing with Ruby
December 8th, 2008
The fifth Australian Open Source Developers’ Conference was held last week in Sydney. In addition to helping organise the conference, I was fortunate enough to be one of the Ruby presenters.
Naturally, these slides were designed to assist my presentation rather than contain all the content. Indeed, the inclusion of some of the slides may beg some questions so I thought it may be helpful to add some explanation here.
Reminiscing about Testing
Each of us programmers is on a specific journey, especially when it comes to testing. Early in my professional career I was taught how to unit test program modules written in PL/I. However, the drivers for those tests had to be written in Job Control Language (JCL) – an experience I am not in a hurry to repeat.
Many years later, having escaped from working on mainframes, I discovered JUnit. This was a fundamental tool in my early experience of test driven development and refactoring. When I began exploring Ruby and Rails, I was eventually introduced to autotest, which I considered another quantum leap forward in the realm of automated testing.
Testing Tools
In 25 minutes there was obviously a limit to the number of Ruby testing tools I could cover. So, having quickly explained the benefit of autotest and touched upon Test::Unit, I moved on to describe some tools that I have used in the last year.
RSpec
To make sure the audience was still awake, at this point I showed a cute photo of our family dog. My lame excuse was that he exhibits a wide range of behaviours and RSpec is all about specifying behaviour. My main example of using RSpec was for specifying a controller. This led on to a brief digression into consider what makes a good test and the use of mock objects to isolate unit tests and make them faster by avoiding unnecessary database I/O.
Integration Testing with Cucumber, Webrat and Selenium
I was pleased to be able to include Cucumber, Webrat and Selenium in my talk. It’s only fairly recently that I started using Cucumber in conjunction with Webrat or Selenium and I’m impressed. As Mike Koukoullis showed in his subsequent talk, developing with Cucumber is a very powerful approach, which fosters clear description of intent before development of any feature.
Speaking of other talks, Alister Scott used a lightning talk to share his enthusiasm for Watir, which looks like a good alternative to Selenium.
Test Data with Machinist
After briefly relating the motivation for developing alternatives to relying on fixtures for test data, I described Machinist, an elegant tool recently developed by Pete Yandell. When used in conjunction with Sham, Machinist provides a neat way of generating “blueprints” that can be used in Cucumber steps.
Other Tools
I briefly mentioned JavaScript unit testing tools that are the subject of a blog post by Dr Nic as well as touching upon Shoulda, which is well written up by Dave Thomas.
Philosophy
To round out my talk, I thought it was important to offer a few philosophical thoughts. In a nutshell my view is that, whilst it is important to remember that automated testing is just one of many error removal approaches, we can all benefit from investing in automated testing.
In my case, as well as practicing using these tools, I’m also looking forward to reading the upcoming title The RSpec Book by David Chelimsky and others.
Navigation
Latest Blog Posts
- 24 Jun 2011: Rails Camp 9
- 13 May 2011: Committed Stand-Ups
- 27 Apr 2011: On Agile
- 5 Apr 2011: Maintaining a Legacy Rails App
- 4 Mar 2011: Reflections on YOW 2010 Conference
Syndication
Tags
agile bundler capgun capistrano community conference consulting css deployment dsl estimation jaoo javascript legacy apps osdc pdf planning prawn rails railscamp reflections rorosyd ruby ruby tracker rubygems rvm standups syntax highlighting testing unconference wds08 xml yow