Close and Go BackBack to Viget

Ruby on Rails

Using polymorphic_url to Generate URLs From Unknown Models

Clinton R. Nixon
Clinton R. Nixon, Senior Developer, March 15, 2008 0

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.

The Problem with Scaffolding

Ben Scofield
Ben Scofield, Senior Developer, February 06, 2008 3

A couple of years ago, DHH‘s fifteen-minute blog screencast introduced Rails to the world. This wonder was accomplished in no small part because of Rails’ scaffolding - code and markup generated by the framework to handle the most common tasks.

Scaffolding - by joelogon

Since that debut, scaffolding in Rails has changed substantially. Dynamic scaffolding (where the generated code lived in memory instead of on the file system), for instance, was pulled out of the core framework a year ago, while static scaffolding (where actual files are created) was updated to reflect the RESTful principles that the community as a whole has been moving towards. Even while the core team made these changes, however, a tension over the goals of scaffolding has emerged.

Cross-Purposes

So what are these goals? Well, on one side, there’s the production-ready faction. These people want scaffolding to resemble Django‘s admin interface, where it’s ready to support a live site out of the box. When they are (inevitably) let down, they opt for or create alternatives like Streamlined and ActiveScaffold.

On the other side, you’ve got the educational faction. Proponents of this want scaffolding to teach new developers best practices for writing Rails code. They’re apt to be big fans of documentation and tutorials, as well, and to be the right people to turn to if you want to know the why of something - like why RESTful controllers have seven actions.

As it turns out, production-ready code, even when it follows best practices, is often not the best way to learn those practices. The problem is that the best practices the educational faction wants to instill underdetermine production code - any application capable of supporting a live site is likely to optimize things, move things around, and in general obscure much of its implementation of best practices behind structures that make it better at supporting a live site (and often easier to maintain).

A Modest Proposal

Given all that, here’s a suggestion: separate the two goals. Abandon the idea that scaffolding can or should be both useful and educational, and rip out everything that detracts from one or the other purpose. My suggestion (for what it’s worth) is to ensure that scaffolded code is in fact production-ready, and is solid for the basic case.

This doesn’t mean that we completely abandon the educational aspect, however. Instead, we should create a sample application expressly tailored to helping new Rails developers learn how best to write their code. It could be distributed via gem or plugin (with a generator or as a resourceful plugin), but it should be separate from Rails core, and easy to find and install.

In the end, clarifying a single purpose for scaffolding will better serve both factions, and the community as a whole.

(photo from joelogon on Flickr)

Sandstone: A Drop-In CMS for Existing Rails Applications

Ben Scofield
Ben Scofield, Senior Developer, January 15, 2008 13

Over the past few months, I’ve been talking here and there about a project I’ve been working on - Sandstone. The general idea is that, while Rails makes it easy to build an application quickly, it’s unreasonably difficult to integrate two distinct Rails projects - but if you have an e-commerce site, you may have a need for static content that doesn’t justify the effort of running an entirely distinct Rails application like Radiant CMS. Sandstone meets this need by providing a drop-in, customizable CMS as a plugin, ready to be installed on any given Rails application.

sandstone formation

There are a couple of really interesting things about this project. The first is that it’s an instance of what we at Viget are calling “resourceful plugins” - that is, plugins that provide a complete set of resources and functionality around them in a specific domain. These plugins are intended to be easy to integrate into any existing Rails application, and to allow for extensive modification and customization without losing the ability to upgrade the core plugin code.

That last bit is especially important, since that’s where a lot of alternatives fall down - sure, there are plugins out there that add CMS functionality, but once you invest the time in customizing them to your particular project you’re wed to the particular version you installed. If a new version comes out with some compelling features, you have to do a lot of work to upgrade. With a resourceful plugin, upgrades are relatively painless. When you install Sandstone, for instance, it copies a series of controllers, models, and views into your app folder so you can tweak them to your heart’s desire. The bulk of the core functionality, however, resides in modules defined in the plugin (which are included in the copied files). To upgrade, then, you just update the plugin and leave the copied files alone. The only problems you’ll run into are ones where the new version of the plugin adds some significant new functionality (with new controllers, models, and views), but we have a strategy for dealing with that easily, too.

The other aspect of the Sandstone project (and our other resourceful plugins) that excites me is the fact that we’re open sourcing it. If you’re interested, you can grab the current version of Sandstone (so new it doesn’t even have a version number!) from http://svn.extendviget.com/lab/sandstone/trunk. If you’d like to contribute, we have Trac set up, so you can open bugs and feature requests and otherwise participate in the process. We’re hoping that Sandstone can help meet the needs of a lot of developers, so we welcome your feedback.

Update: Changed Trac URL to reflect the project’s new location

image taken by Ozyman; from http://www.flickr.com/photos/ozyman/211749949/

Will Ruby and Rails Scale?

Brian Wynne Williams
Brian Wynne Williams, CEO & Co-Founder, June 22, 2007 2

“Can Ruby on Rails scale when my web traffic takes off like a rocket ship?”

This is a common question we get (or some variation).  I have a simple answer:

“Yes, it can.”

As with any technology or framework, it’s easy to build something that won’t scale.  Furthermore, there are applications where Ruby/Rails isn’t the right solution.  However, we believe that Rails will scale fine if you make smart architecture decisions.  Heavily-used apps like Basecamp and large-scale sites like Revolution Health show this; but, lately people like to talk about Twitter‘s problems.

Silicon Valley-based Powerset just announced that they’re building their front-end in Ruby (though not necessarily Rails).  They addressed the question of scaling and Twitter’s situation with some first-hand insight:


We’re not worried about scalingSo, inevitably, whenever we talk about Ruby or Rails scaling these days, someone brings up Twitter and its scaling problems in the past. Twitter is right down the block from our offices and I know several of the devs personally, so before we made a final decision I arranged a sit down with Twitter’s lead developer, Blaine Cook, to talk about the situation. Blaine was kind enough to let me bring along our Search Architect (and former search architect at Yahoo!) Chad Walters, our Head of Product Scott Prevost, and our COO Steve Newcomb, to poke and prod and get their questions answered. The simple fact is that Ruby wasn’t the source of Twitter’s woes. As it often happens with rapidly-growing sites, they ran into architectural problems. Some design decisions don’t hurt until they reach a massive scale and, at that point, you have to rethink your approach. In an email he writes:

For us, it’s really about scaling horizontally - to that end, Rails and Ruby haven’t been stumbling blocks, compared to any other language or framework. The performance boosts associated with a “faster” language would give us a 10-20% improvement; but, thanks to architectural changes that Ruby and Rails happily accommodated, Twitter is 10,000% faster than it was in January.


Twitter’s explosion of growth in March certainly created pain points for them (gotta love slide 7 here) and a lot of lessons learned; but, it’s not an indication that the framework inherently won’t scale.

Our belief is that when building a web app, agility is more important that built-in scalability.  “Premature optimization” causes more problems than it prevents.  Focus on building a site that people will really use, then refactor and optimize over time as your audience grows.  Rails is made for agility.  You always hear about development speed, but test-driven development is easier and faster in Rails as well.  Both factors mean that making architecture improvements to an already-deployed site is more practical.

Regardless of technology, build with scaling in mind, not necessarily built-in.  Friendster didn’t scale, but that seemed to be a management decision.  Had Twitter obsessed about trying to build for the number of users it’s supporting today, they probably never would have made it out of the gates.  And then how would I possibly know that Darth Vader just ate a burrito?

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 »

Upcoming Events

RailsConf - May 29 to June 1
Senior Developer Ben Scofield is presenting "Advanced RESTful Rails" at RailsConf

O’Reilly’s Open Source Convention - July 21 - 25
Clinton R. Nixon, our other Senior Developer, will be speaking on "Extending Rails: Understanding and Building Plugins."

Recent Comments

Hi Matt - thanks for the great post! This looks like a very cool way to configure a server - I have one question and excuse my ignorance (Linux newbie): Why do you need to create a “deploy” user at first (as opposed to just using the root account)? Is that actually necessary for running setup_env, or only needed later for regular deployment? Thanks!