CSC/ECE 517 Fall 2011/ch2 2f mm
Introduction
The original Ruby on Rails platform was extracted from the web-based project-management tool called Basecamp developed by 37signals. Ruby on Rails’ creator, David Heinemeier Hansson, began work on the Rails in 2003 and released it as open source code in 2004, but it wasn’t until 2005 that Hansson shared commit rights to the project<ref>Rails Core Team Profiles</ref>. Hansson designed Ruby on Rails to be an out of the box development framework that includes everything a programmer needs to create database-driven web applications according to the Model-View-Control pattern of separation. Ruby on Rails is based on the two key paradigms of Configuration over Convention and Don't Repeat Yourself.
History of Rails Development
Throughout the development of the Rails framework there have been four significant releases alongside of the usual patches, fixes, and upgrades.
Rails 1.0
Initially, Rails 1.0 was released 15 months after the original source was made available. This version contained the structural foundation of what would become a powerful open source motivator for the Ruby platform. Though there were patches and code adjustments in Rails 1.2 the next major release was Rails 2.0.
Rails 2.0
Rails 2.0 was a major facelift for the framework and much of the effort went into improving the resources and polishing the overall package by making it more lean. Among some of these improvements was a focus on increasing security by adding a new module to work with HTTP Basic Authentication and providing a built-in mechanism for dealing with CRSF attacks. Other improvements were in the areas of changing certain syntactical nomenclature as well as simplifying the format for a few templates.
Rails 2.3
The next major update was Rails 2.3 at it was the most structural update prior to Rails 3.0 being released. The two primary changes in the architecture of the Rails application was the complete integration of the Rack modular web server interface and a renewed support for Rails Engines<ref>Ruby on Rails 2.3 Release Notes</ref>. Alongside of these changes were updates to templates, the addition of built-in support for HTTP Digest Authentication, nested forms models, Metal, and improved caching performance among other things.
Rails 3.0
Between Rails 2.3 and the release of Rails 3.0, Rails announced that it would merge with Merb and that Rails 3.0 would be the successor to both Rails 2 and Merb. Merb which is short for Mongrel+Erb, key feature that prompted the join Rails was its component modularity, extensible API design, and vertical scalability.
Rails 2 vs. Rails 3
As you can see a lot changed since the first release of Rails. We will explore a few of the key areas that changed between Rails 2 and Rails 3 that will affect a developer's everyday coding.
Rails Application Scripts
When you create a new Rails application, a directory named script is generated. In Rails 2, this directory is populated with a set of scripts that can be executed by the programmer. A few of the more important ones are as follows<ref>Ruby 2009, pp 257-258 </ref>:
- generate: Used to generate code for controllers, mailers, models, scaffolds and other sets of code.
- destroy: Used to destroy code created by the generate method.
- server: Starts up the Rails application in a self-contained web server.
- plugin: Helps with the installation and administration of plug-ins to the Rails framework.
- performance directory: Contains scripts used by the programmer to help understand the performance characteristics of the application being built.
Rails 3 does away with all of these scripts and compiles them all into a single script named rails. With this script, the programmer can access all of the functionality that was available with the separate scripts. To make things even easier, the necessity to call this script outright is even unnecessary. By using the operating systems installed rails command (ex, /usr/bin/rails on Linux systems) in the root of any Rails 3 application, it will know to call this script.
Gem Dependencies
The ability to extend the Rails framework using a Gem is a very powerful feature. In Rails 2, the config/environment.rb file had to be edited in order to tell the Rails application to require specific Gems using the config.gem method. To ensure that the Gems were actually installed on the system running the Rails application, the programmer had to execute the rake gem:install command.
Rails 3 does away with the need to have that manual process of installing Gems by utilizing a file named Gemfile in the root of the application as well as the Bundler. The Bundler looks at the contents Gemfile and automatically installs any Gems that are missing from the system. This allows the programmer to focus on more important issues.
Routing DSL
The routing DSL for Rails went through a major reconditioning and has actually been renamed to Action Dispatch. This rewrite took the logic out of the Action Controller and is now a standalone piece of software resulting in a much cleaner implementation. As well, the definition of routes for each application are now named within your Application module instead of the Action Controller. The difference can be seen in the beginning line of the config/routes.rb file:
# Rails 2 ActionController::Routing::Routes.draw do |map| map.resources :posts end # Rails 3 AppName::Application.routes do resources :posts end
With all these changes, the config/routes.rb file now has a new syntax. Here are some of the major differences<ref>Reza 2010</ref>.
Default Route
The differences between the default route are minor between the two versions, but the Rails 3 version is much more explicit, as the parentheses indicate parameters that are optional. Also worth noting is that this route is commented out in Rails 3 by default. The reasoning behind this is that there is a big push for a RESTful architecture with the Rails application and this type of route isn't really recommended for that kind of application. It can be uncommented but be warned that doing so will make all actions in every controller accessible via GET requests.
# Rails 2 map.connect ':controller/:action/:id' # Rails 3 match '/:controller(/:action(/:id))'
Regular Routes
The way in which a regular route is defined is much more streamlined and readable. In Rails 2, you had to define a key for the controller and action. With Rails 3, this definition is streamlined with a :to key where you define in a specific format the controller and action responsible for the request. Here is an example to illustrate this point:
# Rails 2 map.connect 'products/:id', :controller => 'products', :action => 'view' # Rails 3 match 'products/:id', :to => 'catalog#view'
Named Routes
Setting up named routes has changed a little bit as well. The rules for the regular routes apply here but the way that you define the name of the route has changed. Now, you utilize the :as key to define the name of the route as shown here:
# Rails 2 map.logout '/logout', :controller => 'sessions', :action => 'destroy' # Rails 3 match 'logout', :to => 'sessions#destroy', :as => "logout"
Empty Route
The empty route defines where to route the application when a user navigates to the root of the website (for normal HTML sites, this is the same as the index page). Rails 2 had a quick way of defining it but in true Ruby fashion, Rails 3 makes it even simpler to define this route as you can see here:
# Rails 2 map.root :controller => "welcome", :action => 'show' # Rails 3 root :to => 'welcome#show'
RESTful Resources
RESTful resources are very important and have been a part of Rails since version 1.2. Utilizing the rails generate scaffold command, Rails will generate the route, controller, views and model necessary to have the basic REST functionality for a model. As you can see from the following example, defining a RESTful route is simple in either version. Rails 3 grants you the ability to use this line for multiple resources as well, saving lines of code and making it more readable.
# Rails 2 map.resources :products # Rails 3 # Single resource definition resources :products # Multiple resource definitions resources :products, :categories, :comments
Also, Rails 3 provides you with the ability to extend the routing beyond the seven basic RESTful actions. There are multiple ways in which you can extend this functionality:
# Defining extra collection RESTful actions within a block. resources :products do collection do get :sold post :on_offer end # An inline extension. resources :products do get :sold, :on => :member end
Active Record
Active Record, like all of the core Rails components, got a major overhaul.
Arel and the Query Interface
The most prominent changes made that will be apparent to developers will be the integration with Arel. With this integration, all of the core methods for Active Record return relations, allowing them to be chained together to develop complex queries. A full list and their functionality can be found in the Rails Guide. This will take the place of the options hash that would normally get passed in to one of the Active Record methods. To illustrate this, say we wanted to get a list of the first 10 products ordered alphabetically:
# Rails 2 Product.find(:order => "name DESC", :limit => 10) # Rails 3 Product.order("name DESC").limit(10)
Also, there are a lot of methods that are losing the options parameter in their definitions<ref>Naik 2010</ref>, including query methods find and all as well as calculation methods count and average. Also, the :all and :first parameters for the find method are being deprecated in favor of the all and first methods. Here are some examples of how things are changing:
# Changes to the find method. # Rails 2 Product.find(:all) Product.find(:first) # Rails 3 Product.all Product.first # Examples of method options being removed. # Rails 2 Product.all(:joins => :categories) # Rails 3 Product.joins("categories")
Named Scopes
The named_scope definition has been changed to just scope. The options hash is also being deprecated and should be replaced with the new methods provided by the Arel integration. Translating existing Rails 2 named scopes is easy enough:
# Rails 2 class Product named_scope :food, :conditions => { :type => "food" } end # Rails 3 class Product scope :food, where(:type => "food") end
JavaScript Support<ref>Gadbois 2010</ref>
There are many JavaScript libraries available to programmers to make their web applications more dynamic and smooth looking. Whenever you created a Rails 2 application, it would automatically install the Prototype and Script.aculo.us frameworks. Rails also provided helpers for these two JavaScript frameworks so that a few method calls were all that you needed to make your application more fluid.
Rails 3 introduces the idea of Unobtrusive JavaScript (UJS). The JavaScript becomes unobtrusive by not being written in with the HTML objects producing cleaner code that is easier to debug. This is mostly done with the utilization of HTML 5 custom attributes such as data-method, data-confirm, data-remote and data-disable-with:
<form action="http://host.com" id="create-post" method="post" data-remote="true" data-confirm="Are you sure you want to submit?">
By doing this, it also frees Rails from being dependent on the Prototype framework, allowing it to become JavaScript framework agnostic. With its current implementation, the framework can support Prototype, jQuery and MooTools.
It might also be helpful to point out that as of Rails 3.1, the jQuery framework has replaced Prototype as the default JavaScript framework. Programmers that wish to still use Prototype must remember to specify this when they create the Rails application.
rails new myapp -j prototype
References
Citation Notes
<references/>
Full Reference Information
"The Core Team". Riding Rails. Retrieved September 2011.
Rails Ruby on Rails 2.3 Release Notes". Riding Rails. Retrieved September 2011.
Gadbois, John. Using Unobtrusive JavaScript and AJAX with Rails 3 http://net.tutsplus.com/tutorials/javascript-ajax/using-unobtrusive-javascript-and-ajax-with-rails-3/ , 2010.
Lindsaar, Mikel. "Ruby on Rails 3.0 Release Notes" http://edgeguides.rubyonrails.org/3_0_release_notes.html
Naik, Pratik. "Active Record Query Interface 3.0" http://m.onkey.org/active-record-query-interface , 2010.
Reza, Rizwan. "The Lowdown on Routes in Rails 3" http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/ , 2010.
Ruby, Sam, Dave Thomas and David Hansson. Agile Web Development with Rails: Third Edition: The Pragmatic Programmers LLC, 2009.