Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Web Development

What's New in Rails 2.x

Deepak is a Sun Certified Java 1.4 Programmer and Sun Certified Web Component Developer for J2EE.

Rails is an open-source framework for developing web applications. Release 2.0, a major update to the Rails framework, was made available in December 2007 and includes a load of new features and fixes. More recently this was followed by Rails 2.1 (available for download here). In this article, I examine some of the major new features in Rails 2.x.

To install Rails 2.x, simply run the following command:

gem install rails -y

The output from the command (Figure 1)shows that the most recent version, Rails 2.1, has been installed. The rails 2.1.0, activesupport-2.1.0, activerecord-2.1.0, actionpack-2.1.0, actionmailer-2.1.0, and activeresource-2.1.0 gems get installed.

[Click image to view at full size]
Figure 1: Installing Rails.

Rails Web Services

RESTful web services have additional support, while the ActionWebService gem has been removed from the default package. ActiveResource gem has been added to the default bundle. In Rails 2.0 RESTful routes use a new custom delimiter. For example, a custom action route is defined as follows:

map.resources :catalog, :collection => { :entry => :get }

Before Rails 2.0, the resulting route uses a semicolon (;) to delimit the custom action:

GET /catalog;entry

In Rails 2.1 you use the standard forward slash (/):

GET /catalog/entry

In Rails 2.1, nested REST resources have been replaced with has_one and has_many to define resource associations. For example, associations between resources using the nested resources is defined as follows in config/routes.rb:

map.resources :catalogs do |catalogs|
  posts.resource :journal
  posts.resource :edition
  posts.resources :entries

In the example, the catalogs resource is mapped to journal, edition, and entries resources. Using has_one and has_many, the associations between resources may be defined as follows:

map.resources :catalogs, :has_one => [:author,:edition],:has_many => [:entries]

Named prefixes in nested resources is no longer required in Rails 2.0. Previously you had to specify a named prefix using the name_prefix option as follows:

map.resources :catalogs do |catalogs|
  catalogs.resources :entries, :name_prefix => "catalog_"

In Rails 2.0 named prefix is implicit. For example, the following nested resource provides a helper method catalog_entries_url(catalog_id):

map.resources :catalogs do |catalogs|
  catalogs.resources :entries

If you don't want the named prefix to be implicit set name_prefix to nil explicitly.

map.resources :catalogs do |catalogs|
  catalogs.resources :entries, :name_prefix => nil

In Rails 2.0 the namespace feature (map.namespace) has been added to the routing resources. Using the namespace feature, an admin interface may be defined like this:

map.namespace(:admin) do |admin|
  admin.resources :journals,
    :collection => { :catalog => :get },
    :member     => { :duplicate => :post },
    :has_many   => [ :articles, :images ]

The admin interface generates the admin_journals_url, which points to "admin/journals" and looks for the Admin::JournalsController. Corresponding to the has_many relationship the admin_journal_articles_url, which points to "admin/journals/#{journal_id}/articles" and looks for Admin::ArticlesController, is also created. The "rake routes" task has been added to list all the named routes. A new feature in ActiveResource is that the ability to invoke custom methods has been added. Consider a REST web service that has the standard CRUD-based actions for a Employee class including a custom element method promoted and a custom collection method sorted. The ActiveResource class Employee is defined as follows:


class Employee < ActiveResource::Base
  self.site = "http://employeeblog.com/"

The custom methods are invoked using one of GET, POST, PUT, or DELETE. For a collection custom method the get/post/put/delete is invoked on the class and for a element custom method the get/post/put/delete is invoked on an instance of the class. You would invoke the collection custom method sorted with the following URI:

GET /employees/sorted.xml?by=first_name

In the ActiveResource, the collection method sorted is invoked this way:

employees = Employee.get(:sorted, :by => 'first_name')

The custom collection method sorted is specified as the first argument to the get method. Similarly the custom element method promoted is invoked with the following URI:

PUT /employees/1/promoted.xml?position=Manager

In the ActiveResource the custom element method promoted is invoked by specifying the method as the first argument to the put method:

steve = Employee.find(1)
steve.put(:promoted, :position => 'Manager')

The ActiveResource find method supports a new option called :from for a custom method or a resource. The first argument to the find method specifies a resource id or the scope (:all, :first, :one). For example, all the recent catalog entries can be found as follows:

Catalog.find(:all, :from => :recent)

ActiveResource also supports custom headers using the headers option. In the following example, every request from Catalog would include the specified header:


class Catalog < ActiveResource::Base
  headers['X-MyHeader'] = 'steve'

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.