Close and Go BackBack to Viget

Migration Consolidation for Fun and Profit

Ben Scofield
Ben Scofield, Development Director, March 18, 2008 4

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, Senior Developer, March 15, 2008 1

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, Web Developer, March 12, 2008 0

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, Development Director, March 12, 2008 3

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.

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I think that polymorphic_url(@commentable, :anchor => “comment_#{@comment.id}") should work. You can also refactor the “comment_#{@comment.id}” to a separated method, like dom_id, which returns the dom identifier of the comment.