Optimizing a Legacy Rails App
We recently inherited a legacy Rails 2 app in sore need of an upgrade. Here are some of our favorite takeaways. (We'll cover the back-end gains here; the front-end post will come shortly.)
Moving to Heroku
Migrating a legacy app to a modern system like Heroku is a key part of any real upgrade. The benefits are enormous: easy deployment, quick changes, an always up-to-date staging server for the client, easier scaling, and the Heroku addons.
The nuts and bolts of the migration are beyond the scope of this post, but one of the biggest hurdles will be dealing with Heroku's restriction on writing to the disc. That giant "/public" folder that houses all your assets? Kiss it goodbye. Heroku restricts an app's slug size (the total file size of all the app's files) to 100 MB, which doesn't leave much room for images, videos, or other types of media. We addressed this by throwing most everything on S3, but how do you manage the hundreds of existing routes in your app that refer to assets on your filesystem?
We added a route to catch these requests:
That line uses route globbing, which assigns anything after '/assets/' in the URL to the param "other." Then, in your controller:
Boom. Now your browser will render assets from S3.
Our app's legacy mailer code had a few problems, the first being that it wasn't tested. Use Rspec to test the deliveries queue:
Another tool we found helpful was the sanitize_email gem, which delivers mail only to a few specific addresses. This enabled us to test the full ActionMailer cycle, all the way to our inbox.
Many of the app's changes revolved around database-driven content. The extensive library of curriculum materials, for example, determined how resource sections were structured, often scoped by the specific name of that section. To manage all of these changes without cycling in a new DB every day, we set up a rake task where we would dump our content changes. This file was under version control and therefore kept all the developers' DBs up-to-date. It also greatly simplified the deploy, since all we had to do to prepare the data was run one rake task.
So, where to even start? A good place would be in your routes file. Simply removing deprecated routes cleared up a whole slew of errors, and made understanding the large legacy app much easier.
Also, don't forget to set up hoptoad/airbrake on your staging server to monitor errors you might not be able to reproduce yourself. In a large legacy app, there will certainly be errors you can't foresee.
Check back soon for the front-end post!