Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Crossing borders: What's the secret sauce in Ruby on Rails?

Lessons we can learn from the Rails framework

Bruce Tate (bruce.tate@j2life.com), President, RapidRed
Bruce Tate
Bruce Tate is a father, mountain biker, and kayaker in Austin, Texas. He's the author of three best-selling Java books, including the Jolt winner Better, Faster, Lighter Java. He recently released Beyond Java.. He spent 13 years at IBM and is now the founder of the RapidRed consultancy, where he specializes in lightweight development strategies and architectures based on Java technology and Ruby on Rails. 

Summary:  Ruby on Rails seems to be a lightning rod for controversy. At the heart of most of the controversy lies amazing productivity claims. Crossing Borders author Bruce Tate has come to understand that Rails isn't a better hammer; it's a different kind of tool. This article explores the compromises and design decisions that went into making Rails so productive within its niche. Then it looks at Rails-inspired ideas that should get more attention within the Java™ community.

View more content in this series

Date:  09 May 2006
Level:  Intermediate
Also available in:   Chinese  Russian

Activity:  3211 views
Comments:  

Ruby on Rails (aka Rails) is a Ruby framework for database-backed Internet applications. I've now used Rails for two different applications and been involved with two others as an associate. For an upcoming book called Java to Ruby (see Resources), I've interviewed many Rails developers (people who have both succeeded and failed with the framework), the framework's founder, and the lead author of the flagship Rails book Agile Web Development with Rails (see Resources). I'm starting to understand why the Ruby on Rails framework is so successful.

Hype and skepticism

Debates about Rails in the Java community have been intense and show no sign of dying down any time soon. Rails proponents boast of incredible productivity, with some claims of 10 to 1 over Java development. As a Java programmer, your knee-jerk response is to dismiss any wild productivity claims because you've likely heard them before and been disappointed. Java advocates increasingly insist that Ruby on Rails is a toy that can't scale, produces bad code, and won't work beyond the simplest applications. But as Rails praise keeps popping up -- often from credible sources -- a more prudent course might be to understand what Rails does well and to bring those ideas back to the Java platform. In this article, I'll explore the core features -- the secret sauce -- that are the essence of Rails's great productivity.

About this series

In the Crossing borders series, author Bruce Tate advances the notion that today's Java programmers are well served by learning other approaches and languages. The programming landscape has changed since Java technology was the obvious best choice for all development projects. Other frameworks are shaping the way Java frameworks are built, and the concepts you learn from other languages can inform your Java programming. The Python (or Ruby, or Smalltalk, or ... fill in the blank) code you write can change the way that you approach Java coding.

This series introduces you to programming concepts and techniques that are radically different from, but also directly applicable to, Java development. In some cases, you'll need to integrate the technology to take advantage of it. In others, you'll be able to apply the concepts directly. The individual tool isn't as important as the idea that other languages and frameworks can influence developers, frameworks, and even fundamental approaches in the Java community.

Rails philosophies

The Ruby on Rails framework is not a typical application-development framework by any stretch of the imagination. Rails founder David Heinemeier Hansson often calls the framework opinionated software, and he enjoys breaking long-standing conventions. David has made strong philosophical decisions and strictly follows them throughout the framework. Some of the core opinions pervasive within Rails are:

  • Seamless integration: Rails makes brilliant use of the best features of the Ruby language. It extends Ruby in ways that often make it hard to tell where Ruby ends and Rails begins. You also see nice integration between Active Record (the Rails persistence engine) and the model-view-controller (MVC) framework. For example, you can write three lines of code, create a table, and then immediately generate a user interface for that model.

  • Convention over configuration: To keep perfect flexibility, Java frameworks maintain massive, pervasive configuration files. Rails rejects this strategy. It assumes a common project directory structure and simple, common naming conventions for methods, classes, tables, and columns to infer much of what's configured in Java applications. As a result, Rails applications need a fraction of the configuration code of Java counterparts, often by a factor of 10 or more.

  • Low repetition: Don't Repeat Yourself, or DRY, is a common buzzword within the Rails community. Rails framework committers seek to abstract out repetitive tasks with methods that often look like extensions of the Ruby language. As you saw in the third article in this series, Rails's metaprogramming strategy makes each line of code work harder.

  • Immediate feedback: With Rails, most of what you do can give you immediate feedback. You write a line of code and save, and your change is active when you load your next Web page. Migrations can instantly show you changes after updates to your database.

A practical basis

The opinions that underlie Ruby on Rails are all well grounded in practical experience. The Rails framework grew out of practical use in the development of the popular Basecamp project-management application (see Resources).

Focus on a niche

The argument against wild productivity claims usually goes something like this: If I've got a decent hammer, I'd be hard-pressed to find another hammer to make me twice as productive, let alone 5 to 10 times more productive, because hammers have evolved over thousands of years. But people who compare Ruby on Rails with a mix of general-purpose Java frameworks are missing the point. You can be 10 times more productive for some problems by radically changing the nature of the tool. Professional framers now use nail guns that can drive in dozens of nails in the time it takes to hammer in one nail. Like nail guns, Rails is specialized. It's a framework written with a laser focus on a single niche: new database-backed Web applications.

I'd guess that as many as half of the applications built today are database-backed, Web-enabled applications. So Rails is definitely a niche product, but its niche is large and important. Specializing in this space gives Rails huge advantages that account for the big splash that it has made. By focusing on projects in this niche, Rails designers can take some shortcuts that other frameworks cannot or should not take. This specialization often sacrifices flexibility for simplicity.

New, database-backed applications suggest a wrapping approach over a mapping approach. As you saw in the first article in this series, Rails tools assume conventions in the data model. Rails applications need a fraction of the model code found in Java applications. If you're creating your schema especially for your Rails applications, this philosophy works well. If you're trying to shoehorn a legacy schema into Rails, things will go less smoothly.

Web-based applications allow a similar set of optimizations. When you know an application is Web-based, you know the general structure of the application and the major components that it's likely to need. The following features are enhanced in Rails because the Rails focus is on Web-based applications:

  • Model-view-controller: The Rails MVC framework -- called Action Pack -- is customized for Web-based access and implements a well-known design strategy called Model 2 (see Resources). The Rails version has optimized integration between the controller and view that minimizes configuration and automatically makes controller instance variables available to the view.

  • Project directory structure: Rails applications all have the same project structure, with directories to handle application code, database configuration, public static files, and scripts for managing Web servers and Web-based functional testing.

  • Architecture: The Rails framework simplifies architecture by providing out-of-the box scripts that generate application components that all adhere to common architectural goals, such as page-level and fragment-level caching; two-tier design; and environments for test, development, and production.

  • Tooling: The Rails tooling is specialized for the Web. The logging support, breakpointer, profiler, and testing frameworks are all tailored for Web-based applications and enabled for two-tier operation.

But nail guns will never replace hammers, and we'd be foolish to expect complete replacement. Hammers will always do things that nail guns can't. Rails will never be a tool for enterprise integration, object-relational mapping, or full-stack Web services. The best you can hope for from Rails is a specialized tool that fills its niche well.


The developer experience

As you start to dig under the covers, you begin to understand how radically different the Rails developer experience can be. A rapid feedback loop, interactive consoles at every turn, and convention over configuration all enhance the developer experience with dimensions not frequently available in Java frameworks.

The feedback loop

One of the most important factors in developer productivity is the overall feedback loop. The feedback loop is the amount of time between making a change in code and seeing the results in the execution of your application on the screen. In Rails, you get instantaneous feedback as you code. That feature is most notable when you make changes to your Ruby code. You can immediately load a browser page to see the results of your changes. Because I don't need to compile or deploy during development, I tend to make only tiny programming changes before I reload my browser or execute my test cases. Just about every Java developer who begins to use Rails codes in smaller chunks.

You might expect a rapid feedback loop that's friendly to the developer experience to be hostile to production applications. After all, the frequent class reloads that enable the rapid feedback loop should slow production applications to a crawl. But Rails works around this problem by giving you different environments for deployment and development. The development environment forces frequent class reloads at the expense of application performance, and the production environment reduces reloads to a bare minimum, providing a fast end-user experience at the expense of a rapid feedback loop for the developer.

Interactivity

The interactive experience of Ruby also contributes to Rails. You might expect debugging a Rails application without a full IDE to be a painful experience. It's not. Rails provides two features that simplify debugging. One of them is the breakpointer, which lets you add the breakpoint keyword to your source code.

To see the breakpointer in action, create a simple Rails application, generate a controller, start the server, and start a breakpointer. Make sure you have access to the breakpointer window, because you'll use it when Ruby encounters the breakpoint. Using Windows, the sequence looks like this:

>rails sample
>cd sample
>ruby script/generate controller samples
>start ruby script\server
>start ruby script\breakpointer

If you're running in UNIX® or Mac OS X, just make sure that your server starts in a separate process.

Type or paste the following code into the app/controllers/samples_controller.rb file:

class SamplesController < ApplicationController
  def index
    breakpoint
    @session[:message] = "hi, mom"
    render_text "Showing index"
  end

  def show
    render_text @session[:message]
  end
end

Test the code by loading the pages localhost:3000/samples and localhost:3000/samples/show.

When Rails executes the breakpoint, the application hangs. The breakpointer window opens a Ruby interpreter with the environment having the current state of the controller. You can then issue Ruby commands to query the state of your session, execute methods, and query variables:

> puts @session[:message]
-> hi, mom

This nice touch doesn't give you a full debugger, but you do have some capabilities that Java debuggers don't give you, including access to a full interpreter and the ability to execute methods on your application.

The second feature that simplifies debugging is the Active Record console. In the first article in this series, you saw that Rails also comes with a script that lets you work with your persistent objects in an interactive Ruby interpreter window. I've often wanted such a capability within my Java applications. You can code a persistent model, make changes to the database through the model, and then run some database queries to see their impact on the system. It would be nice to be able to query Hibernate objects in a similar setting.

Convention over configuration

Convention over configuration also leads to "aha!" moments for new Rails developers because the controller and model code is so concise. You saw in the first article that by leaning on the Rails environment, you can get some pretty advanced behavior out of some very thin classes -- by adopting Rails naming conventions and letting Rails infer your application's connection points instead of configuring them directly. To review, a Person object with many attributes and a one-to-many relationship with a department might look like this:

class Person < Active Record::Base
belongs_to :department
end

No configuration is necessary because Rails infers the name of the table (people), the name of the object identifier and primary key (id), the name of the related table (departments), the name of the foreign key (department_id), and the name of the foreign class (department.rb) based on naming conventions. The code remains simple, light, and very easy on the eyes, whether you're writing, reading, or maintaining it. Intentions are immediately clear.


What can Java developers learn?

I don't recommend that we build a better Rails in the Java language. Instead, Java developers should learn some lessons from the Rails framework and seek to build or enhance Java frameworks to do all of the following:

  • Enable hot deploy where it will shorten the development feedback loop or support frameworks that enable hot deploy. This priority should be much higher on the Java side than it is now.

  • Use less XML and more convention. Conventions don't rule out configuration because you can use conventions to specify meaningful defaults and configuration to override convention. Using this approach, as Rails does, you get the best of both worlds: concise code with less repetition without sacrificing flexibility.

  • Work to incorporate more scripting languages, including BeanShell (see Resources), for exploring Java classes during the debugging process.

  • Use the right tool for the job. Don't necessarily reach for Hibernate just because you need persistence or reach for Struts just because you need a Web application.

By incorporating the best features of other programming languages, you might not reproduce Rails, but you definitely can improve the Java experience.


Resources

Learn

Get products and technologies

  • Ruby on Rails: Download the open source Ruby on Rails Web framework.

  • Ruby: Get Ruby from the project Web site.

About the author

Bruce Tate

Bruce Tate is a father, mountain biker, and kayaker in Austin, Texas. He's the author of three best-selling Java books, including the Jolt winner Better, Faster, Lighter Java. He recently released Beyond Java.. He spent 13 years at IBM and is now the founder of the RapidRed consultancy, where he specializes in lightweight development strategies and architectures based on Java technology and Ruby on Rails. 

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Web development
ArticleID=110977
ArticleTitle=Crossing borders: What's the secret sauce in Ruby on Rails?
publish-date=05092006