Article

Home » Server-side Coding » Ruby & Rails » Get On Track with Ruby on Rails
SitePoint Feature Article

About the Author

Daniel Bogan

Daniel is a Sydney-based neurotic web monster, who spends most of his life buried inside Rails applications and playing video games. Sometimes at the same time. You can find him at waferbaby.com.

View all articles by Daniel Bogan...

Get On Track with Ruby on Rails

By Daniel Bogan

March 22nd, 2006

Reader Rating: 9

Page: 1 2 Next

Ruby? Rails? Ajax? Is this cluster of confusing buzzwords swarming around your head like a mob of angry bees? Then fear not, gentle padawan -- Jedi help is at hand! For I, too, was just like you once: confused, jumping at shadows, sinking into the depths of yet another custom Python web framework while softly weeping behind a stack of dog-eared PHP books. But not anymore. Today I build my applications in Ruby on Rails.

Rubbing the Rails

So what exactly is this Ruby on Rails thing? We're talking He-man and Battle Cat ... well, almost. Ruby on Rails combines two separate elements -- Ruby, the object-oriented scripting language, and Rails, the popular web framework built on top of Ruby -- to form a powerful new whole.

Ruby?

Ruby is an interpreted scripting language, just like Python and PHP. The code you write, break and swear over is converted into machine code as it's processed. Invented in Japan (hai!), the object-oriented language has become increasingly popular for building web-based applications and useful script utilities.

OOP is a Good Thing (TM) when it's done right, and Ruby nails it. This language is about as object-oriented as it gets: in Ruby, everything is an object.

Here's a little sample Ruby code to whet your appetite:


class MyClass
 
 def initialize
   @message = "My name is I.P. Freely\n"
 end
 
 def be_witty
   print @message
 end

end

my_joke = MyClass.new
my_joke.be_witty

As you can see, Ruby terminates code with a line break instead of a semicolon. Like seriously dude, colons are soooooo 90's! The above snippet introduces a whole bag of Ruby syntax: we're creating a new class (MyClass) and defining two methods, initialize, which is called automatically upon object creation, and be_witty, which prints (to standard output) the value of @message -- a classic of childhood prank calls.

Variables in Ruby can take different prefixes depending on where you want to use them:

  • @@variable is a class variable, available across every instance of that particular class
  • @variable is an instance variable, available only to one particular instance of the class
  • variable is a local variable, available only to the context in which it's created and used

To use our class, we must first instantiate it. We do this with the MyClass.new statement. Thus, my_joke is now an instance of MyClass, and we can use our freshly hatched object to call any of the methods we've stuck inside our oh-so-funny class.

Can you guess what happens next? Hilarity ensues, of course! Attractive members of the opposite sex shower us with praise!

From this simple overview, we've grown together and learnt that:

  • A class in Ruby is defined by the class keyword, with a CamelCase'd name
  • Methods begin with def and are completed by an end keyword
  • Classes are also completed using an end keyword
  • Method names, by convention (though it's one that's not enforced), have words separated by underscores
  • An instance of a class is created with the [class name].new method
  • The author needs to grow up

Rails?

So where does Rails fit into the picture, and why should you give a darn?

You should give a darn because, without Rails, Ruby is nothing! What was He-man without Battle cat? What's an engine without wheels? If Ruby is the engine, Rails is the body and the wheels -- a souped-up web framework nestled lovingly around a fuel-injected gem of a core. You don't need me to tell you that a good web framework can make all the difference between shipping 1.0 of your Web 2.0 app, and shipping a steaming pile of hot vapourware. In fact, Rails itself springs from the former: a nice little application called Basecamp, by 37 Signals.

Okay, now you know where it hailed from, but what does it actually do? The official Rails description reads:

Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern, From the Ajax in the view, to the request and response in the controller, to the domain model wrapping the database, Rails gives you a pure-Ruby development environment. To go live, all you need to add is a database and a web server.

"Wait a minute," I hear you cry. "Model-View-Controller? Domain model? My rash is getting worse! HELP!". Calm down. Take a few deep breaths and down another swig of that ÜberJolt, because we're going to get through this together. We're a team.

Model-View-Controller (or MVC) is a neat, tried-and-tested design approach. A Model represents one particular object (say, a Picture, a Person, a Folder, or Claudia Schiffer), a View is some sort of output from a given Model, and a Controller ties the previous two together by acting as a mediator.

In Rails, a Model and a Controller are Ruby classes, and Views are usually XHTML files. Rails runs through a dispatcher via your web server. Controllers take requested URLs (say, /list/1) and turn them into method calls: Controller.list(1).

As for that mention of a "domain model wrapping the database", this involves neither .com or Marshall Mathers (at the time of writing, anyhow). Rails has magical database object modeling powers that link tables to models, and allow you to manipulate table contents without needing to write a lick of SQL.

Installation

Let's go ahead and get this beast installed.

A number of installation options are available for both Ruby and Rails on various platforms. Windows users would do well to check out Instant Rails.

For OS X, I'd recommend Locomotive. As for you hardcore *nix and BSD users, I'm sure you're savvy enough with RPMs and ports to get yourself up and running.

If you've decided on Instant Rails, or you're installing things manually, you'll also need to grab hold of the SQLite database (Locomotive includes this for you). Pre-compiled binaries are available for download -- make sure you get version 3. You'll also need the Ruby bindings for SQLite 3.If you get stuck, be sure to check out the official Rails wiki for installation instructions.

It's one thing to tell you what Ruby on Rails is all about, but it's another to actually show you. Now that you've got both Ruby and Rails installed, why don't we jump in the deep end and build ourselves a no-nonsense, almost useful application?

Learn by Doing

A shopping list -- programming really doesn't get any more serious or useful than that! Remember that attractive member of the opposite sex, the one who laughed so heartily at our joke earlier? Imagine if we invited that person home for dinner, and forgot to buy the necessary groceries for our meal!

To prevent this catastrophe, we're going to be building a simple little shopping list -- nothing too fancypants, but hopefully it will be enough to give you some idea of how things in Rails are put together, and ensure that you cook a drop-dead delicious dinner.

Let's start by opening up a terminal window and moving into a directory of your choosing. The exact location isn't important, so long as you remember where it is. Me, I'm going to be working on my Desktop:

And now the fun begins! Type in:

> rails ShoppingList

If everything goes according to plan, you'll see a bunch of text go flying past and be thrown back to your prompt -- Rails magic is happening! If this didn't work, you might want to kick me in the face and check the installation instructions again.

So what just happened? The rails command created the skeleton of our app: we now have a folder called ShoppingList (hereafter SL), populated with all of the sub-folders Rails needs to function. The most important ones we'll be dealing with in this article are:

  • app - Models, views and controllers specific to our application will live here
  • db - We'll be storing our database in here
  • config - Our database and environment settings
  • public - Files that are visible via a web browser - our stylesheets, Javascript files, etc. - live here
  • script - Handy tools to make our Rails life easier

Let's get busy.

Model

Since we're building a Shopping List, we'll need some sort of Model to represent the individual items in the list. Let's call it List Item. To make this Model useful, it's going to need some data, so let's go ahead and assume that each of these items is going to have its own id, name, cost, and quantity. In pseudocode, that might look something like this:

model ListItem

 id (integer)

 name (string)

 cost (float)

 quantity (integer)

Cool. Now let's go ahead and build the Model! Making sure you're still inside the SL, type in:

> ./script/generate model ListItem

The generate script is a nifty workhorse, and you'll use it a fair bit in your Rails coding. It creates models, controllers and anything else you tell it to, and you can download and install new generators to extend it. Personally, I'm still waiting for it to make me coffee. In the command above, we've instructed it to build all the necessary files and folders for our Model called ListItem (there's that CamelCase again):

Open up the list_item.rb file inside the app/models/ folder -- this is our Model's class file -- and you'll see that the script has also built the necessary skeleton code to make things work:

class ListItem < ActiveRecord::Base

end

This class definition looks a little different from our first example, doesn't it? That's because ListItem is a subclass of another class. A subclass is identified by the '<' character. Our parent class is ActiveRecord::Base, and ListItem inherits everything ActiveReacord::Base can do. Remember that I said Rails has magical database modeling powers?

That power is ActiveRecord.

Database

Of course, that's only the code side of our Model. What about its mysterious underbelly? Time to slit it open and set up our database! As we're already covering a swath of potentially confusing topics as it is, I've elected to use the lightweight and simple SQLite for this lil' app.

In your terminal window, move into the 'db' folder inside SL and type:

> sqlite3 storage.db

We've just opened up a SQLite console and created a blank database file called storage.db. Let's go ahead and populate this with hot, juicy table action by turning our pseudocode into real SQL gravy. In your console, enter the following:

> create table list_items (id integer primary key, name text, cost float, quantity integer);

We now have a table ready for ActiveRecord to play with. You'll notice that I made the name of the table a plural. ActiveRecord ties your model to its table by comparing the names of the classes to that of the table; thus, our class ListItem becomes our table list_items (plural, lowercased, underscore-separated). You can, of course, change this name if you so desire. For example, you might need to do so if you were moving a legacy application across to Rails and already had a populated database.

To quit out of the SQLite console, type:

> .quit

We've now built a happy little database and furnished it with a brand-new table. But for it to be of any use, we need to let Rails know its particulars. Using your favourite text editor, open up the database.yml file inside the config folder in SL. Delete all of the existing example text and replace it with the following:

development:

 adapter: sqlite3
 database: db/storage.db

test:

 adapter: sqlite3
 database: db/storage-test.db

production:

 adapter: sqlite3
 database: db/storage.db

Rails works in three different modes: development, test, and production. Various settings are optimised for each particular mode. We'll focus only on the first and last ones for now -- testing is a whole new article.

Controller

Let's move on and complete the MVC triangle by creating a controller and building Views to present the ListItem Model via the web. Again, we turn to our trusty steed, the generate script. Making sure you're still in the main SL folder, type:

> ./script/generate controller ListItems

As with the ListItem model, this creates all the necessary files and folders to bring our new controller to life:

Open up the new list_items_controller.rb file inside app/controllers, and you'll see another skeleton class:

class ListItemsController < ApplicationController

end

In this particular case, our ListItemsController (along with any other controller we create) is a subclass of ApplicationController, which Rails created when it built our application's skeleton. Open up the application.rb file and you'll see:

class ApplicationController < ActionController::Base

end

As with the ActionRecord::Base class for our Model, ActionController::Base is where the magic happens. The base controller handles all the conversion from URLs to a controller's methods. By default, the name of the controller will govern the URLs that your Rails application is going to use. Because our controller is called ListItemsController, we'll be able to interact with it automatically via /list_items/.

Thus, if we had a method called create_boring_rails_article, hitting up /list_items/create_boring_rails_article/ would work.

Before we go fleshing out the controller and building our Views, let's take advantage of another built-in Rails feature called scaffolding. Scaffolding can automatically generate, on the fly, all of the CRUD methods -- Create, Retrieve, Update, Delete -- that we need to play with our Model.

We're going to edit our Controller, so open up the list_items_controller.rb file again and modify the class to look like this:

class ListItemsController < ApplicationController
 scaffold :list_item
end

The scaffold command tells Rails we want to enable scaffolding for the list_item Model inside this Controller.

But hang on -- why is there a colon in front of the list_item? Because it's a Ruby symbol, an object that's used to reference other objects, regardless of context. You'll see a lot of these used in both Ruby and Rails.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article