Welcome Rails 3.0

As of December 23, 2008, the Merb (Mongrel + Erb) project is being merged with Rails, and a version with the best features of both will be released in 2010 under the name Rails 3.

Main additions in Rails 3.0

– Brand new router with an emphasis on RESTful declarations
– New Action Mailer API modeled after Action Controller
– New Active Record chainable query language built on top of relational algebra
– Unobtrusive Javascript helpers with drivers for Prototype and jQuery

Almost every property of Rails has been upgraded in Rails 3.0. The following lists all the properties and its upgrades and additions to the earlier release:

The basic changes include the following :

Rails 3.0 supports only Ruby 1.8.7 and higher

Application Object

To run multiple Rails applications in the same process, a new concept called Application object has been introduced. An application object holds all the application specific configurations and is very similar in nature to config/environment.rb from the previous versions of Rails.

– Script/*

The new script/rails replaces all the scripts that used to be in the script directory.

Eg: instead of script/console
rails console
instead of script/generate scaffold post title:string
rails g scaffold post title:string

Gemfile and Bundler

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler, which then installs all your dependencies.
Bundler is a tool that manages gem dependencies for your ruby application. It is able to fetch, download, and install the
gems and all child dependencies specified in the manifest file.
The ‘gem install bundler’ command will install this gem.

– All Rails core component have been decoupled.

Rails core components are now using the same API that you can use for developing plugins.This means any plugin you make can access all the functionality that the Rails core components have access to.
ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.


Arel is an Object_Oriented interpretation of Relation Algebra. It provides an SQL abstraction that simplifies Active Record and provides the foundation for the relation functionality in Active Record. More about Arel is discussed in the Active Record part of the article.


– An Internationalization gem called the I18n gem has been introduced which is used to support programming in various regional languages.


– Generators were given a lot of attention in Rails 3.0. Some of the many changes and additions made were:
Generators were completely rewritten and are backwards incompatible. Rails templates API and generators API are now merged. Generators are no longer loaded from special paths anymore, they are just found in the Ruby load path, so calling
rails generate foo will look for generators/foo_generator.
New generators provide hooks, so any template engine, ORM, test framework can easily hook in.
New generators allow you to override the templates by placing a copy at RAILS_ROOT/lib/templates.
Rails::Generators::TestCase is also supplied so you can create your own generators and test them.


ActionController and ActionMailer have been greatly simplified with common code removed from all these libraries and put into an AbstractController.
Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle.

application_controller.rb now has protect_from_forgery on by default.
The cookie_verifier_secret has been moved to initializers/cookie_verification_secret.rb.
The session_store configuration has moved to initializers/session_store.rb.
cookies.secure allowing you to set encrypted values in cookies with cookie.secure[:key] => value.
cookies.permanent allowing you to set permanent values in the cookie hash
cookie.permanent[:key] => value that raise exceptions on signed values if verification failures.

You can now pass :notice => ‘This is a flash message’ or :alert =>
‘Something went wrong’ to the format call inside a respond_to block. The flash[] hash still works as previously.
respond_with method has now been added to your controllers simplifying the venerable format blocks.
ActionController::Responder added allowing you flexibility in how your responses get generated.

The creation of the AbstractController allowed ActionMailer::Base to now just inherit from AbstractController and just wrap the Rails DSL onto the
Mail gem. This reduces the amount of code and duplication of other libraries in Action Mailer considerably.

– All email message related functionality have been abstracted out to the Mail gem. This reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.
– What were mailer unit tests have been moved to functional tests.
– You can now send email using new API with three methods: attachments, headers and mail.

Unobtrusive JavaScript (UJS) have been implemented and old inline AJAX commands have been removed. This enables Rails to use any compliant UJS
driver to implement the UJS hooks in the helpers. Meaning all previous remote_ helpers have been removed from Rails core and put into the
Prototype Legacy Helper. To get UJS hooks into your HTML, you now pass
:remote => true instead.
Eg: form_for @post :remote => true
You no longer need to call h(string) to escape HTML output, it is on by default in all view templates. If you want the unescaped string, call raw(string).
Helpers now output HTML 5 by default.
Form label helper now pulls values from I18n with a single value, so f.label :name will pull the :name translation.
I18n select label on should now be :en.helpers.select instead of
You no longer need to place a minus sign at the end of a ruby interpolation inside an ERb template to remove the trailing carriage return in the HTML output.
Added grouped_collection_select helper to Action View.
Action View now will raise exceptions if CSS stylesheets and javascript files listed in the javascript_include_tag and stylesheet_include_tag helpers are missing.
content_for? has been added allowing you to check for the existence of content in a view before rendering.


The addition of Arel now lets Active Record return relations on its methods. These relations can be chained together. A few of the methods which provide these are:
where – provides conditions on the relation, what gets returned.
select – choose what attributes of the models you wish to have returned from the database.
group – groups the relation on the attribute supplied.
having – provides an expression limiting group relations (GROUP BY constraint).
joins – joins the relation to another table.
clause – provides an expression limiting join relations (JOIN constraint).
includes – includes other relations pre-loaded.
order – orders the relation based on the expression supplied.
limit – limits the relation to the number of records specified.
lock – locks the records returned from the table.
readonly – returns an read only copy of the data.
from – provides a way to select relationships from more than one table.
scope – (previously named_scope) return relations and can be chained together with the other relation methods.
with_scope – and with_exclusive_scope now also return relations and so can be chained.

An example using some of the above mentioned methods
red_items = Item.where(:colour => ‘red’)
item = red_items.new
Now, giving an item.colour would give the output => red

red_items.update_all :colour => ‘black’
Gives an output=> false

Taking another example

cars = Car.where(:colour => ‘black’)
This would not give any query output. If we want to fire a select then we need to add the following
cars.each {|c| puts c.name }

The above relation is called lazy loading. This is very useful along side fragment caching. So in your controller action, you could just do

def index
@recent_items = Item.limit(10).order(‘created_at DESC’)

And in your view :
<% cache(‘recent_items’) do %>
<% @recent_items.each do |item| %>

<% end %>
In the above example, @recent_items are loaded on @recent_items.each call from the view. As the controller doesn’t actually fire any query, fragment caching becomes more effective without requiring any special work arounds.
A few enhancements to the old API has also been done which are:
Added :destroyed? to Active Record objects.
SQLite 2 support has been dropped in favour of SQLite 3.
MySQL support for column order.
PostgreSQL adapter has had its TIME ZONE support fixed so it no longer inserts incorrect values.
Support multiple schemas in table names for PostgreSQL.
PostgreSQL support for the XML data type column.
table_name is now cached.
A large amount of work done on the Oracle adapter as well with many bug fixes.
named_scope in an Active Record class is deprecated and has been renamed to just scope.
In scope methods, you should move to using the relation methods, instead of

:conditions => {} finder method, for example scope :since, lambda {|time|
where(“created_at > ?”, time) }.
save(false) is deprecated, in favour of save(:validate => false).
I18n error messages for ActiveRecord should be changed from
:en.activerecord.errors.template to :en.errors.template.
model.errors.on is deprecated in favour of model.errors[]
validates_presence_of => validates. :presence => true
ActiveRecord::Base.colorize_logging and
config.active_record.colorize_logging are deprecated in favour of
Rails::Subscriber.colorize_logging or config.colorize_logging
find(:first) and find(:all) ( without any options ) are also being deprecated in favour of first and all.


Rails 2.3 has a ton of really nice functionality locked up in monolithic components. Rails 3 has opened up a lot of that functionality in ActionPack, making it easier to reuse the router, dispatcher, and individual parts of ActionController. Validations have been moved from Active Record into Active Model, providing an interface to validations that works across ORM libraries in Rails 3.
There is now a validates :attribute, options_hash shortcut method that allows you to pass options for all the validates class methods, you can pass more than one option to a validate method.
The validates method has the following options:
:acceptance => Boolean.
:confirmation => Boolean.
:exclusion => { :in => Ennumerable }.
:inclusion => { :in => Ennumerable }.
:format => { :with => Regexp, :on => :create }.
:length => { :maximum => Fixnum }.
:numericality => Boolean.
:presence => Boolean.
:uniqueness => Boolean.

A new and clean implementation of routing is done using the ActionDispatch.
Routes defined by each application are now name spaced within your Application module.
Eg: The first line of the routers.rb file i.e
ActionController: :Routing: :Routes.draw do |map|
map.resources :post
has been replaced by
AppName: :Application.routes do
resources :posts

Match method has been added to the router. Any Rack application can be passed to the matched route. Routes can be expressed via blocks, for example you can call controller :home { match ‘/:action’ }.
Eg: map.connect ‘products/:id’, :controller => ‘catalog’,:action
match ‘products/:id’ => ‘catalog#view’

While much of Rails 3 is seeing an internal rewrite, the Routes DSL has seen a complete revision in Rails 3. It has been rewritten from the ground up a few times before, and it has brought speed and flexibility with each iteration.
The new DSL takes less keystrokes and looks clean. Here’s a typical RESTful route file in Rails 2:
map.resources :products, :member => {:short => :post}, :collection =>
{:long => :get} do |products|
products.resource :category
Here’s how it looks in Rails 3:

resources :products do
resource :category

member do
post :short

collection do
get :long

There are many additions and changes made to a lot of properties of Rails. Although it may be too soon for a few of us to change our view on the new APIs and their syntax, the old style of syntax still works due to a backwards compatibility layer which has been added. However this will be removed in the Rails 3.1 release.

Get in touch with us.

Leave a Comment

Your email address will not be published. Required fields are marked *