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 ▼
RSS

Web Development

What's New in Rails 2.x


Multiple Views Support

The ActionPack has added support for multiviews. The .rhtml files have been replaced with .erb files and the .rxml files have been replaced with .builder files; the show.rhtml file becomes show.html.erb and the show.rxml file becomes show.xml.builder. The .erb and .builder templates may be used to render more than just HTML and XML format files. The format of the template has been separated from the rendering engine. The new format for view templates is action.format.renderer. For example, you are designing the iPhone and mobile versions of your website and you want both the versions to serve text/html. First, you would be required to register the iphone and mobile formats in the /config/initializers/mime_types.rb file as follows:


Mime::Type.register_alias "text/html", :iphone   
Mime::Type.register_alias "text/html", :mobile  

Using multiviews the index.html.erb, index.iphone.erb and index.mobile.erb templates would all serve text/html. Similarly you could serve csv files such as show.csv.erb by registering the text/csv format. If you want to run Atom feed view templates, first you would register the application/atom+xml type.


Mime::Type.register_alias "application/atom+xml", :atom

View template index.atom.builder would render the index action for the atom feed. Previously the view template would have been called index.rxml.

Improvements in Fixtures

Prior to Rails 2.0 setting up fixtures for model classes with associations between them involved specifying fixture ids. Consider the following model in which the Catalog class has a 1:many association with the Journal class:


class Catalog < ActiveRecord::Base; has_many :journals; end
class Journal < ActiveRecord::Base; belongs_to :catalog end

The fixture file catalog.yml corresponding to the Catalog class is as follows:


catalog1:
  id: 1
  edition: January 2009
  Publisher: Dr. Dobb's

The fixture file journals.yml has a reference to the catalog id.


journal1:
  id: 1
  name: JavaDept
  catalog_id: 1

journal2:
  id: 2
  name: Dr. Dobb's
  catalog_id: 1

In Rails 2.0 fixture ids and references to fixture ids are not needed. In Rails 2.0 the catalog.yml fixture file is specified as follows:

 

catalog1:
  edition: January 2009
  Publisher: Think Services 

And, the journals.yml fixture file is defined without the id references as follows:


journal1:
  name: JavaDept
  catalog: catalog1

journal2:
  name: Dr. Dobb's
  catalog: catalog1

Another new fixtures feature is that multiple fixtures may be referred in a single fixtures invocation. For example, fixtures catalog1 and catalog2 may be invoked using the assert_equal method as follows:


fixtures :catalogs
 ...
assert_equal catalogs(:catalog1, :catalog2), Catalog.find(:all)

Prior to Rails 2.0 multiple fixtures invocations had to be specified. For example, the previous assert_equal statement is specified as follows:


fixtures :catalogs
 ...
assert_equal [catalogs(:catalog1), catalogs(:catalog2)], Catalog.find(:all)

Performance of fixtures has been greatly improved to increase the performance of test suites by 50-100 percent.

Better Exception Handling

It is common to redirect the user or render specific pages for specific exceptions. Rails 2.0 has added support for the ActionController::Base.rescue_from method, which provides a cleaner style than the case statement-based rescue_action_in_public. For example, different files are rendered for different exceptions using the rescue_action_in_public method as follows:


class CatalogsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

Using the rescue_from method the different exceptions may be mapped to different handler methods as follows:


class CatalogsController < ApplicationController

  # Declare exception to handler methods
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end
end

The rescue_from method accepts a block or a proc to specify exception handling.

Efficient Migrations

Rails 2.0 provides an alternative, more efficient form of declaring migrations:


create_table :catalog do |t|
  t.column, "catalog_id",  :integer
  t.column, "journal",  :string, :null => false
  t.column, "publisher",   :string, :null => false
  t.column, "edition", :string, :null => false
  t.column, "title",  :string, :null => false
  t.column, "author",  :string, :null => false
end

In Rails 2.0, you specify the following:


create_table :catalog do |t|
  t.integer :catalog_id
  t.string  :journal, :publisher,:edition,:title,:author :null => false
end

New ActiveRecord Features

In Rails 2.0 active record cache is enabled by default for all controller actions. Query Cache has been added in Rails 2.0 to return cached results for similar SQL calls. For example, in the following action definition the SQL statement would be run twice against the database in earlier versions of Rails; in Rails 2.0 the SQL statement would run once and be loaded from cache in the second call.


class CatalogController < ApplicationController
  def getCatalogEntries
      catalog = Catalog.find(1)
       ...
      catalog_again = Catalog.find(1)
  end
end

If you have been using Rails with commercial databases you have to install the commercial database adapters as they are not included in the Rails distribution. Only database adapters for the open source databases MySQL, SQLite, and PostgreSQL are included in the Rails distribution. If you do have to use a commercial database simply run the gem install command for the database.


gem install activerecord-oracle-adapter
gem install activerecord-sqlserver-adapter
gem install activerecord-firebird-adapter
gem install activerecord-frontbase-adapter
gem install activerecord-openbase-adapter
gem install activerecord-sybase-adapter

Cleaner Environment File

In Rails 2.0 the config/initializers directory has been added from which all Ruby files are automatically loaded after the Rails configuration is completed and the Rails::Initializer has run. The config/initializers directory feature makes environment.rb file a lot more cleaner as the various configs are not required to be declared in the environment.rb file. For example, if you needed to declare some action mailer configs and date formats you would add the following config statements to environment.rb:


ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.default_charset = "utf-8"
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:concise => "%d.%b.%y")
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:medium => "%b %e, %Y"

With the config/initialzers directory feature create a config/initializers/mail.rb file with the following configs and the mail.rb files gets loaded automatically:

 

ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.default_charset = "utf-8"

Similarly create a config/initializers/date_formats.rb file with the following date formats:


ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:concise => "%d.%b.%y")
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:medium => "%b %e, %Y"

Rails 2.0 includes the config/initializers/inflections.rb file for the pluralization rules and the mime_types.rb file for the mime types.

Misc Features

Some simplifications have been made to controller and view methods involving URLs. Record identification has been made easier in Rails 2.0. Conventions have been added to map model classes to resource URLs. For example, 'catalog' is a Catalog object that by convention will be mapped to catalog_url.

A new module for HTTP Basic Authentication has been added to Rails 2.0. The ActionPack includes new security features to prevent cross site scripting and cross site references. Session storage is easier to maintain in Rails 2.0 using cookies instead of a file system on the database. ActionPack includes a new request profiler to speed up an application. ActionPack includes a AtomFeedHelper, which makes it easier to create Atom feeds using an enhanced Builder syntax. For better testing assert_difference has been added to the ActiveSupport and assert_emails has been added to ActionMailer. The debugger has returned in Rails 2.0. All that is required to use the debugger is install the ruby-debug gem, put "debugger" in the application, and start the server with debugger or -u. Source-annotations extractor tasks have been added to rake. All helpers from app/helpers/**/*.rb are automatically included in the ApplicationController. Some new options have been added to the render method to improve rendering. Layouts have been added to partials. ActiveSupport::BufferedLogger has been added as new default logger for better logging performance. Rails 2.0 has the provision to specify the plugin loading order. The allow_blank option has been added to active record validation methods to allow blank values. For all the changes in Rails 2.0, see the Rails CHANGELOGS.

What's New In Rails 2.1

Support for time zones has been added in Rails 2.1. Just specify the time zone using the Time.zone variable and all date references will use the specified time zone. The time zone may be set in the controller using a before filter:


class ApplicationController < ActionController::Base
  before_filter :set_timezone
  def set_timezone
    Time.zone = "London"
  end
end

With the timezone specified in the controller, all controller actions and views will use the specified time zone. The default time zone may be set in environment.rb:


Rails::Initializer.run do |config|
  config.time_zone = "Pacific Time"
end

In Rails 2.1, provision has been added to track changes in ActiveRecordobjects. Rails 2.1 has also added the provision to specify gems that are required by the Rails application. The gems may be specified using config.gem and when the application loads it will find and require the specified gems. The following environment.rb specifies the requird gems:


Rails::Initializer.run do |config| 

  # Require the latest version of activerecord-sqlserver-adapter
  config.gem "activerecord-sqlserver-adapter"

  # Require a specific version of activerecord-oracle-adapter
  config.gem "activerecord-oracle-adapter", :version => '1.0'

  # Require a gem from a non-standard source
  config.gem "sybase-adapter", :source => "http://www.sybase-adapter.net"
end

Also rake tasks have been added to install, build, package, and unpackage gems. The named_scope feature has been added to make it easier to create reusable SQL queries. Naming convention has been added to Rails migrations to name the migrations based on unique UTC based timestamp. Caching has been improved in Rails 2.1 in which custom controller caching mechanism may be specified.


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.