« In Portland, @ OSCON | Main | Open Tagging »
Ruby on Rails (OSCON 2005 Tutorial)
I went to David Heinemeier Hansson’s tutorial on Ruby on Rails this afternoon. David’s first application in Ruby was Basecamp. He’d had 5 years of PHP experience and didn’t even consider himself a programmer. He claims that even people who aren’t language nuts can love Ruby and he created Rails to make it easy. (BTW, I brushed up my Ruby last week by reading “Why’s (poignant) Guide to Ruby (with cartoon foxes)”. Recommended.
David’s calls a “blogging package” the “hello world” program of the Internet age and he intends to create one today in the tutorial. The blog will have posts (natch), comments, … What’s needed?
- Ruby 1.8.2
- Database (pick one of six)
- The RubyGems package manager (like CPAN, maybe?)
- A few Gems, like rails
We’re going to stat from a scaffold, build a domain model, and manage authentication. Rails comes with a program, called ‘rails’ that builds scaffolding, including directory structures and files, for a project. It’s not so much about creating boilerplate classes as it is just creating the file structure for the application. Later tools will use these assumptions.
Rails is layered on top of a built-in Ruby Web server that is added to a Rails project by default. Rails uses a generate command to generate various code stubs. Some, like a controller, are there by default, but you can write your own generators as well. Things created by a generator are available immediately on the Web site. Essentially, when you’re done with the generation, you can an application that “works” structurally and needs to have functionality added. That mimics closely the way I like to code on the Web: get the structure working and then incrementally ad functionality.
Building controllers is easy, so new actions can just be based on a new controller. One of the design decisions Rails developers face is when to create a new controller and when to embed and action in another controller.
Rails is architected around naming conventions. For example, creating a view called “foo” is associated with the “foo” action in the controller. If the action doesn’t explicitly render something, the controller looks for a view with the same name and renders it.
Once you’ve created a database and table (in this case in MySQL), you use the Rails’ generate command again, to create the file structure for Ruby model that links it. (As an aside, if you don’t like what you’ve created with “generate” you can use “destroy” to remove them all.) Using the scaffold method within the stubbed-out classes, creates a basic application for managing the table in the database including creating, editing, and deleting records. Scaffolding isn’t for building the applications so much as just getting started. A scaffold can be incrementally changed to create the real application. Pieces o the scaffolding can be made explicit using another generate command. Again, as you overwrite various pieces of the scaffold, you create the final application that you want.
The domain model reflects the database table structure and has declarative templates that allow linking tables together easily in one-to-one, one-to-many, and many-to-many relationships. Of course, if you’d rather if not reflect the structure, you can do that, but the default gives you a starting point that’s fairly far down the path to your application. All default actions are wrapped in transactions.
Layouts are the wrapping for the view files that do things like headers and footers. Rather than having each file include the header and footer, Rails has the layout include the view file.
Validation rules can be added to the domain model declaratively (“validate presence of …”). This automatically activates validation code in the view. Again, the validation can be incrementally changed to develop the final application behavior.
Filters are created in controllers and can require certain conditions to be true before specific methods are run. The filter condition is just a method, so it can be anything you like, and it’s linked to methods in the controller, which are actions in the application. David demonstrated this by creating an authorization function for creating and editing posts. In this case, the authenticate filter redirected to a login action on an account controller.
Part of the Rails package is the automatic generation of unit test scaffolding. Adding new unit tests is, like incrementally building out the functionality, a step-by-step process. Running them is easy since the scaffolding is already created. They act just like you’d expect them to with success and failure of assertions with appropriate messages. One nice feature, when you create the database, Rails creates duplicate tables for testing automatically and the tests are done there.
In addition to the unit tests for the domain, there are also functional tests that are automatically created for controllers. The functional tests use a little language or simulating Web browser interactions. Assertions can include what template is returned, what action is to be taken next, and session data.
This leaves the testing of the interaction between controllers and models. The unit tests and the functional tests on the controllers can be mixed to accomplish that objective. Breakpoints can be added to test methods. When the test reaches the breakpoint it halts and throws up a console with the context of the execution at that point that can be inspected. Very nice.
Rails bills itself as an end-to-end framework—that is, a development framework that handles not only the server side, but also the client side as well. On to AJAX!
The Javascript features of Rails is aimed at keeping programmers from writing Javascript. That is, it’s generated. Rails ships with four different Javascript libraries. They can be included in the layout.
The link_to and form_tag methods in Rails have analogs called link_to_remote and form_tag_remote. These take a URL to call (using XmlHTTPRequest) and an action (not a controller action, an AJAX action) to take when the call-back is complete. These AJAX actions are effects and so on that are included in the libraries. This makes it pretty easy to add AJAX features to Rail applications.
Rather than using Javascript on the client side to totally build the page when things change, Rails uses what it calls “partials,” blocks of HTML pages use for reuse, to rerender parts of a page on the server and pass them back for reinclusion on the page. That’s a simpler format for achieving page rewriting without refresh than building a model of the page on the client and rebuilding individual pieces and reuses the functionality that exists on the server to render the page (and its pieces) on the server to great effect.
One problem with this technique is that its difficult to add effects (like fading yellow to highlight what’s new) to just the new part. The hack that Rails uses is to pass information that the effect needs in a special X- header.
AJAX introduces new concerns to Web programming, like clearing the contents of a form when the page refreshes. Rails has helper functions for doing these housekeeping functions. This is made easier by the fact that Rails automatically ads IDs to tags.
This was one of those tutorials that you had to be in to appreciate. David was slinging code fast and furious and it was very good, but difficult to recreate in a blog entry. I have great respect for anyone who can write significant code in front of 100 people over a three hour period—with or without a script.
Posted by windley on August 1, 2005 6:02 PM





Comment from David Heinemeier Hansson at August 2, 2005 7:53 PM
I'm glad you enjoyed the show, Windley. Thanks for sharing.
Comment from George Moschovitis at August 6, 2005 1:32 AM
And if you like Ruby, you could also try Nitro, another Ruby Web Framework (http://www.nitrohq.com)