23 Jun 2006
It’s been observed that the success of Ruby on Rails isn’t due to any particular technical breakthrough or insight. The framework is basically just a collection of good ideas culled from elsewhere, packaged nicely and explained well, with a heapin’ helping of hype. One of those good ideas is passive code generators: tools that spit out application boilerplate for the developer to modify as needed. On the surface, code generators are simply about cutting keystrokes. But there are subtler implications as well: they lower the barrier to entry for new developers, they encourage consistency (both intra- and inter-project), and they create invitations to best practices, like unit testing.
After installation, code generation is the first thing a new Rails developer experiences:
rails myapp. (Unfortunately, the next step for newcomers is usually
script/generate scaffold, but that’s another story.) The generators are a large part of what makes Rails welcoming to first-timers, and pleasant for full-timers. And they cement community conventions, which is a huge benefit—every Rails app looks the same in terms of directory structure, file names, and configuration format. Learn how one Rails app is organized, and you’ve learned how they’re all organized.
Bells ring; singers sing; abstractions leak. For many Railsers—even experienced ones—generators involve some degree of voodoo. They make it easy to not understand how everything works. What are all those files? What’s actually required, and what’s just convention? The significance isn’t just academic. Someday, you’ll face a bug that requires understanding the generated code.
So let’s void the warranty, crack the case, shun the scripts, and build a Rails app from scratch. You’ll find it’s not hard. A minimal working Rails application needs only six directories, five files, and 19 lines of code—including configuration. Here’s how to do it.
I’ll assume that you’ve got Rails installed and working already (if not, see Curt’s introduction.) I’ll also assume MySQL is installed and accessible with the default permissions (username
root; blank password). And we’ll use the excellent Mongrel web server (
gem install mongrel) to serve the app. The command line examples are for a Unix-like OS, but the ideas transfer directly to Windows. This example will expect a database named
myapp, with one table named
people, with one column named
name. Go ahead and create a row in the table, with your name in it. Ready? Set?
mkdir myapp; cd myapp
mkdir log public app config app/controllers config/environments
require 'rubygems' require_gem 'rails' require 'initializer' RAILS_ROOT = File.join File.dirname(__FILE__), '..' Rails::Initializer.run
These lines pull in the framework (through the RubyGems package manager) and wind everything up. A stock environment.rb includes much more, providing configuration hooks and code to handle edge cases.
development: adapter: mysql database: myapp
Rails will assume reasonable defaults:
root for the username, a blank password, and
localhost for the host.
ActionController::Routing::Routes.draw do |map| map.connect '', :controller => 'people' end
class Person < ActiveRecord::Base; end class PeopleController < ActionController::Base def index @person = Person.find :first render :inline => "Hello, <%= @person.name %>" end end
Notice we don’t have an ApplicationController—it’s optional; your controllers can inherit directly from ActionController::Base. And we don’t have the models, helpers, or views directories. They aren’t needed; models can be defined anywhere, including application.rb.
That’s it—the minimal application, stripped it down to the rails. Moment of truth time: start it up by running
mongrel_rails start, and then point your browser to http://localhost:3000/. If all is well, you’ll see a hyper-minimal Rails app that exercises the whole stack, M, V, and C. Now stop to consider what’s not there: helpers, views, and model files, a bunch of directories (components, db, doc, lib, script, and vendor), dispatchers, Rake tasks, and tests. All of those things are technically optional. They’re conventional, convenient, and recommended—but not essential.
So is this the real man’s way to write Rails? Hell no. Rails’ generators are there for a reason, and there’s no reason to forgo them in your real work. But it’s a worthwhile exercise to go without them, at least once. Not only will you appreciate the shortcuts more, but your understanding of the framework will be stronger.
Have I overlooked anything else that can be cut? Left out something essential? Let me know!
P.S. Attending RailsConf this weekend in Chicago? I’d love to meet. I’ll be speaking at 10am Saturday morning—please stop by and introduce yourself!