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