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.

ActiveRecord

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
end

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
end

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
end

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

ActionController

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
  end

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

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

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
end

ActionView

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).

______________________

Comments

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'

Bart

Minor bug in RJS sample

Bill Mitchell's picture

www.iconbuffet.com/products/amsterdam

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.

Webmaster
Linux Journal

"I have always wished that my computer would be as easy to use as my telephone.
My wish has come true. I no longer know how to use my telephone."
-- Bjarne Stroustrup

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

rocky

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?

"I have always wished that my computer would be as easy to use as my telephone.
My wish has come true. I no longer know how to use my telephone."
-- Bjarne Stroustrup

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState