CSC/ECE 517 Fall 2011/ch2 2f jm: Difference between revisions
No edit summary |
m (→Introduction) |
||
(75 intermediate revisions by 3 users not shown) | |||
Line 5: | Line 5: | ||
==Introduction== | ==Introduction== | ||
There are many changes | There are many changes involved when you migrate your Rails application from Rails 2 to Rails 3. If your application is a based on Rails 2, there are important changes you'll need to make to run your application in Rails 3.<ref name="refone">Carletti, Simone. "The Road to Rails 3: make your Rails 2.3 project more Rails 3 oriented" http://www.simonecarletti.com/blog/2010/07/the-way-to-rails-3/</ref>. | ||
Rails 3 is a result of the merge between Rails and Merb. Merb is famous for honoring agnosticism and Rails has a long history of providing rock-solid defaults. We’ll see how Rails 3 hits a sweet spot in being an opinionated and agnostic framework at the same time, resulting in a framework that’s sure to be appreciated by developers of both camps. <ref name="Upgrading a Rails 2 App to Rails 3">Ruby. http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3/</ref> | |||
There are additional changes planned for Rails 3.1 and Rails 3.2 that you should consider now if you're migrating from Rails 2 to Rails 3.<ref name="reftwo">Naik, Pratik. "Active Record Query Interface 3.0" http://m.onkey.org/active-record-query-interface</ref> A variety of these changes, including changes covered in class, are covered in the sections below. | |||
==Differences between Rails 2 and Rails 3== | == Differences between Rails 2 and Rails 3 == | ||
The differences between Rails 2 and Rails 3 are probably best understood by the categories of changes required to make your Rails 2 application work in a Rails 3 environment. The following categories address some of these changes. | |||
==== | === Prerequisites === | ||
In any major version upgrade of software there are likely to be prerequisites. Rails is no different and there are a few items that you'll need to consider. These prerequisites include the following:<ref name="refone"/> | |||
<ul> | |||
<li>Make sure you have unit, functional and integration testing already implemented in your application before porting it to Rails 3.<ref>"Ruby on Rails Guides: A Guide to Testing Rails Applications" http://guides.rubyonrails.org/testing.html></ref></li> | |||
<li>Rails 3 incorporates string escaping. This can break your view helpers, so they will need to be reviewed and tested.<ref name="refone"/></li> | |||
<li>Upgrade your Ruby software to at least version 1.8.7 or skip to 1.9.2. Other versions do not work or do not work properly.<ref name="refthree">"Ruby on Rails Guides: Ruby on Rails 3.0 Release Notes" http://edgeguides.rubyonrails.org/3_0_release_notes.html</ref></li> | |||
</ul> | |||
=== Mandatory Changes === | |||
Even after prerequisites are met there are mandatory changes introduced by updates that obsolete certain features or capabilities. Again Rails 3 is no different in this respect.<ref name="refone"/> | |||
<ul> | |||
<li>The standard for managing Gem dependencies is called [http://gembundler.com/ Bundler]<ref>"Bundler: The Best Way to Manage Ruby Applications" http://gembundler.com/</ref>. This is backwards compatible with Rails 2.3 so you can [http://gembundler.com/rails23.html implement this] prior to migrating to Rails 3.<ref>"Using Bundler with Rails 2.3" http://gembundler.com/rails23.html</ref></li> | |||
<li>Rails 3 is JavaScript framework agnostic and is no longer prototype-oriented.<ref name="refone"/> As a result, there are [http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/ changes] that require attention.<ref>Carletti, Simone (June 2010). "Unobtrusive JavaScript in Rails 3" http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/</ref></li> | |||
<li><b>Object#returning</b> has been removed and you should begin using <b>Object#Tap</b>.<ref name="refone"/></li> | |||
<li>Make sure your YAML files with embedded HTML have a key that ends in <b>_html</b> or the HTML will be escaped.<ref name="refone"/></li> | |||
<li>The Rails Metal feature has been removed.<ref name="refone"/></li> | |||
<li>You can only have <b>ActiveRecord</b> fixtures in the test/fixtures folder.<ref name="refone"/></li> | |||
<li>Rails helpers for <b>input</b>, <b>form</b>, <b>error_messages_for</b> and <b>error_message_on</b> have been removed.<ref name="refone"/>. A plugin called [https://github.com/rails/dynamic_form dynamic_form] is available to continue using this functionality.<ref>"rails/dynamic_form - GitHub" https://github.com/rails/dynamic_form</ref> However, there is another method by [http://railscasts.com/episodes/211-validations-in-rails-3 Ryan Bates] to accomplish these features without using a plugin.<ref>Bates, Ryan. "Validations in Rails 3" http://railscasts.com/episodes/211-validations-in-rails-3</ref></li> | |||
</ul> | |||
=== Optional Changes === | |||
Several constants available in Rails 2 have been changed in Rails 3. These constants are RAILS_ROOT, RAILS_ENV, and RAILS_DEFAULT_LOGGER. The new constants are <b>Rails.root</b>, <b>Rails.env</b> and <b>Rails.logger</b>, respectively.<ref name="refone"/>. Simone Carletti identifies other optional changes that you may need to make. | |||
For purposes of this class, the next section identifies changes between Rails 2 and Rails 3 that were identified in class. | |||
=== Other Changes? === | |||
Have all the changes been identified here? Probably not. There are a variety of references available on the Internet that address changes from Rails 2 to Rails 3. Some are identified in the References section below, and some are identified here: | |||
<ul> | |||
<li>[http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done Rails 3.0: It's Ready!]<ref>"Rails 3.0: It's Ready!" http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done</ref></li> | |||
<li>[http://railscasts.com/episodes/225-upgrading-to-rails-3-part-1 Upgrading to Rails 3 Part 1]<ref>"Upgrading to Rails 3 Part 1" http://railscasts.com/episodes/225-upgrading-to-rails-3-part-1</ref></li> | |||
<li>[http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3 Upgrading a Rails 2 App to Rails 3]<ref>Reza, Rizwan "Upgrading a Rails 2 App to Rails 3" http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3</ref></li> | |||
</ul> | |||
You can use Google search to identify additional articles with change information. | |||
== Example Code == | |||
=== Active Record Query Interface for Rails 3 === | |||
<p> | <p> | ||
At this point you may have discovered some of the great functionalities that come with Rails 3. | At this point you may have discovered some of the great functionalities that come with Rails 3. But when you start to switch from Rails 2 to Rails 3, you may find warning messages or even errors in some of your existing methods. That is because in Rails 3, all of the internals, especially the ActiveRecord interface, were updated extensively, which makes the Rails modularity framework much cleaner and more extensible for developers to use. <ref>"Is Rails 3.0 a Game Changer?" http://lindsaar.net/2010/2/4/is_rails_3_a_game_changer</ref> Because of this, some of the methods in Rails 2 are now deprecated or even fully removed, which causes warning messages or errors when compiling the old code. Below is a list of these deprecated methods in the ActiveRecord interface. | ||
==== | ==== The find([:all | :first | :last]) Method ==== | ||
The find(*args) method in the Active Record interface allows user to retrieve objects from the database | The find(*args) method in the Active Record interface allows user to retrieve objects from the database. The user has different ways to retrieve objects, for example, they can retrieve only the first or the last object of the table, or just one object by its primary id, or all of the objects at once. These methods follow the syntax of find(:all), find(:first) or find(:last)in Rails 2. However in Rails 3, they are now deprecated and have been converted to all, first, and last alternatives. See the following example for comparison: | ||
<pre> | <pre> | ||
Line 33: | Line 79: | ||
</pre> | </pre> | ||
==== | ==== The find(*args, OPTIONS) Method ==== | ||
In Rails 3.1, ActiveRecord methods that have | In Rails 3.1, ActiveRecord methods that have <b>OPTIONS</b> as an argument are also deprecated and will be removed in Rails 3.2. Passing option hashes include :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock. So what is the replacement for this find(*args, options) method? The answer is inside the new Rails 3 API. The new Rails 3 API has the following new finder methods to replace with the find(*args, options) method.<ref name="reftwo"/> | ||
:conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock. | |||
So what is the replacement for | |||
<ul> | <ul> | ||
Line 54: | Line 98: | ||
</ul> | </ul> | ||
For | For example, in Rails 2 you used to do | ||
<pre> | <pre> | ||
# deprecated | # the deprecated version | ||
@desert_categories = Category.find(:all, :conditions => {:name => "Desert"}) | @desert_categories = Category.find(:all, :conditions => {:name => "Desert"}) | ||
@two_categories = Category.find(:all, :limit => 2) | @two_categories = Category.find(:all, :limit => 2) | ||
Line 62: | Line 106: | ||
</pre> | </pre> | ||
But in Rails, you should now do | But in Rails 3, you should now do | ||
<pre> | <pre> | ||
# | # the new version | ||
@desert_categories = Category.where(:name=>"Desert") | @desert_categories = Category.where(:name=>"Desert") | ||
@two_categories = Category.limit(2) | @two_categories = Category.limit(2) | ||
Line 70: | Line 114: | ||
</pre> | </pre> | ||
Furthermore, all of the above methods are defined on the Relation object, which gains the ability of chainability. In other | Furthermore, all of the above finder methods are defined on the Relation object, which gains the ability of chainability. In other words, all these methods can be chained together for use. This is a very powerful feature because it allows you to define multiple conditions in just one line of finder statement, which makes developers’ life so much easier. For example, if you want to return the 10 newest Desert recipes in descending order based on the creation date, you can do | ||
<pre> | <pre> | ||
Line 76: | Line 120: | ||
</pre> | </pre> | ||
==== | ==== The named_scope Method ==== | ||
The named_scoped method is deprecated | The named_scoped method is also deprecated. But to fix it, all you need to do is to rename named_scope to scope. <ref name="refthree"/> For instance, a definition like : | ||
<pre> | <pre> | ||
class Category | class Category | ||
name_scope :desert, :conditions => {:name => “Desert”} | |||
name_scope :fruit, :condition => {:name => “Fruit”} | |||
end | end | ||
</pre> | </pre> | ||
will become : | |||
<pre> | <pre> | ||
class Category | class Category | ||
scope :desert, :conditions => {:name => “Desert”} | scope :desert, :conditions => {:name => “Desert”} | ||
scope :fruit, :condition => {:name => “Fruit”} | scope :fruit, :condition => {:name => “Fruit”} | ||
end | end | ||
</pre> | </pre> | ||
However, since using options hash is deprecated in Rails 3.1, therefore the new finder methods should be used | However, since using options hash is deprecated in Rails 3.1, therefore the new finder methods should be used as below: | ||
<pre> | <pre> | ||
class Category | class Category | ||
scope :desert, where {:name => “Desert”} | scope :desert, where {:name => “Desert”} | ||
scope :fruit, where {:name => “Fruit”} | scope :fruit, where {:name => “Fruit”} | ||
end | end | ||
</pre> | </pre> | ||
Line 111: | Line 155: | ||
fruit = Category.fruit | fruit = Category.fruit | ||
</pre> | </pre> | ||
=== The New DSL in Rails 3 Router === | |||
The Rails router is used to recognize URLs and dispatch them to a controller’s action. It can also generate paths and URLs, avoiding the need to hardcode strings in the views. <ref name="refRails1"> "Rails Routing from the Outside In" http://edgeguides.rubyonrails.org/routing.html </ref> In Rails 3, other than handing basic routes in the old Domain Specific Langauges (DSL), the new DSL has some advanced features that every developer will appreciate. | |||
Comparing with the old DSL in Rails 2, the new DSL takes less keystroke and is more readable. For example, here is how DSL used to look in Rails 2: <ref>"Revamped Routes in Rails 3" http://rizwanreza.com/2009/12/20/revamped-routes-in-rails-3</ref> | |||
<pre> | |||
map.resources :products, :member => {:short => :post}, | |||
:collection => {:long => :get} do |products| | |||
products.resource :category | |||
end | |||
</pre> | |||
and now it looks like: | |||
<pre> | |||
resources :products do | |||
resource :category | |||
member do | |||
post :short | |||
end | |||
collection do | |||
get :long | |||
end | |||
end | |||
</pre> | |||
As you can see, it looks very similar to Ruby syntax, which becomes cleaner and easier to understand. | |||
==== Regular Route ==== | |||
Here is an example of how regular route looks like in Rails 2: | |||
<pre> | |||
map.connect 'products/:id', :controller => 'catalog', :action => 'view' | |||
</pre> | |||
Instead of defining keys for controller and action, you can now do: | |||
<pre> | |||
match 'products/:id' => 'catalog#view' | |||
</pre> | |||
which is less verbose and much simpler. | |||
==== Empty Route ==== | |||
Empty route can be used to route to the root of the web site. Rails 2 uses | |||
<pre> | |||
map.root :controller => "welcome", :action => 'show' | |||
</pre> | |||
which has been now simplified to | |||
<pre> | |||
root :to => 'welcome#show' | |||
</pre> | |||
==== RESTful Routes ==== | |||
The new RESTful route is one of the nicest enhancements in Rails 3 for developers. Let’s consider the Photos example <ref name="refRails1"/> below. By simply calling | |||
<pre> | |||
Resources :photos | |||
</pre> | |||
the basic routes including index, new, create, show, edit, update and destroy will be created automatically for you, and mapped to the PhotosController in this case. Here is a table that can provide you more details about these seven routes. | |||
[[File:PhotoExampleTable.jpg]] | |||
==== More RESTful Routes ==== | |||
If you want to add routes in addition to the seven routes above, you may add these routes by creating member routes or collection routes.<ref name="routeref"/> | |||
===== Member Route vs Collection Route ===== | |||
First, what is the difference between member route and collection route? The difference is that a member route requires an ID and acts on a single object, while a collection route acts on a collection of objects instead. For example, the Show route in the above example can be considered as a member route because it takes an id and displays a specified photo; the Index route can be considered as a collection route because it builds on a collection of photos and used to display all photos.<ref name="routeref">"Difference between collection route and member route in ruby on rails" http://stackoverflow.com/questions/3028653/difference-between-collection-route-and-member-route-in-ruby-on-rails</ref> | |||
===== Adding Member Routes ===== | |||
To add a member route, just simply add a member block into the resource block. For example, | |||
<pre> | |||
resources :photos do | |||
member do | |||
get 'preview' | |||
end | |||
end | |||
</pre> | |||
Doing this will recognize //photos/:id/preview with GET, and route to the preview action of the PhotosController. You can also do: | |||
<pre> | |||
resources :photos do | |||
get 'preview', :on => :member | |||
end | |||
</pre> | |||
===== Adding Collection Routes ===== | |||
To add a collection route, do | |||
<pre> | |||
resources :photos do | |||
collection do | |||
get 'search' | |||
end | |||
end | |||
</pre> | |||
Doing this will recognize //photos/search with GET, and route to the search action of the PhotosController. You can also try | |||
<pre> | |||
resources :photos do | |||
get 'search', :on => :collection | |||
end | |||
</pre> | |||
For more information regarding Rails route, please refer to [http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/ link].<ref>Katz, Yehuda (December 26, 2009) "The Rails 3 Router: Rack it Up" http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/</ref> | |||
== Recommended Reading == | |||
<ol> | |||
<li>Ruby, S., Thomas, D., Hansson, D. H. (2011). <i>Agile Web Development with Rails, 4th Edition.</i></li> | |||
</ol> | |||
==References== | ==References== | ||
<references/> | <references/> |
Latest revision as of 02:47, 22 September 2011
Rails 2 vs. Rails 3
Introduction
There are many changes involved when you migrate your Rails application from Rails 2 to Rails 3. If your application is a based on Rails 2, there are important changes you'll need to make to run your application in Rails 3.<ref name="refone">Carletti, Simone. "The Road to Rails 3: make your Rails 2.3 project more Rails 3 oriented" http://www.simonecarletti.com/blog/2010/07/the-way-to-rails-3/</ref>. Rails 3 is a result of the merge between Rails and Merb. Merb is famous for honoring agnosticism and Rails has a long history of providing rock-solid defaults. We’ll see how Rails 3 hits a sweet spot in being an opinionated and agnostic framework at the same time, resulting in a framework that’s sure to be appreciated by developers of both camps. <ref name="Upgrading a Rails 2 App to Rails 3">Ruby. http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3/</ref> There are additional changes planned for Rails 3.1 and Rails 3.2 that you should consider now if you're migrating from Rails 2 to Rails 3.<ref name="reftwo">Naik, Pratik. "Active Record Query Interface 3.0" http://m.onkey.org/active-record-query-interface</ref> A variety of these changes, including changes covered in class, are covered in the sections below.
Differences between Rails 2 and Rails 3
The differences between Rails 2 and Rails 3 are probably best understood by the categories of changes required to make your Rails 2 application work in a Rails 3 environment. The following categories address some of these changes.
Prerequisites
In any major version upgrade of software there are likely to be prerequisites. Rails is no different and there are a few items that you'll need to consider. These prerequisites include the following:<ref name="refone"/>
- Make sure you have unit, functional and integration testing already implemented in your application before porting it to Rails 3.<ref>"Ruby on Rails Guides: A Guide to Testing Rails Applications" http://guides.rubyonrails.org/testing.html></ref>
- Rails 3 incorporates string escaping. This can break your view helpers, so they will need to be reviewed and tested.<ref name="refone"/>
- Upgrade your Ruby software to at least version 1.8.7 or skip to 1.9.2. Other versions do not work or do not work properly.<ref name="refthree">"Ruby on Rails Guides: Ruby on Rails 3.0 Release Notes" http://edgeguides.rubyonrails.org/3_0_release_notes.html</ref>
Mandatory Changes
Even after prerequisites are met there are mandatory changes introduced by updates that obsolete certain features or capabilities. Again Rails 3 is no different in this respect.<ref name="refone"/>
- The standard for managing Gem dependencies is called Bundler<ref>"Bundler: The Best Way to Manage Ruby Applications" http://gembundler.com/</ref>. This is backwards compatible with Rails 2.3 so you can implement this prior to migrating to Rails 3.<ref>"Using Bundler with Rails 2.3" http://gembundler.com/rails23.html</ref>
- Rails 3 is JavaScript framework agnostic and is no longer prototype-oriented.<ref name="refone"/> As a result, there are changes that require attention.<ref>Carletti, Simone (June 2010). "Unobtrusive JavaScript in Rails 3" http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/</ref>
- Object#returning has been removed and you should begin using Object#Tap.<ref name="refone"/>
- Make sure your YAML files with embedded HTML have a key that ends in _html or the HTML will be escaped.<ref name="refone"/>
- The Rails Metal feature has been removed.<ref name="refone"/>
- You can only have ActiveRecord fixtures in the test/fixtures folder.<ref name="refone"/>
- Rails helpers for input, form, error_messages_for and error_message_on have been removed.<ref name="refone"/>. A plugin called dynamic_form is available to continue using this functionality.<ref>"rails/dynamic_form - GitHub" https://github.com/rails/dynamic_form</ref> However, there is another method by Ryan Bates to accomplish these features without using a plugin.<ref>Bates, Ryan. "Validations in Rails 3" http://railscasts.com/episodes/211-validations-in-rails-3</ref>
Optional Changes
Several constants available in Rails 2 have been changed in Rails 3. These constants are RAILS_ROOT, RAILS_ENV, and RAILS_DEFAULT_LOGGER. The new constants are Rails.root, Rails.env and Rails.logger, respectively.<ref name="refone"/>. Simone Carletti identifies other optional changes that you may need to make.
For purposes of this class, the next section identifies changes between Rails 2 and Rails 3 that were identified in class.
Other Changes?
Have all the changes been identified here? Probably not. There are a variety of references available on the Internet that address changes from Rails 2 to Rails 3. Some are identified in the References section below, and some are identified here:
- Rails 3.0: It's Ready!<ref>"Rails 3.0: It's Ready!" http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done</ref>
- Upgrading to Rails 3 Part 1<ref>"Upgrading to Rails 3 Part 1" http://railscasts.com/episodes/225-upgrading-to-rails-3-part-1</ref>
- Upgrading a Rails 2 App to Rails 3<ref>Reza, Rizwan "Upgrading a Rails 2 App to Rails 3" http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3</ref>
You can use Google search to identify additional articles with change information.
Example Code
Active Record Query Interface for Rails 3
At this point you may have discovered some of the great functionalities that come with Rails 3. But when you start to switch from Rails 2 to Rails 3, you may find warning messages or even errors in some of your existing methods. That is because in Rails 3, all of the internals, especially the ActiveRecord interface, were updated extensively, which makes the Rails modularity framework much cleaner and more extensible for developers to use. <ref>"Is Rails 3.0 a Game Changer?" http://lindsaar.net/2010/2/4/is_rails_3_a_game_changer</ref> Because of this, some of the methods in Rails 2 are now deprecated or even fully removed, which causes warning messages or errors when compiling the old code. Below is a list of these deprecated methods in the ActiveRecord interface.
The find([:all | :first | :last]) Method
The find(*args) method in the Active Record interface allows user to retrieve objects from the database. The user has different ways to retrieve objects, for example, they can retrieve only the first or the last object of the table, or just one object by its primary id, or all of the objects at once. These methods follow the syntax of find(:all), find(:first) or find(:last)in Rails 2. However in Rails 3, they are now deprecated and have been converted to all, first, and last alternatives. See the following example for comparison:
# the deprecated version @categories = Category.find(:all) @first_category = Category.find(:first) @last_category = Category.find(:last) # the good version @categories = Category.all @first_category = Category.first @last_category = Category.last
The find(*args, OPTIONS) Method
In Rails 3.1, ActiveRecord methods that have OPTIONS as an argument are also deprecated and will be removed in Rails 3.2. Passing option hashes include :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock. So what is the replacement for this find(*args, options) method? The answer is inside the new Rails 3 API. The new Rails 3 API has the following new finder methods to replace with the find(*args, options) method.<ref name="reftwo"/>
- where (:conditions)
- having (:conditions)
- select
- group
- order
- limit
- offset
- joins
- includes (:include)
- lock
- readonly
- from
For example, in Rails 2 you used to do
# the deprecated version @desert_categories = Category.find(:all, :conditions => {:name => "Desert"}) @two_categories = Category.find(:all, :limit => 2) @ordered_categories = Category.find(:all, :order => “created_at desc”)
But in Rails 3, you should now do
# the new version @desert_categories = Category.where(:name=>"Desert") @two_categories = Category.limit(2) @ordered_categories = Category.order("created_at desc")
Furthermore, all of the above finder methods are defined on the Relation object, which gains the ability of chainability. In other words, all these methods can be chained together for use. This is a very powerful feature because it allows you to define multiple conditions in just one line of finder statement, which makes developers’ life so much easier. For example, if you want to return the 10 newest Desert recipes in descending order based on the creation date, you can do
@recipes = Recipe.where(:category_name => “Desert”). order("created_at desc").limit(10)
The named_scope Method
The named_scoped method is also deprecated. But to fix it, all you need to do is to rename named_scope to scope. <ref name="refthree"/> For instance, a definition like :
class Category name_scope :desert, :conditions => {:name => “Desert”} name_scope :fruit, :condition => {:name => “Fruit”} end
will become :
class Category scope :desert, :conditions => {:name => “Desert”} scope :fruit, :condition => {:name => “Fruit”} end
However, since using options hash is deprecated in Rails 3.1, therefore the new finder methods should be used as below:
class Category scope :desert, where {:name => “Desert”} scope :fruit, where {:name => “Fruit”} end
At the end when you call these named scopes, you can simply do
desert = Category.desert fruit = Category.fruit
The New DSL in Rails 3 Router
The Rails router is used to recognize URLs and dispatch them to a controller’s action. It can also generate paths and URLs, avoiding the need to hardcode strings in the views. <ref name="refRails1"> "Rails Routing from the Outside In" http://edgeguides.rubyonrails.org/routing.html </ref> In Rails 3, other than handing basic routes in the old Domain Specific Langauges (DSL), the new DSL has some advanced features that every developer will appreciate.
Comparing with the old DSL in Rails 2, the new DSL takes less keystroke and is more readable. For example, here is how DSL used to look in Rails 2: <ref>"Revamped Routes in Rails 3" http://rizwanreza.com/2009/12/20/revamped-routes-in-rails-3</ref>
map.resources :products, :member => {:short => :post}, :collection => {:long => :get} do |products| products.resource :category end
and now it looks like:
resources :products do resource :category member do post :short end collection do get :long end end
As you can see, it looks very similar to Ruby syntax, which becomes cleaner and easier to understand.
Regular Route
Here is an example of how regular route looks like in Rails 2:
map.connect 'products/:id', :controller => 'catalog', :action => 'view'
Instead of defining keys for controller and action, you can now do:
match 'products/:id' => 'catalog#view'
which is less verbose and much simpler.
Empty Route
Empty route can be used to route to the root of the web site. Rails 2 uses
map.root :controller => "welcome", :action => 'show'
which has been now simplified to
root :to => 'welcome#show'
RESTful Routes
The new RESTful route is one of the nicest enhancements in Rails 3 for developers. Let’s consider the Photos example <ref name="refRails1"/> below. By simply calling
Resources :photos
the basic routes including index, new, create, show, edit, update and destroy will be created automatically for you, and mapped to the PhotosController in this case. Here is a table that can provide you more details about these seven routes.
More RESTful Routes
If you want to add routes in addition to the seven routes above, you may add these routes by creating member routes or collection routes.<ref name="routeref"/>
Member Route vs Collection Route
First, what is the difference between member route and collection route? The difference is that a member route requires an ID and acts on a single object, while a collection route acts on a collection of objects instead. For example, the Show route in the above example can be considered as a member route because it takes an id and displays a specified photo; the Index route can be considered as a collection route because it builds on a collection of photos and used to display all photos.<ref name="routeref">"Difference between collection route and member route in ruby on rails" http://stackoverflow.com/questions/3028653/difference-between-collection-route-and-member-route-in-ruby-on-rails</ref>
Adding Member Routes
To add a member route, just simply add a member block into the resource block. For example,
resources :photos do member do get 'preview' end end
Doing this will recognize //photos/:id/preview with GET, and route to the preview action of the PhotosController. You can also do:
resources :photos do get 'preview', :on => :member end
Adding Collection Routes
To add a collection route, do
resources :photos do collection do get 'search' end end
Doing this will recognize //photos/search with GET, and route to the search action of the PhotosController. You can also try
resources :photos do get 'search', :on => :collection end
For more information regarding Rails route, please refer to link.<ref>Katz, Yehuda (December 26, 2009) "The Rails 3 Router: Rack it Up" http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/</ref>
Recommended Reading
- Ruby, S., Thomas, D., Hansson, D. H. (2011). Agile Web Development with Rails, 4th Edition.
References
<references/>