Close and Go BackBack to Viget

Migration Consolidation for Fun and Profit

Ben Scofield
Ben Scofield, Former Staffer, March 18, 2008

Migrations are a huge step forward for many developers new to Rails – versioning the database is not all that common in, say, PHP. Over time, however, migrations can get unwieldy – as you accumulate more and more they can slow down, and early migrations can create conflicts with later code changes.

We’ve been experimenting with one approach to deal with this with some success of late: consolidation. Basically, we develop with migrations normally, creating (for example) files numbered 001-010. Once the iteration is solid, we then push everything out to stage for testing, and assuming that passes we push it all to production. After the production release, we then consolidate the existing migrations into a single file that has the same number as the last migration file. In the example already mentioned, we’d create 010_consolidated_migration_for_[date].rb. All of the individual changes in the migrations get rolled up into the consolidated file, so that it represents a single step to initialize a new database.

Subsequent iterations work much the same – new migrations are created in development on top of the consolidated migration (say, 011-015). Once they’re tested and released, we consolidated again, merging 010-015 into a new 015 file.

There’s an obvious downside here – rolling back in production is made much more difficult after a consolidation. For our processes, that’s not a huge problem, since we place a high priority on never rolling back the production DB. You could minimize the risk, however, by keeping a rolling window of consolidated migrations (so you’d have two or three consolidated files on production, each with the appropriate self.down methods). Even then you wouldn’t need to keep too many files, however, since you should rarely need to roll back more than one release. 

Using polymorphic_url to Generate URLs From Unknown Models

Clinton R. Nixon
Clinton R. Nixon, Former Staffer, March 15, 2008

I was recently helping out another developer with a polymorphic “commentable” model; that is, comments polymorphically belonged to any model as “commentables.” In most web applications, comment forms are shown on their parent, like the comment form shown when looking at this post. After we created a comment, we wanted to redirect back to the commentable resource, even though we don’t know what class it is. With Rails 2.0’s polymorphic routes, it’s a pretty easy task. You can just pass the model to redirect_to, like so:

redirect_to @commentable

We wanted to add an anchor, though, to take you to the comment you just added. After struggling with it for a bit, I found polymorphic_url deep in ActionController. This method is in the Rails documentation, but I’d never seen it before. It returns the URL for an ActiveRecord model as a string, so you can do something like the following:

redirect_to polymorphic_url(@commentable) + "#comment_#{@comment.id}"

It’s not particularly pretty, but it gets the job done. I’d love to see a better way. If you have one, let us know in the comments!

Tools of the Trade: vl_cruise_control

Mark Cornick
Mark Cornick, Former Staffer, March 12, 2008

This is the first in what should become a series on various tools we’ve developed here at Viget and are sharing with the community through our open source repository. While we’ve been diligently creating code, we haven’t always been as good at telling people about it—so here’s an effort to correct that oversight.

Late last year, we installed and enthusiastically adopted the CruiseControl.rb package for continuous integration. Out of the box, CC.rb runs your test suite and reports when tests fail. This has encouraged us to write better tests and run them more often before we commit code. We’ve also used rcov to check our test coverage, finding those parts of the code where our testing was inadequate, but we weren’t using rcov consistently. Two great tools that could work better together—how could we make our code even better by combining the two?

The answer is vl_cruise_control, a Rails plugin that uses rcov to enforce a coverage target, and causes CC.rb to mark a build as failed if that target isn’t met. So in addition to regularly checking that all the tests pass, we also check that all (or substantially all) of our code is accounted for in our tests.

vl_cruise_control is intentionally easy to install and use. Just install rcov on your CC.rb system:

sudo gem install rcov

Then check out the plugin into your Rails application’s vendor/plugins directory, and add a line to your Rakefile defining your coverage target:

require_coverage '95%'

Once that line is added, the plugin will define a Rake task called cruise, which will automatically be picked up by CC.rb and run in place of the default test suite every time it detects a new revision. If any of the tests fail, or if the coverage calculated by rcov falls below your threshold, Rake will exit with an error and CC.rb will fail the build. Otherwise, the build passes. It’s really just that simple. It works great with standard Test::Unit tests as well as RSpec.

We’ve been using this plugin to great success. We started a few projects with a target of 95%. Once we met 95%, we stepped it up to 98%. And now we’re aiming for the full 100%. Granted, test coverage is just one metric and doesn’t, by itself, guarantee anything about the quality of the code or its tests. But it encourages good habits in developers, and when vl_cruise_control makes checking coverage so easy, it’s hard to argue against it.

GitHub Announces Pricing Plans

Ben Scofield
Ben Scofield, Former Staffer, March 12, 2008

Some of us around the Lab have been using GitHub for a while now, and we love it. (It’s currently in beta, but we’ve got some invitations if you’re interested in checking it out - just leave a comment here.) Unlike at least one of the alternatives, however, GH won’t be entirely free once it launches. Finally, we have some details on their pricing plans.

All in all, I’d say it looks very reasonable - 100 MB of space for the free account is plenty given git’s efficiency, unless you’re storing media in your repository. I also love the focus on open source projects and public repositories, which are always unlimited. I think GitHub’s clearly on the right track, and I’m looking forward to seeing how it grows.

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many days in a non-leap year?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.