If you’re like me, you’re reading this on your bright-red custom-built laptop in a soothing rosemary-scented bubble bath, and you’re wondering, “Why do I want another interpreted programming language? I can find my way around Perl and PHP and maybe a little Python. And Unix shell scripting. I feel fine. Why do people keep talking about Ruby?”
Why Ruby is Cool
Like so many of the very coolest things, Ruby was invented in Japan in the ’90s. Ruby is purely object-oriented; even things like integers and strings have intrinsic methods and properties. So, for example, print "Webmonkey".reverse outputs “yeknombeW”. It’s a clean, pretty language, with a flexible, predictable syntax that’s easy to read and write, and comfortable for people coming from Perl or C.
It’s more than easy to learn and use though — it’s fun, especially if you use Why’s (Poignant) Guide to Ruby, an engrossing, whimsical adventure story that reads like a collaboration between Stanislaw Lem and Ed Lear and just happens to teach the reader Ruby (and the love of Ruby). (Note to editor:can you get this guy to write for Webmonkey?)
Why Rails Is Cool
Much of the attention being heaped on Ruby these days is fueled by Rails, a framework for using Ruby to make web applications. Ruby on Rails has been used for a handful of high-profile sites, such as Basecamp and Backpack.
Rails is much more than just a tube of glue with which to stick Ruby on the web. And of course, it’s possible to program web apps in Ruby without getting Rails involved — just tell Apache to invoke your Ruby scripts via CGI. Rails is a programming toolbox, with a wealth of pre-written code that implements the structure and many of the common functions of a database-driven site. That eliminates much of the preliminary busywork necessary to create such a site, but also enforces a tight, sane structure on the code, which has the effect of making development very facile. It’s like working in a well-organized company:it takes a little time to figure out who sits where and what they do, but once you understand the structure, you can use it to your advantage without having to make lots of micro-managerial decisions all the time.
Rails uses a model-view-controller style of architecture, in which the database and its representation (“model”), the user interface (“view”), and the functional logic (“controller”) of the application are all kept neatly separate. The advantages of this architecture can be debated, but at least it means you have to try pretty hard if you want to make an application that’s not clean, portable, and sharable.
And easy. All over the web you’ll find testaments to how “The first time I ever looked at Ruby on Rails, I built a mobile-platform, social-networked auction site in six hours with one hand, while making this awesome Ajax-enabled to-do-list manager with the other!”
Regardless of Rails’s actual merits, the enthusiasm — fueled by things like the Rails Day festival, in which hundreds of competing developers had 24 hours to build a web app — is contagious. Let’s join the party!
Installing Ruby and Rails
For integration into an existing web setup, Rails can run under Apache via CGI or FastCGI. It also comes conveniently bundled with its own web server software, WEBrick, which is written in Ruby and serves sites on port 3000 by default, making it easy to test RoR apps on a development machine.
Cool people who manage their own web servers can install first Ruby and then Rails (you’ll also need a database, like MySQL or PostgreSQL) and get started — the official installation instructions are more comprehensive, platform by platform, than I could ever hope to be. Rails hasn’t become a popular offering on hosting services the way Perl and PHP are. If you pay for hosting on a shared server, your experience may vary. You can beg the host to install it on the server, or install your own Rails and work around snags you encounter. If you just want a version to play around with on your local Windows machine, Curt Hibbs goes into painstaking detail here. We can just use the built-in web server to start with, and you can configure it to work with your Apache installation later.
However you get your RoR on your system, the procedure is pretty simple once it’s installed. Let’s take a stroll through building a basic application. How about a bookmark manager? We’re only going to walk through the starter steps, so if you want an actual full-featured bookmark manager at the end of the day, I am not your guy. I can only teach you to fish; poaching the result in a nice court-bouillon is up to you.
Grab your stopwatches — let’s see how long it takes to get this site off the ground.
Step one:Set up the database
Let’s create the MySQL database that Rails is going to use to store our bookmarks. Rails is particular about certain things. Mainly, it likes the primary key in the database table to be an auto-incremented integer called ‘id’, and the database table to have a plural name (i.e., ending in ‘s’). Ours will be “bookmarks”; woe unto you if you want Rails to organize your gooses. Me, I want the table to store a URL, a name, and a description for each bookmark. So, using my command-line MySQL interface, I create the database:
mysql> CREATE DATABASE bookmarker;
and then create and populate the table within it:
mysql> USE DATABASE bookmarker;
note: some versions of MySQL don’t require the DATABASE keyword.
mysql> CREATE TABLE bookmarks ( -> id SMALLINT (5) NOT NULL auto_increment, -> url VARCHAR (255), -> name VARCHAR (100), -> description VARCHAR (255), -> PRIMARY KEY (id) -> );
If you have a mouse and like to administer your MySQL in some snazzier way, feel free to use that instead.
Step two:Create the scaffolding
Now the magic begins. Regardless of the nature of a Rails app, the first step, once the database is in place, is to create a starter framework. In a nice fresh directory, we type the magic words on the command line:
And Rails automatically creates a directory called Bookmarker containing eleven subdirectories which constitute our budding application. Let’s pause here to take a brief look at what goes into a Rails app.
$ ls Bookmarker CHANGELOG README Rakefile app/ components/ config/ db/ doc/ lib/ log/ public/ script/ test/ vendor/
The app directory contains the meat of our application, including some elements you may remember from a few sections ago:
ls Bookmarker/app apis/ controllers/ helpers/ models/ views/
Within this directory, controllers contains the functional Ruby code that drives the application, models contains a description of the database, and views contains .rhtml template files that control the visible HTML output of the methods. There is one template for each method of our application.
What else? log contains logs, doc will contain documentation. script contains some helpful executable scripts for working with Rails. config contains configuration info, which we’ll set up right now.
config/database.yml is a YAML file that tells Rails where the database is. We open it in a text editor and modify the first stanza to reflect the database we created above:
development: adapter:mysql database:bookmarker host:localhost username:root password:''s3cr3t''
Next we use one of the included tools to generate the components of our application:
$ ruby ./Bookmarker/script/generate scaffold Bookmark
Models are capitalized, controllers are not. Don’t ask me why. Again, if your app delivers synergetic enterprise solutions leveraging seminal proto-alternative band fIREHOSE, you’re on your own.
We have just created a controller, a model and a handful of views. Let’s fire up WEBrick, Rails’ built-in web server software, on port 3000, so we can check out the site we just MADE! For the record, make sure there’s no firewall between you and WEBrick.
$ ruby ./Bookmarker/script/server
Now we point our browser to http://oursite.org:3000/bookmarks (because “bookmarks” is the name of the controller) and wow! We have a working bookmark manager. The scaffolding we created with a single line of typing already includes functions to create, delete and edit bookmarks. Stop the stopwatches! Do you see yet why people say this is easy? All that remains is customization.
Steps three and beyond:Customize the application
All the functions of the application — create, edit, destroy — are Ruby methods, defined in app/controllers/bookmarks_controller.rb, and each is displayed by an .rhtml template in the models directory. The core of Rails development involves modifying these files with custom code, to turn a basic Show-Edit-Destroy database front-end into a Ta-Da List. Let’s add a clickable link to each bookmark that points to the relevant URL. Let us take a look at views/list.rhtml.
Ruby’s .rhtml templates are Embedded Ruby, which uses %= and % tags to interpolate Ruby code into HTML documents. The former is used when you want the Ruby’s output displayed in the browser, the latter when you just want to run some method behind the scenes and not output anything. So in views/bookmark.rb, we see:
<td><%= link_to 'Show', :action => 'show', :id => bookmark %></td> <td><%= link_to 'Edit', :action => 'edit', :id => bookmark %></td>
That code, which runs once for each bookmark in the database table, uses Ruby’s link_to() method to create a href link tags on the page that invoke the show and edit methods. Let’s add another link, pointing to the bookmarked page, for each bookmark:
<td><%= link_to 'Open', bookmark["url"] %></td>
Simply enough, that creates a link whose text is “Open” and whose target is the URL value for the current bookmark.
Let’s look at one slightly more complicated example before we go our separate ways today. Since the bookmark manager just has users typing in URLs, we should check (at the very least) whether they have an “http://” prefix already before throwing up a link to them. As with many commonly desirable features, Rails has a pre-existing way to do that. In models/bookmark.rb, we add a method call to the class definition:
validates_format_of :url, :with => /^http:///, :message => "needs to begin with 'http'."
Now, when the user tries to create a new bookmark, that method will check the URL attribute against the regular expression, and, if it doesn’t begin with “http://”, then our little error message will be displayed. Documentation for the validates_format_of() method is available on the application site.
Go ahead and keep polishing the bookmarker app. Learn some Ruby — it almost learns itself! Add CSS to public/stylesheets/scaffold.css, add new functionality to the controller, modify the database model, hook in an Ajax bookmarklet, whatever you’d like.
Rails’ cleverness — things like auto-naming submit buttons after their actions — and Ruby’s flexibility — you can rewrite any method you don’t quite like — form a powerful combo. Because of Ruby’s reasonably intuitive way of doing things, getting from a starter scaffolding to a finished application is a short and pleasurable journey. If Rails sometimes seems like a domineering older sibling, insisting that you build your project the way it wants you to, well then, both of you probably still have some growing to do.