Rails Writ Large

Ruby on Rails 1.1 and the paradox of how constraints can lead to greater freedom.

Ruby on Rails is a framework for Web application development that promises—and delivers—a powerful, productive and fun platform for building dynamic Web sites. A framework can be thought of as a library—a collection of functions for your application to use—but it's also more than that, it's a system of constraints for your code. Why would constraints be a good thing? Because by embracing constraints for a specific purpose, you actually enable creativity by focusing energy on the problem at hand. The Rails framework is a set of constraints that enable effective Web development. To get a feel for how it works, let's look at the parts that make up Rails.


Like most Web application frameworks, Rails follows the Model-View-Controller (MVC) design pattern, which divides your code into three logical layers. The model layer consists of domain objects, backed by a database, and the Rails component for that job is ActiveRecord. Note the three major features of ActiveRecord: associations, callbacks and validations. Associations allow you to define relationships between your ActiveRecord classes, such as one-to-one, one-to-many and many-to-many. Here's how it looks:

class User < ActiveRecord::Base
  has_many   :projects
  has_one    :address
  belongs_to :department

Details that normally would require configuration (table names, foreign key names and so on) are inferred automatically, and object attributes are created automatically for every column in the database. Rails calls this convention over configuration. Callbacks provide a robust set of hooks into the life cycle of your objects, where you can add behavior. For example, when user record is saved for the first time, send a welcome e-mail:

class User < ActiveRecord::Base
  after_create :send_welcome_email
  after_update :update_audit_log

Validations are a special kind of callback that make standard data validation routines a cinch:

class User < ActiveRecord::Base
  validates_presence_of     :name
  validates_format_of       :phone, :with => /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/i
  validates_confirmation_of :email
  validates_acceptance_of   :terms_of_service, :message => "must be accepted"
  validates_inclusion_of    :age, :in => 0..99

By keeping your associations, callbacks and validations rules in the ActiveRecord class definition, you make it easier to create reliable, maintainable code.


ActionPack has two subcomponents that work together closely, ActionController and ActionView. ActionController classes define actions—public methods that are accessible from the Web. Actions always end in one of two ways: either with a redirect (an HTTP response header sent back, causing the client to be forwarded to another URL) or with a render (some content being sent back to the client, usually an HTML file). When an action does a render, ActionView is invoked. Take a look at an example controller, with three actions:

class MessagesController < ActionController::Base
  def list
    @messages = Message.find :all

              def show
    @message = Message.find params[:id]

  def create
    @message = Message.create params[:message]
    redirect_to :action => :show, :id => @message.id

The first action uses an ActiveRecord object to find all messages in the database and then renders the template messages/list.rhtml. The second action looks up one particular message by its ID and shows it. The third action also uses the ActiveRecord object, this time to save the parameters passed in from an HTML form. Then, it sends an HTTP redirect response, sending the user back to the show action.

Controllers and actions are mapped to URLs using routes. The default route is :controller/:action/:id, so without any additional configuration, the URL for the actions above would be /messages/list, /messages/show/1 and /messages/create.

In addition to actions, controllers also can have filters, which allow you to interrupt actions, and caches, which allow actions to execute faster. For example:

class MessagesController < ActionController::Base
  before_filter :authenticate, :except => :public
  caches_page   :public
  caches_action :show, :feed


ActionView is Rails' system for formatting the output of your application—usually HTML files. The primary mechanism is ERB, Embedded Ruby, which will be familiar to anyone who has used PHP or JSP-like syntax. Any template file with an .rhtml extension can have embedded Ruby snippets, inside of <% %> and <%= %> tags. The first kind doesn't output anything, the second does. For example:

<% for message in @messages %>
  <h2><%= message.title %></h2>
<% end %>

You also can create template partials to extract commonly used chunks of markup, and helpers are Ruby functions available within your templates to provide handy functionality, like drop-dead easy Ajax. Lastly, special templates called layouts can hold markup that is common to the whole project (like HTML headers and footers).



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

toggle's code doesn't work for me

Bart's picture

point 8) code doesn't work for me. Browser (FF/IE) complains with RJS error (RerefenceError:'blind_down' is not defined). Here are my *.rjs files

caused problem:
page.visual_effect :toggle_blind, 'element', :effect => 'blind_down'

works fine:
page.visual_effect :toggle_blind, 'element'


Minor bug in RJS sample

Bill Mitchell's picture


Click "add to cart", then click "remove from cart". Now try to click "add to cart." You can't because the buttons still say "remove." Buttons fail to refresh after removing from cart. Must reload page to see the add to cart button again.

This page displays too wide, requires horizontal scrolling for e

Randy Kramer's picture

This page displays too wide, requires horizontal scrolling for each line. I haven't tried to pinpoint the cause of the trouble.

You should limit lines to something around 80 characters, and/or make them (lines) wrap to the width of the page.

This page displays too wide

Keith Daniels's picture

I can't replicate this problem. I tested at 800x600 resolution and though the gray code blocks had horizontal scroll bars none of the body text was outside of the screen.

What browser are you using, what screen resolution and what operating system. It would also help if you would check that you have not changed any of you browser settings so that they override the style sheets on the web site.

Linux Journal

All the new OSs and windowing systems are oriented towards content consumption instead of content production.

--Steve Daniels 2013

print version runs off the line

bumparocky's picture

too wide for printing also....
print preview in the latest firefox, of the printer friently version, shows the lines getting chopped off


print version runs off the line

Keith Daniels's picture

Re: too wide for printing also....

Does the "also" imply that the horizontal scroll bars appear as well -- during regular viewing?

I too have the latest version of FireFox and the priter friendly version looks fine in FireFox's print preview.

The print preview of the regular web page does look funny but I think that is a FireFox problem dealing with complex multi column pages instead of a site problem.

Are you using the Windows version of FireFox? If not which Linux version are you using and what is the FireFox version?

All the new OSs and windowing systems are oriented towards content consumption instead of content production.

--Steve Daniels 2013