aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/Rakefile22
-rw-r--r--railties/doc/guides/debugging/debugging_rails_applications.txt358
-rw-r--r--railties/doc/guides/index.txt21
-rw-r--r--railties/doc/guides/introduction.txt116
-rw-r--r--railties/doc/guides/routing/routing_outside_in.txt819
5 files changed, 1331 insertions, 5 deletions
diff --git a/railties/Rakefile b/railties/Rakefile
index 174c85b59a..a3d031020e 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -272,13 +272,25 @@ Rake::RDocTask.new { |rdoc|
rdoc.rdoc_files.include('lib/commands/**/*.rb')
}
-guides = ['securing_rails_applications', 'testing_rails_applications', 'creating_plugins']
+guides = [
+ 'securing_rails_applications',
+ 'testing_rails_applications',
+ 'creating_plugins',
+ { 'routing' => 'routing_outside_in' }
+]
guides_html_files = []
-guides.each do |guide_name|
- input = "doc/guides/#{guide_name}/#{guide_name}.txt"
- output = "doc/guides/#{guide_name}/#{guide_name}.html"
+guides.each do |entry|
+ if entry.is_a?(Hash)
+ guide_folder = entry.keys.first
+ guide_name = entry.values.first
+ else
+ guide_folder = entry
+ guide_name = entry
+ end
+ input = "doc/guides/#{guide_folder}/#{guide_name}.txt"
+ output = "doc/guides/#{guide_folder}/#{guide_name}.html"
guides_html_files << output
- file output => Dir["doc/guides/#{guide_name}/*.txt"] do
+ file output => Dir["doc/guides/#{guide_folder}/*.txt"] do
sh "mizuho", input, "--template", "manualsonrails", "--multi-page",
"--icons-dir", "../icons"
end
diff --git a/railties/doc/guides/debugging/debugging_rails_applications.txt b/railties/doc/guides/debugging/debugging_rails_applications.txt
new file mode 100644
index 0000000000..cc18285782
--- /dev/null
+++ b/railties/doc/guides/debugging/debugging_rails_applications.txt
@@ -0,0 +1,358 @@
+Debugging Rails applications
+============================
+
+You may have heard about debugging:
+
+_Debugging is a methodical process of finding and reducing the number of bugs, or defects, in a computer program or a piece of electronic hardware thus making it behave as expected._
+
+Many times your code may not behave has you expect, sometimes you will try to print in logs or console values to make a diagnostic of the problem.
+
+Unfortunately, you won't find always the answer you are looking for this way. In that case, you will need to know what's happening and adventure into Rails, in this journey the debugger will be your best companion.
+
+If you ever wanted to learn about Rails source code but you didn't know where to start, this may be the best way, just debug any request you would normally do and using this guide you will learn how to move in the code you have written but also go deeper into Rails code.
+
+== Introducing the debugger
+
+=== Rails debugging history
+
+Rails has built-in support for ruby-debug since April 28, 2007. When the Breakpoint library was removed in favor of ruby-debug, the reason?
+
+The breakpointer, included in the Breakpoint library, and Binding.of_caller were removed in favor of relying on ruby-debug by Kent Sibilev.
+
+The problem was a bug in Ruby 1.8.4, that was fixed in Ruby 1.8.5 but left unusable the breakpointer. The Breakpoint library is also no longer being maintained, so it's effectively dead.
+
+=== Start debugging your rails app
+
+Inside any Rails application you can invoke the debugger by calling the *debugger* method.
+
+Let's take a look at an example:
+
+[source, ruby]
+----------------------------------------------------------------------------
+class PeopleController < ApplicationController
+ def new
+ debugger
+ @person = Person.new
+ end
+end
+----------------------------------------------------------------------------
+
+If you see the message in the console or logs:
+
+[source, shell]
+----------------------------------------------------------------------------
+***** Debugger requested, but was not available: Start server with --debugger to enable *****
+----------------------------------------------------------------------------
+
+Make sure you have started your web server with the option --debugger:
+
+[source, shell]
+----------------------------------------------------------------------------
+~/PathTo/rails_project$ script/server --debugger
+----------------------------------------------------------------------------
+
+In order to use Rails debugging you'll need to be running either *WEBrick* or *Mongrel*. For the moment, no alternative servers are supported.
+
+
+== The debugger
+=== The shell
+
+As soon as your application calls the *debugger* method, the debugger will be started in a debugger shell inside the terminal window you've fired up your application server and you will be placed in the ruby-debug's prompt (rdb:n). The n is the thread number.
+
+If you got there by a browser request, the browser will be hanging until the debugger has finished and the trace has completely run as any normal request.
+
+For example:
+
+[source, shell]
+----------------------------------------------------------------------------
+@posts = Post.find(:all)
+(rdb:7)
+----------------------------------------------------------------------------
+
+Now it's time to play and dig into our application. The first we are going to do is ask our debugger for help... so we type: *help* (You didn't see that coming, right?)
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:7) help
+ruby-debug help v0.10.2
+Type 'help <command-name>' for help on a specific command
+
+Available commands:
+backtrace delete enable help next quit show trace
+break disable eval info p reload source undisplay
+catch display exit irb pp restart step up
+condition down finish list ps save thread var
+continue edit frame method putl set tmate where
+----------------------------------------------------------------------------
+
+[NOTE]
+To view the help menu for any command use *help <command-name>* in active debug mode. For example: _help var_
+
+The second command before we move on, is one of the most useful command: *list* (or his shorthand *l*).
+
+This command will give us a starting point of where we are by printing 10 lines centered around the current line; the current line here is line 6 and is marked by =>.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:7) list
+[1, 10] in /PathToProject/posts_controller.rb
+ 1 class PostsController < ApplicationController
+ 2 # GET /posts
+ 3 # GET /posts.xml
+ 4 def index
+ 5 debugger
+=> 6 @posts = Post.find(:all)
+ 7
+ 8 respond_to do |format|
+ 9 format.html # index.html.erb
+ 10 format.xml { render :xml => @posts }
+----------------------------------------------------------------------------
+
+If we do it again, this time using just *l*, the next ten lines of the file will be printed out.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:7) l
+[11, 20] in /PathTo/project/app/controllers/posts_controller.rb
+ 11 end
+ 12 end
+ 13
+ 14 # GET /posts/1
+ 15 # GET /posts/1.xml
+ 16 def show
+ 17 @post = Post.find(params[:id])
+ 18
+ 19 respond_to do |format|
+ 20 format.html # show.html.erb
+----------------------------------------------------------------------------
+
+And so on until the end of the current file, when the end of file is reached, it will start again from the beginning of the file and continue again up to the end, acting as a circular buffer.
+
+=== The context
+When we start debugging your application, we will be placed in different contexts as you go through the different parts of the stack.
+
+A context will be created when a stopping point or an event is reached. It has information about the suspended program which enable a debugger to inspect the frame stack, evaluate variables from the perspective of the debugged program, and contains information about the place the debugged program is stopped.
+
+At any time we can call the *backtrace* command (or alias *where*) to print the backtrace of the application, this is very helpful to know how we got where we are. If you ever wondered about how you got somewhere in your code, then *backtrace* is your answer.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:5) where
+ #0 PostsController.index
+ at line /PathTo/project/app/controllers/posts_controller.rb:6
+ #1 Kernel.send
+ at line /PathTo/project/vendor/rails/actionpack/lib/action_controller/base.rb:1175
+ #2 ActionController::Base.perform_action_without_filters
+ at line /PathTo/project/vendor/rails/actionpack/lib/action_controller/base.rb:1175
+ #3 ActionController::Filters::InstanceMethods.call_filters(chain#ActionController::Fil...,...)
+ at line /PathTo/project/vendor/rails/actionpack/lib/action_controller/filters.rb:617
+...
+----------------------------------------------------------------------------
+
+You move anywhere you want in this trace using the *frame n* command, where n is the specified frame number.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:5) frame 2
+#2 ActionController::Base.perform_action_without_filters
+ at line /PathTo/project/vendor/rails/actionpack/lib/action_controller/base.rb:1175
+----------------------------------------------------------------------------
+
+The available variables are the same as if we were running the code line by line, after all, that's what debugging is.
+
+Moving up and down the stack frame: You can use *up [n]* (*u* for abbreviated) and *down [n]* commands in order to change the context _n_ frames up or down the stack respectively. _n_ defaults to one.
+
+=== Inspecting variables
+
+In the following example we will print the instance_variables defined within the current context.
+
+[source, shell]
+----------------------------------------------------------------------------
+@posts = Post.find(:all)
+(rdb:11) instance_variables
+["@_response", "@action_name", "@url", "@_session", "@_cookies", "@performed_render", "@_flash", "@template", "@_params", "@before_filter_chain_aborted", "@request_origin", "@_headers", "@performed_redirect", "@_request"]
+----------------------------------------------------------------------------
+
+As you may have figured out, all variables that you can access from a controller are displayed, lets run the next line, we will use *next* (we will get later into this command).
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:11) n
+Processing PostsController#index (for 127.0.0.1 at 2008-09-04 19:51:34) [GET]
+ Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA==--b16e91b992453a8cc201694d660147bba8b0fd0e
+ Parameters: {"action"=>"index", "controller"=>"posts"}
+/PathToProject/posts_controller.rb:8
+respond_to do |format|
+-------------------------------------------------------------------------------
+
+And we'll ask again for the instance_variables.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:11) instance_variables
+["@_response", "@action_name", "@url", "@_session", "@_cookies", "@performed_render", "@_flash", "@template", "@_params", "@before_filter_chain_aborted", "@posts", "@request_origin", "@_headers", "@performed_redirect", "@_request"]
+----------------------------------------------------------------------------
+
+Now @posts is a included in them, because the line defining it was executed.
+
+[NOTE]
+You can also step into *irb* mode with the command *irb* (of course!). This way an irb session will be started within the context you invoked it. But you must know that this is an experimental feature.
+
+To show variables and their values the *var* method is the most convenient way:
+
+[source, shell]
+----------------------------------------------------------------------------
+var
+(rdb:1) v[ar] const <object> show constants of object
+(rdb:1) v[ar] g[lobal] show global variables
+(rdb:1) v[ar] i[nstance] <object> show instance variables of object
+(rdb:1) v[ar] l[ocal] show local variables
+----------------------------------------------------------------------------
+
+This is a great way for inspecting the values of the current context variables. For example:
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:9) v l
+ __dbg_verbose_save => false
+----------------------------------------------------------------------------
+
+You can also inspect for an object method this way:
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:9) v instance Post.new
+@attributes = {"updated_at"=>nil, "body"=>nil, "title"=>nil, "published"=>nil, "created_at"...
+@attributes_cache = {}
+@new_record = true
+----------------------------------------------------------------------------
+
+[NOTE]
+Commands *p* (print) and *pp* (pretty print) can be used to evaluate Ruby expressions and display the value of variables to the console.
+
+We can use also *display* to start watching variables, this is a good way of tracking values of a variable while the execution goes on.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:1) display @recent_comments
+1: @recent_comments =
+----------------------------------------------------------------------------
+
+The variables inside the displaying list will be printed with their values after we move in the stack. To stop displaying a variable use *undisplay n* where n is the variable number (1 in the last example).
+
+== Step by step
+
+Now you should know where you are in the running trace and be able to print the available variables. But lets continue and move on with the application execution.
+
+Use *step* (abbreviated *s*) to continue running your program until the next logical stopping point and return control to ruby-debug.
+
+[NOTE]
+You can also use *step+ n* and *step- n* to move forward or backward n steps respectively.
+
+You may also use *next* which is similar to step, but function or method calls that appear within the line of code are executed without stopping. As with step, you may use plus sign to move n steps.
+
+The difference between *next* and "step" is that *step* stops at the next line of code executed, doing just single step, while *next* moves to the next line without descending inside methods.
+
+Lets run the next line in this example:
+
+[source, ruby]
+----------------------------------------------------------------------------
+class Author < ActiveRecord::Base
+ has_one :editorial
+ has_many :comments
+
+ def find_recent_comments(limit = 10)
+ debugger
+ @recent_comments ||= comments.find(
+ :all,
+ :conditions => ["created_at > ?", 1.week.ago],
+ :limit => limit
+ )
+ end
+end
+----------------------------------------------------------------------------
+
+[NOTE]
+You can use ruby-debug while using script/console but remember to *require "ruby-debug"* before calling *debugger* method.
+
+[source, shell]
+----------------------------------------------------------------------------
+/PathTo/project $ script/console
+Loading development environment (Rails 2.1.0)
+>> require "ruby-debug"
+=> []
+>> author = Author.first
+=> #<Author id: 1, first_name: "Bob", last_name: "Smith", created_at: "2008-07-31 12:46:10", updated_at: "2008-07-31 12:46:10">
+>> author.find_recent_comments
+/PathTo/project/app/models/author.rb:11
+)
+----------------------------------------------------------------------------
+
+Now we are where we wanted to be, lets look around.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:1) list
+[6, 15] in /PathTo/project/app/models/author.rb
+ 6 debugger
+ 7 @recent_comments ||= comments.find(
+ 8 :all,
+ 9 :conditions => ["created_at > ?", 1.week.ago],
+ 10 :limit => limit
+=> 11 )
+ 12 end
+ 13 end
+----------------------------------------------------------------------------
+
+We are at the end of the line, but... was this line executed? We can inspect the instance variables.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:1) var instance
+@attributes = {"updated_at"=>"2008-07-31 12:46:10", "id"=>"1", "first_name"=>"Bob", "las...
+@attributes_cache = {}
+----------------------------------------------------------------------------
+
+@recent_comments hasn't been defined yet, so we can assure this line hasn't been executed yet, lets move on this code.
+
+[source, shell]
+----------------------------------------------------------------------------
+(rdb:1) n
+/PathTo/project/app/models/author.rb:12
+@recent_comments
+(rdb:1) var instance
+@attributes = {"updated_at"=>"2008-07-31 12:46:10", "id"=>"1", "first_name"=>"Bob", "las...
+@attributes_cache = {}
+@comments = []
+@recent_comments = []
+----------------------------------------------------------------------------
+
+Now we can see how @comments relationship was loaded and @recent_comments defined because the line was executed.
+
+In case we want deeper in the stack trace we can move single *steps* and go into Rails code, this is the best way for finding bugs in your code, or maybe in Ruby or Rails.
+
+== Editing
+
+At any time, you may use *edit [line specification]* command to edit line specification using the editor specified by the EDITOR environment variable.
+
+If you use TextMate, you can the command *tmate n* to open the current file in TextMate. It uses n-th frame if arg (n) is specified.
+
+== Resuming Execution
+
+* *continue* [line-specification] (or *c*): resume program execution, at the address where your script last stopped; any breakpoints set at that address are bypassed. The optional argument line-specification allows you to specify a line number to set a one-time breakpoint which is deleted when that breakpoint is reached.
+* *finish* [frame-number] (or *fin*): execute until selected stack frame returns. If no frame number is given, we run until the currently selected frame returns. The currently selected frame starts out the most-recent frame or 0 if no frame positioning (e.g up, down or frame) has been performed. If a frame number is given we run until frame frames returns.
+
+
+== Quitting
+To exit the debugger, use the *quit* command (abbreviated *q*), or alias *exit*.
+
+A simple quit tries to terminate all threads in effect. Therefore your server will be stopped and you will have to start it again.
+
+== References
+
+* link:http://www.datanoise.com/ruby-debug[ruby-debug Homepage]
+* link:http://www.sitepoint.com/article/debug-rails-app-ruby-debug/[Article: Debugging a Rails application with ruby-debug]
+* link:http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/[ruby-debug Basics screencast]
+* link:http://railscasts.com/episodes/54-debugging-with-ruby-debug[Ryan Bate's ruby-debug screencast]
+* link:http://bashdb.sourceforge.net/ruby-debug.html[Debugging with ruby-debug]
+* link:http://cheat.errtheblog.com/s/rdebug/[ruby-debug cheat sheet] \ No newline at end of file
diff --git a/railties/doc/guides/index.txt b/railties/doc/guides/index.txt
new file mode 100644
index 0000000000..5f44103570
--- /dev/null
+++ b/railties/doc/guides/index.txt
@@ -0,0 +1,21 @@
+The Book on Rails
+=================
+
+This book is about Ruby on Rails, a web development framework that saves you time and makes web development a joy. Using Ruby on Rails, you can build and maintain high-quality web applications with minimal fuss.
+
+At its best, web development is an exciting, creative act; at its worst, it can be a repetitive, frustrating nuisance. Ruby on Rails lets you focus on the fun stuff -- the crux of your web application -- while easing the pain of the repetitive bits. In doing so, it provides high-level abstractions of common web development patterns, shortcuts for frequent programming tasks, and clear conventions for how to solve problems.
+
+The goal of this book is to make you familiar with Ruby on Rails. This book assumes that you are already familiar with Ruby -- the programming language that Ruby on Rails is written in -- and that you have basic knowledge about HTML and web development.
+
+The focus of this book is twofold. First, we explain, in depth, what Ruby on Rails does and how to build web applications with it. Second, we discuss higher-level concepts where appropriate, answering the question ``How can I apply these tools effectively in my own projects?'' By reading this book, you'll learn the skills needed to develop powerful web sites quickly, with code that is clean and easy to maintain.
+
+== Introduction to Ruby on Rails ==
+include::introduction.txt[]
+
+== Installing Ruby on Rails ==
+include::installing_rails.txt[]
+
+== Creating a New Rails Project ==
+
+== Deploying Ruby on Rails ==
+
diff --git a/railties/doc/guides/introduction.txt b/railties/doc/guides/introduction.txt
new file mode 100644
index 0000000000..403c10380f
--- /dev/null
+++ b/railties/doc/guides/introduction.txt
@@ -0,0 +1,116 @@
+In this chapter, we provide a high-level overview of Ruby on Rails.
+
+=== What Is a Web Framework? ===
+
+Ruby on Rails is a prominent member of a new generation of web frameworks. So what exactly does that term mean?
+
+To answer that question, let's consider the design of a web application written in PHP, a popular way to write web applications at this time (circa 2008). PHP is a scripting language, mostly meant for producing dynamic web pages. When you write a PHP application, you do everything yourself -- the equivalent of baking a cake from scratch. For example, here's a simple PHP script, that displays the ten most recently published books from a database:
+
+[source, php]
+-----------------------------------------
+<?php
+echo "<html><head><title>Books</title></head>\n"
+echo "<body>\n"
+echo "<h1>Books</h1>\n"
+echo "<ul>\n";
+
+mysql_connect("localhost", "me", "letmein");
+mysql_select_db("my_db");
+$result = mysql_query("SELECT name FROM books ORDER BY pub_data DESC LIMIT 10");
+while ($row = mysql_fetch($result)) {
+ echo "<li>$row[0]</li>\n";
+}
+
+echo "</ul>\n";
+echo "</body></html>\n";
+?>
+-----------------------------------------
+
+This code is straightforward. First, it prints some introductory HTML. Then, it connects to a database and executes a query that retrieves the latest ten books. Looping over those books, it generates an HTML unordered list. Finally, it prints the closing HTML and closes the database connection.
+
+With a one-off dynamic page such as this one, the write-it-from-scratch approach isn't necessarily bad. For one thing, this code is simple to comprehend -- even a novice developer can read these 14 lines of PHP and understand all it does, from start to finish. There's nothing else to learn; no other code to read. It's also simple to deploy: just save this code in a file called 'latestbooks.php', upload that file to a web server, and visit that page with a browser.
+
+But as a web application grows beyond the trivial, this approach breaks down, and you face a number of problems:
+
+ * What happens when multiple pages need to connect to the database? Surely that database-connecting code shouldn't be duplicated in each individual PHP script, so the pragmatic thing to do would be to refactor it into a shared function.
+ * Should a developer really have to worry about printing the ``Content-Type'' line and remembering to close the database connection? This sort of boilerplate reduces programmer productivity and introduces opportunities for mistakes. These setup- and teardown-related tasks would best be handled by some common infrastructure.
+ * What happens when this code is reused in multiple environments, each with a separate database and password? At this point, some environment-specific configuration becomes essential.
+ * What happens when a web designer who has no experience coding Ruby wishes to redesign the page? Ideally, the logic of the page -- the retrieval of books from the database -- would be separate from the HTML display of the page, so that a designer could edit the latter without affecting the former.
+
+These problems are precisely what a web framework intends to solve. A web framework provides a programming infrastructure for your applications, so that you can focus on writing clean, maintainable code without having to reinvent the wheel. In a nutshell, that's what Ruby on Rails does. Ruby on Rails also leverages the power of the Ruby programming language, to make web development as pleasant as possible.
+
+
+=== The MVC Design Pattern ===
+
+Let's dive in with a quick example that demonstrates the difference between the previous approach and that undertaken using a web framework. Here's how you might write the previous PHP code using Ruby on Rails:
+
+[source, ruby]
+----------------------------------------
+# File: app/models/book.rb (the database model with business logic)
+
+class Book < ActiveRecord::Base
+ def self.latest_books
+ return Book.find(:all, :order => 'pub_date DESC', :limit => 10)
+ end
+end
+----------------------------------------
+
+[source, ruby]
+----------------------------------------
+# File: app/controllers/books_controller.rb (the controller, which handles HTTP requests)
+
+class BooksController < ApplicationController
+ def index
+ @books = Book.latest_books
+ end
+end
+----------------------------------------
+
+[source, html]
+----------------------------------------
+<!-- File: app/views/books/index.html.erb (the view template) -->
+
+<html>
+<head>
+ <title>Books</title>
+</head>
+<body>
+ <h1>Books</h1>
+ <ul>
+ <% for book in @books %>
+ <li><%=h book.name %></li>
+ <% end %>
+ </ul>
+</body>
+</html>
+----------------------------------------
+
+Don't worry about the particulars of how this works just yet -- we just want you to get a feel for the overall design. The main thing to note here is the separation of concerns:
+
+ * The 'book.rb' file contains a *model* for the 'books' database table. Using this class, you can create, retrieve, update, and delete records in your database using simple Ruby code rather than writing repetitive SQL statements.
+
+ * The 'books_controller.rb' file is called the *controller*. It receives HTTP requests and processes them. It prepares information that the view will use to render the final HTML output for the HTTP client.
+
+ * The 'index.html.erb' file an HTML-ERB *template* that describes the design of the page.
+
+Taken together, these pieces loosely follow the Model-View-Controller (MVC) design pattern. Simply put, MVC defines a way of developing software so that the code for defining and accessing data (the model) is separate from request logic (the controller), which in turn is separate from the user interface (the view).
+
+A key advantage of such an approach is that components are loosely coupled. That is, each distinct piece of a Ruby on Rails-powered web application has a single key purpose and can be changed independently without affecting the other pieces. For example, a designer can change the user interface without having to understand the business logic. A database administrator can rename a database table and specify the change in a single place, rather than having to search and replace through a dozen files.
+
+
+=== Ruby on Rails's Philosophies: Convention-Over-Configuration and Don't-Repeat-Yourself ===
+
+Ruby on Rails is intended to emphasize *Convention over Configuration* (CoC), and the agile programming principle of *Don't repeat yourself* (DRY). But what do these terms mean?
+
+``Don't repeat yourself'' means that information is located in a single, unambiguous place. The careful reader will notice that that the model file lacks sort of database column definitions. Traditionally, web developers have to define database table information in their databases (in the form of a schema) and again in their applications. However, there are very few good reasons why such information should be duplicated, and -- indeed -- such duplication could lead to code maintenance problems. Ruby on Rails's database abstraction layer -- called 'ActiveRecord' -- automatically infers how your 'books' database table looks like, by performing database introspection.
+
+Ruby on Rails also places emphasis on ``Convention over Configuration''. For example, ActiveRecord automatically infers from the model class's name, `Book`, that the database table should be called 'books'. By following this naming convention, the developer need not to write a lot of configuration files.
+
+These philosophies are intended to speed up development and to reduce redundant information in the code base. DRY and CoC are key properties of the Ruby on Rails framework, and they are reflected throughout all of the framework.
+
+That said, it is still possible to tell ActiveRecord that the database table has a different name. So Ruby on Rails does not force you follow conventions, but you should carefully consider whether you will want to deviate from the convention because of the development speed advantages that following conventions will give you.
+
+
+=== What's Next ===
+
+In the next chapter, we'll get started with Ruby on Rails, covering installation and initial setup.
diff --git a/railties/doc/guides/routing/routing_outside_in.txt b/railties/doc/guides/routing/routing_outside_in.txt
new file mode 100644
index 0000000000..aecfb949e9
--- /dev/null
+++ b/railties/doc/guides/routing/routing_outside_in.txt
@@ -0,0 +1,819 @@
+Rails Routing from the Outside In
+=================================
+
+This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:
+
+* Understand the purpose of routing
+* Decipher the code in +routing.rb+
+* Construct your own routes, using either the classic hash style or the now-preferred RESTful style
+* Identify how a route will map to a controller and action
+
+== The Dual Purpose of Routing
+
+Rails routing is a two-way piece of machinery - rather as if you could turn trees into paper, and then turn paper back into trees. Specifically, it both connects incoming HTTP requests to the code in your application's controllers, and helps you generate URLs without having to hard-code them as strings.
+
+=== Connecting URLs to Code
+
+When your Rails application receives an incoming HTTP request, say
+
+-------------------------------------------------------
+GET /patient/17
+-------------------------------------------------------
+
+the routing engine within Rails is the piece of code that dispatches the request to the appropriate spot in your application. In this case, the application would most likely end up running the +show+ action within the +patients+ controller, displaying the details of the patient whose ID is 17.
+
+=== Generating URLs from Code
+
+Routing also works in reverse. If your application contains this code:
+
+[source, ruby]
+-------------------------------------------------------
+@patient = Patient.find(17)
+<%= link_to "Patient Record", patient_path(@patient) %>
+-------------------------------------------------------
+
+Then the routing engine is the piece that translates that to a link to a URL such as +http://example.com/patient/17+. By using routing in this way, you can reduce the brittleness of your application as compared to one with hard-coded URLs, and make your code easier to read and understand.
+
+NOTE: Patient needs to be declared as a resource for this style of translation via a named route to be available.
+
+== Quick Tour of Routes.rb
+
+There are two components to routing in Rails: the routing engine itself, which is supplied as part of Rails, and the file +config/routes.rb+, which contains the actual routes that will be used by your application. Learning exactly what you can put in +routes.rb+ is the main topic of this guide, but before we dig in let's get a quick overview.
+
+=== Processing the File
+
+In format, +routes.rb+ is nothing more than one big block sent to +ActionController::Routing::Routes.draw+. Within this block, you can have comments, but it's likely that most of your content will be individual lines of code - each line being a route in your application. You'll find five main types of content in this file:
+
+* RESTful Routes
+* Named Routes
+* Nested Routes
+* Regular Routes
+* Default Routes
+
+Each of these types of route is covered in more detail later in this guide.
+
+The +routes.rb+ file is processed from top to bottom when a request comes in. The request will be dispatched to the first matching route. If there is no matching route, then Rails returns HTTP status 404 to the caller.
+
+=== RESTful Routes
+
+RESTful routes take advantage of the built-in REST orientation of Rails to wrap up a lot of routing information in a single declaration. A RESTful route looks like this:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :books
+-------------------------------------------------------
+
+=== Named Routes
+
+Named routes give you very readable links in your code, as well as handling incoming requests. Here's a typical named route:
+
+[source, ruby]
+-------------------------------------------------------
+map.login '/login', :controller => 'sessions', :action => 'new'
+-------------------------------------------------------
+
+=== Nested Routes
+
+Nested routes let you declare that one resource is contained within another resource. You'll see later on how this translates to URLs and paths in your code. For example, if your application includes parts, each of which belongs to an assembly, you might have this nested route declaration:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :assemblies do |assemblies|
+ assemblies.resources :parts
+end
+-------------------------------------------------------
+
+=== Regular Routes
+
+In many applications, you'll also see non-RESTful routing, which explicitly connects the parts of a URL to a particular action. For example,
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'parts/:number', :controller => 'inventory', :action => 'show'
+-------------------------------------------------------
+
+=== Default Routes
+
+The default routes are a safety net that catch otherwise-unrouted requests. Many Rails applications will contain this pair of default routes:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id'
+map.connect ':controller/:action/:id.:format'
+-------------------------------------------------------
+
+These default routes are automatically generated when you create a new Rails application. If you're using RESTful routing, you will probably want to remove them.
+
+== RESTful Routing: the Rails Default
+
+RESTful routing is the current standard for routing in Rails, and it's the one that you should prefer for new applications. It can take a little while to understand how RESTful routing works, but it's worth the effort; your code will be easier to read and you'll be working with Rails, rather than fighting against it, when you use this style of routing.
+
+=== What is REST?
+
+The foundation of RESTful routing is generally considered to be Roy Fielding's doctoral thesis, link:http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm[Architectural Styles and the Design of Network-based Software Architectures]. Fortunately, you need not read this entire document to understand how REST works in Rails. REST, an acronym for Representational State Transfer, boils down to two main principles for our purposes:
+
+* Using resource identifiers (which, for the purposes of discussion, you can think of as URLs) to represent resources
+* Transferring representations of the state of that resource between system components.
+
+For example, to a Rails application a request such as this:
+
++DELETE /photos/17+
+
+would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities.
+
+=== CRUD, Verbs, and Actions
+
+In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos
+-------------------------------------------------------
+
+creates seven different routes in your application:
+
+[grid="all"]
+`----------`---------------`-----------`--------`-------------------------------------------
+HTTP verb URL controller action used for
+--------------------------------------------------------------------------------------------
+GET /photos Photos index display a list of all photos
+GET /photos/new Photos new return an HTML form for creating a new photo
+POST /photos Photos create create a new photo
+GET /photo/1 Photos show display a specific photo
+GET /photo/1/edit Photos edit return an HTML form for editing a photo
+PUT /photo/1 Photos update update a specific photo
+DELETE /photo/1 Photos destroy delete a specific photo
+--------------------------------------------------------------------------------------------
+
+For the specific routes (those that reference just a single resource), the identifier for the resource will be available within the corresponding controller action as +params[:id]+.
+
+TIP: If you consistently use RESTful routes in your application, you should disable the default routes in +routes.rb+ so that Rails will enforce the mapping between HTTP verbs and routes.
+
+=== URLs and Paths
+
+Creating a RESTful route will also make available a pile of helpers within your application:
+
+* +photos_url+ and +photos_path+ map to the path for the index and create actions
+* +new_photo_url+ and +new_photo_path+ map to the path for the new action
+* +edit_photo_url+ and +edit_photo_path+ map to the path for the edit action
+* +photo_url+ and +photo_path+ map to the path for the show, update, and destroy actions
+
+NOTE: Because routing makes use of the HTTP verb as well as the path in the request to dispatch requests, the seven routes generated by a RESTful routing entry only give rise to four pairs of helpers.
+
+In each case, the +_url+ helper generates a string containing the entire URL that the application will understand, while the +_path+ helper generates a string containing the relative path from the root of the application. For example:
+
+[source, ruby]
+-------------------------------------------------------
+photos_url # => "http://www.example.com/photos"
+photos_path # => "/photos"
+-------------------------------------------------------
+
+=== Singular Resources
+
+You can also apply RESTful routing to singleton resources within your application. In this case, you use +map.resource+ instead of +map.resources+ and the route generation is slightly different. For example, a routing entry of
+
+[source, ruby]
+-------------------------------------------------------
+map.resource geocoder
+-------------------------------------------------------
+
+creates seven different routes in your application:
+
+[grid="all"]
+`----------`---------------`-----------`--------`-------------------------------------------
+HTTP verb URL controller action used for
+--------------------------------------------------------------------------------------------
+GET /geocoder/new Geocoders new return an HTML form for creating the new geocoder
+POST /geocoder Geocoders create create the new geocoder
+GET /geocoder Geocoders show display the one and only geocoder resource
+GET /geocoder/edit Geocoders edit return an HTML form for editing the geocoder
+PUT /geocoder Geocoders update update the one and only geocoder resource
+DELETE /geocoder Geocoders destroy delete the geocoder resource
+--------------------------------------------------------------------------------------------
+
+NOTE: Even though the name of the resource is singular in +routes.rb+, the matching controller is still plural.
+
+A singular RESTful route generates an abbreviated set of helpers:
+
+* +new_geocoder_url+ and +new_geocoder_path+ map to the path for the new action
+* +edit_geocoder_url+ and +edit_geocoder_path+ map to the path for the edit action
+* +geocoder_url+ and +geocoder_path+ map to the path for the create, show, update, and destroy actions
+
+=== Customizing Resources
+
+Although the conventions of RESTful routing are likely to be sufficient for many applications, there are a number of ways to customize the way that RESTful routes work. These options include:
+
+* +:controller+
+* +:singular+
+* +:requirements+
+* +:conditions+
+* +:as+
+* +:path_names+
+* +:path_prefix+
+* +:name_prefix+
+
+You can also add additional routes via the +:member+ and +:collection+ options, which are discussed later in this guide.
+
+==== Using :controller
+
+The +:controller+ option lets you use a controller name that is different from the public-facing resource name. For example, this routing entry:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :controller => "images"
+-------------------------------------------------------
+
+will recognize incoming URLs containing +photo+ but route the requests to the Images controller:
+
+[grid="all"]
+`----------`---------------`-----------`--------`-------------------------------------------
+HTTP verb URL controller action used for
+--------------------------------------------------------------------------------------------
+GET /photos Images index display a list of all images
+GET /photos/new Images new return an HTML form for creating a new image
+POST /photos Images create create a new image
+GET /photo/1 Images show display a specific image
+GET /photo/1/edit Images edit return an HTML form for editing a image
+PUT /photo/1 Images update update a specific image
+DELETE /photo/1 Images destroy delete a specific image
+--------------------------------------------------------------------------------------------
+
+NOTE: The helpers will be generated with the name of the resource, not the name of the controller. So in this case, you'd still get +photos_path+, +photos_new_path+, and so on.
+
+==== Using :singular
+
+If for some reason Rails isn't doing what you want in converting the plural resource name to a singular name in member routes, you can override its judgment with the +:singular+ option:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :teeth, :singular => "tooth"
+-------------------------------------------------------
+
+TIP: Depending on the other code in your application, you may prefer to add additional rules to the +Inflector+ class instead.
+
+==== Using :requirements
+
+You an use the +:requirements+ option in a RESTful route to impose a format on the implied +:id+ parameter in the singular routes. For example:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :requirements => {:id => /[A-Z][A-Z][0-9]+/}
+-------------------------------------------------------
+
+This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, +/photos/1+ would no longer be recognized by this route, but +/photos/RR27+ would.
+
+==== Using :conditions
+
+Conditions in Rails routing are currently used only to set the HTTP verb for individual routes. Although in theory you can set this for RESTful routes, in practice there is no good reason to do so. (You'll learn more about conditions in the discussion of classic routing later in this guide.)
+
+==== Using :as
+
+The +:as+ option lets you override the normal naming for the actual generated paths. For example:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :as => "images"
+-------------------------------------------------------
+
+will recognize incoming URLs containing +image+ but route the requests to the Photos controller:
+
+[grid="all"]
+`----------`---------------`-----------`--------`-------------------------------------------
+HTTP verb URL controller action used for
+--------------------------------------------------------------------------------------------
+GET /images Photos index display a list of all photos
+GET /images/new Photos new return an HTML form for creating a new photo
+POST /images Photos create create a new photo
+GET /image/1 Photos show display a specific photo
+GET /image/1/edit Photos edit return an HTML form for editing a photo
+PUT /image/1 Photos update update a specific photo
+DELETE /image/1 Photos destroy delete a specific photo
+--------------------------------------------------------------------------------------------
+
+NOTE: The helpers will be generated with the name of the resource, not the path name. So in this case, you'd still get +photos_path+, +photos_new_path+, and so on.
+
+==== Using :path_names
+
+The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in URLs:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :path_names => { :new => 'make', :edit => 'change' }
+-------------------------------------------------------
+
+This would cause the routing to recognize URLs such as
+
+-------------------------------------------------------
+/photos/make
+/photos/1/change
+-------------------------------------------------------
+
+NOTE: The actual action names aren't changed by this option; the two URLs show would still route to the new and edit actions.
+
+TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can set a default in your environment:
+
+[source, ruby]
+-------------------------------------------------------
+config.action_controller.resources_path_names = { :new => 'make', :edit => 'change' }
+-------------------------------------------------------
+
+==== Using :path_prefix
+
+The +:path_prefix+ option lets you add additional parameters that will be prefixed to the recognized paths. For example, suppose each photo in your application belongs to a particular photographer. In that case, you might declare this route:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :path_prefix => '/photographers/:photographer_id'
+-------------------------------------------------------
+
+Routes recognized by this entry would include:
+
+-------------------------------------------------------
+/photographers/1/photo/2
+/photographers/1/photos
+-------------------------------------------------------
+
+NOTE: In most cases, it's simpler to recognize URLs of this sort by creating nested resources, as discussed in the next section.
+
+==== Using :name_prefix
+
+You can use the :name_prefix option to avoid collisions between routes. This is most useful when you have two resources with the same name that use +:path_prefix+ to map differently. For example:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources photos, :path_prefix => '/photographers/:photographer_id', :name_prefix => 'photographer_'
+map.resources photos, :path_prefix => '/agencies/:agency_id', :name_prefix => 'agency_'
+-------------------------------------------------------
+
+This combination will give you route helpers such as +photographer_photos_path+ and +agency_photo_edit_path+ to use in your code.
+
+=== Nested Resources
+
+It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
+
+[source, ruby]
+-------------------------------------------------------
+class Magazine < ActiveRecord::Base
+ has_many :ads
+end
+
+class Ad < ActiveRecord::Base
+ belongs_to :magazine
+end
+-------------------------------------------------------
+
+Each ad is logically subservient to one magazine. Nested routes allow you to capture this relationship in your routing. In this case, you might include this route declaration:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :magazines do |magazine|
+ magazine.resources :ads
+end
+-------------------------------------------------------
+
+In addition to the routes for magazines, this declaration will also create routes for ads, each of which requires the specification of a magazine in the URL:
+
+[grid="all"]
+`----------`-----------------------`-----------`--------`-------------------------------------------
+HTTP verb URL controller action used for
+--------------------------------------------------------------------------------------------
+GET /magazines/1/ads Ads index display a list of all ads for a specific magazine
+GET /magazines/1/ads/new Ads new return an HTML form for creating a new ad belonging to a specific magazine
+POST /magazines/1/ads Ads create create a new photo belonging to a specific magazine
+GET /magazines/1/ad/1 Ads show display a specific photo belonging to a specific magazine
+GET /magazines/1/ad/1/edit Ads edit return an HTML form for editing a photo belonging to a specific magazine
+PUT /magazines/1/ad/1 Ads update update a specific photo belonging to a specific magazine
+DELETE /magazines/1/ad/1 Ads destroy delete a specific photo belonging to a specific magazine
+--------------------------------------------------------------------------------------------
+
+This will also create routing helpers such as +magazine_ads_url+ and +magazine_edit_ad_path+.
+
+==== Using :name_prefix
+
+The +:name_prefix+ option overrides the automatically-generated prefix in nested route helpers. For example,
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :magazines do |magazine|
+ magazine.resources :ads, :name_prefix => 'periodical'
+end
+-------------------------------------------------------
+
+This will create routing helpers such as +periodical_ads_url+ and +periodical_edit_ad_path+. You can even use +:name_prefix+ to suppress the prefix entirely:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :magazines do |magazine|
+ magazine.resources :ads, :name_prefix => nil
+end
+-------------------------------------------------------
+
+This will create routing helpers such as +ads_url+ and +edit_ad_path+. Note that calling these will still require supplying an article id:
+
+[source, ruby]
+-------------------------------------------------------
+ads_url(@magazine)
+edit_ad_path(@magazine, @ad)
+-------------------------------------------------------
+
+==== Using :has_one and :has_many
+
+The +:has_one+ and +:has_many+ options provide a succinct notation for simple nested routes. Use +:has_one+ to nest a singleton resource, or +:has_many+ to nest a plural resource:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos, :has_one => :photographer, :has_many => [:publications, :versions]
+-------------------------------------------------------
+
+This has the same effect as this set of declarations:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos do |photo|
+ photo.resource :photographer
+ photo.resources :publications
+ photo.resources :versions
+end
+-------------------------------------------------------
+
+==== Limits to Nesting
+
+You can nest resources within other nested resources if you like. For example:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :publishers do |publisher|
+ publisher.resources :magazines do |magazine|
+ magazine.resources :photos
+ end
+end
+-------------------------------------------------------
+
+However, without the use of +name_prefix => nil+, deeply-nested resources quickly become cumbersome. In this case, for example, the application would recognize URLs such as
+
+-------------------------------------------------------
+/publishers/1/magazines/2/photos/3
+-------------------------------------------------------
+
+The corresponding route helper would be +publisher_magazine_photo_url+, requiring you to specify objects at all three levels.
+
+==== Shallow Nesting
+
+The +:shallow+ option provides an elegant solution to the difficulties of deeply-nested routes. If you specify this option at any level of routing, then paths for nested resources which reference a specific member (that is, those with an +:id+ parameter) will not use the parent path prefix or name prefix. To see what this means, consider this set of routes:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :publishers, :shallow => true do |publisher|
+ publisher.resources :magazines do |magazine|
+ magazine.resources :photos
+ end
+end
+-------------------------------------------------------
+
+This will enable recognition of (among others) these routes:
+
+-------------------------------------------------------
+/publishers/1 ==> publisher_path(1)
+/publishers/1/magazines ==> publisher_magazines_path(1)
+/magazines/2 ==> magazine_path(2)
+/magazines/2/photos ==> magazines_photos_path(2)
+/photos/3 ==> photo_path(3)
+-------------------------------------------------------
+
+=== Adding More RESTful Actions
+
+You are not limited to the seven routes that RESTful routing creates by default. If you like, you may add additional member routes (those which apply to a single instance of the resource), additional new routes (those that apply to creating a new resource), or additional collection routes (those which apply to the collection of resources as a whole).
+
+==== Adding Member Routes
+
+To add a member route, use the +:member+ option:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos, :member => { :preview => :get }
+-------------------------------------------------------
+
+This will enable Rails to recognize URLs such as +/photos/1/preview+ using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create a +preview_photo+ route helper.
+
+Within the hash of member routes, each route name specifies the HTTP verb that it will recognize. You can use +:get+, +:put+, +:post+, +:delete+, or +:any+ here.
+
+==== Adding Collection Routes
+
+To add a collection route, use the +:collection+ option:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos, :collection => { :search => :get }
+-------------------------------------------------------
+
+This will enable Rails to recognize URLs such as +/photos/search+ using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create a +search_photos+ route helper.
+
+==== Adding New Routes
+
+To add a new route (one that creates a new resource), use the +:new+ option:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos, :new => { :upload => :post }
+-------------------------------------------------------
+
+This will enable Rails to recognize URLs such as +/photos/upload+ using the POST HTTP verb, and route them to the upload action of the Photos controller. It will also create a +upload_photos+ route helper.
+
+TIP: If you want to redefine the verbs accepted by one of the standard actions, you can do so by explicitly mapping that action. For example:
+
+[source, ruby]
+-------------------------------------------------------
+map.resources :photos, :new => { :new => :any }
+-------------------------------------------------------
+
+This will allow the new action to be invoked by any request to +photos/new+, no matter what HTTP verb you use.
+
+==== A Note of Caution
+
+If you find yourself adding many extra actions to a RESTful route, it's time to stop and ask yourself whether you're disguising the presence of another resource that would be better split off on its own. When the +:member+ and +:collection+ hashes become a dumping-ground, RESTful routes lose the advantage of easy readability that is one of their strongest points.
+
+== Regular Routes
+
+In addition to RESTful routing, Rails supports regular routing - a way to map URLs to controllers and actions. With regular routing, you don't get the masses of routes automatically generated by RESTful routing. Instead, you must set up each route within your application separately.
+
+While RESTful routing has become the Rails standard, there are still plenty of places where the simpler regular routing works fine. You can even mix the two styles within a single application. In general, you should prefer RESTful routing _when possible_, because it will make parts of your application easier to write. But there's no need to try to shoehorn every last piece of your application into a RESTful framework if that's not a good fit.
+
+=== Bound Parameters
+
+When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: +:controller+ maps to the name of a controller in your application, and +:action+ maps to the name of an action within that controller. For example, consider one of the default Rails routes:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id'
+-------------------------------------------------------
+
+If an incoming request of +/photos/show/1+ is processed by this route (because it hasn't matched any previous route in the file), then the result will be to invoke the +show+ action of the +Photos+ controller, and to make the final parameter (1) available as +params[:id]+.
+
+=== Wildcard Components
+
+You can set up as many wildcard symbols within a regular route as you like. Anything other than +:controller+ or +:action+ will be available to the matching action as part of the params hash. So, if you set up this route:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id/:userid:'
+-------------------------------------------------------
+
+An incoming URL of +/photos/show/1/2+ will be dispatched to the +show+ action of the +Photos+ controller. +params[:id]+ will be set to 1, and +params[:user_id]+ will be set to 2.
+
+=== Static Text
+
+You can specify static text when creating a route. In this case, the static text is used only for matching the incoming requests:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id/with_user/:userid:'
+-------------------------------------------------------
+
+This route would respond to URLs such as +/photos/show/1/with_user/2+.
+
+=== Querystring Parameters
+
+Rails routing automatically picks up querystring parameters and makes them available in the +params+ hash. For example, with this route:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id'
+-------------------------------------------------------
+
+An incoming URL of +/photos/show/1?user_id=2+ will be dispatched to the +show+ action of the +Photos+ controller. +params[:id]+ will be set to 1, and +params[:user_id]+ will be equal to 2.
+
+=== Defining Defaults
+
+You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply defaults for these two parameters in a hash:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'photo/:id', :controller => 'photos', :action => 'show'
+-------------------------------------------------------
+
+With this route, an incoming URL of +/photos/12+ would be dispatched to the +show+ action within the +Photos+ controller.
+
+=== Named Routes
+
+Regular routes need not use the +connect+ method. You can use any other name here to create a _named route_. For example,
+
+[source, ruby]
+-------------------------------------------------------
+map.logout '/logout', :controller => 'sessions', :action => 'destroy'
+-------------------------------------------------------
+
+This will do two things. First, requests to +/logout+ will be sent to the +destroy+ method of the +Sessions+ controller. Second, Rails will maintain the +logout_path+ and +logout_url+ helpers for use within your code.
+
+=== Route Requirements
+
+You can use the +:requirements+ option to enforce a format for any parameter in a route:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'photo/:id', :controller => 'photos', :action => 'show',
+ :requirements => { :id => /[A-Z]\d{5}/ }
+-------------------------------------------------------
+
+This route would respond to URLs such as +/photo/A12345+. You can more succinctly express the same route this way:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'photo/:id', :controller => 'photos', :action => 'show',
+ :id => /[A-Z]\d{5}/
+-------------------------------------------------------
+
+=== Route Conditions
+
+Route conditions (introduced with the +:conditions+ option) are designed to implement restrictions on routes. Currently, the only supported restriction is +:method+:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'photo/:id', :controller => 'photos', :action => 'show',
+ :conditions => { :method => :get }
+-------------------------------------------------------
+
+As with conditions in RESTful routes, you can specify +:get+, +:post+, +:put+, +:delete+, or +:any+ for the acceptable method.
+
+=== Route Globbing
+
+Route globbing is a way to specify that a particular parameter (which must be the last parameter in the route) should engulf all the remaining parts of a route. For example
+
+[source, ruby]
+-------------------------------------------------------
+map.connect 'photo/*other', :controller => 'photos', :action => 'unknown',
+-------------------------------------------------------
+
+This route would match +photo/12+ or +/photo/long/path/to/12+ equally well, creating an array of path segments as the value of +params[:other]+.
+
+=== Route Options
+
+You can use +:with_options+ to simplify defining groups of similar routes:
+
+[source, ruby]
+-------------------------------------------------------
+map.with_options :controller => 'photo' do |photo|
+ photo.list '', :action => 'index'
+ photo.delete ':id/delete', :action => 'delete'
+ photo.edit ':id/edit', :action => 'edit'
+end
+-------------------------------------------------------
+
+The importance of +map.with_options+ has declined with the introduction of RESTful routes.
+
+== Formats and respond_to
+
+There's one more way in which routing can do different things depending on differences in the incoming HTTP request: by issuing a response that corresponds to what the request specifies that it will accept. In Rails routing, you can control this with the special +:format+ parameter in the route.
+
+For instance, consider the second of the default routes in the boilerplate +routes.rb+ file:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id.:format'
+-------------------------------------------------------
+
+This route matches requests such as +/photo/new/1.xml+ or +/photo/show/2.rss+. Within the appropriate action code, you can issue different responses depending on the requested format:
+
+[source, ruby]
+-------------------------------------------------------
+respond_to do |format|
+ format.html # return the default template for HTML
+ format.xml { render :xml => @photo.to_xml }
+end
+-------------------------------------------------------
+
+=== Specifying the Format with an HTTP Header
+
+If there is no +:format+ parameter in the route, Rails will automatically look at the HTTP Accept header to determine the desired format.
+
+=== Recognized MIME types
+
+By default, Rails recognizes +html+, +text+, +json+, +csv+, +xml+, +rss+, +atom+, and +yaml+ as acceptable response types. If you need types beyond this, you can register them in your environment:
+
+[source, ruby]
+-------------------------------------------------------
+Mime::Type.register "image/jpg", :jpg
+-------------------------------------------------------
+
+== The Default Routes
+
+When you create a new Rails application, +routes.rb+ is initialized with two default routes:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect ':controller/:action/:id'
+map.connect ':controller/:action/:id.:format'
+-------------------------------------------------------
+
+These routes provide reasonable defaults for many URLs, if you're not using RESTful routing.
+
+NOTE: The default routes will make every action of every controller in your application accessible to GET requests. If you've designed your application to make consistent use of RESTful and named routes, you should comment out the default routes.
+
+== The Empty Route
+
+Don't confuse the default routes with the empty route. The empty route has one specific purpose: to route requests that come in to the root of the web site. For example, if your site is example.com, then requests to +http://example.com+ or +http://example.com/+ will be handled by the empty route.
+
+=== Using map.root
+
+The preferred way to set up the empty route is with the +map.root+ command:
+
+[source, ruby]
+-------------------------------------------------------
+map.root :controller => "pages", :action => "main"
+-------------------------------------------------------
+
+The use of the +root+ method tells Rails that this route applies to requests for the root of the site.
+
+For better readability, you can specify an already-created route in your call to +map.root+:
+
+[source, ruby]
+-------------------------------------------------------
+map.index :controller => "pages", :action => "main"
+map.root :index
+-------------------------------------------------------
+
+Because of the top-down processing of the file, the named route must be specified _before_ the call to +map.route+.
+
+=== Connecting the Empty String
+
+You can also specify an empty route by explicitly connecting the empty string:
+
+[source, ruby]
+-------------------------------------------------------
+map.connect '', :controller => "pages", :action => "main"
+-------------------------------------------------------
+
+TIP: If the empty route does not seem to be working in your application, make sure that you have deleted the file +public/index.html+ from your Rails tree.
+
+== Inspecting and Testing Routes
+
+Routing in your application should not be a "black box" that you never open. Rails offers built-in tools for both inspecting and testing routes.
+
+=== Seeing Existing Routes with rake
+
+If you want a complete list of all of the available routes in your application, run the +rake routes+ command. This will dump all of your routes to the console, in the same order that they appear in +routes.rb+. For each route, you'll see:
+
+* The route name (if any)
+* The HTTP verb used (if the route doesn't respond to all verbs)
+* The URL pattern
+* The routing parameters that will be generated by this URL
+
+For example, here's a small section of the +rake routes+ output for a RESTful route:
+
+-------------------------------------------------------------------------------------------------------
+ users GET /users {:controller=>"users", :action=>"index"}
+formatted_users GET /users.:format {:controller=>"users", :action=>"index"}
+ POST /users {:controller=>"users", :action=>"create"}
+ POST /users.:format {:controller=>"users", :action=>"create"}
+-------------------------------------------------------------------------------------------------------
+
+TIP: You'll find that the output from +rake routes+ is much more readable if you widen your terminal window until the output lines don't wrap.
+
+=== Testing Routes
+
+Routes should be included in your testing strategy (just like the rest of your application). Rails offers three link:http://api.rubyonrails.com/classes/ActionController/Assertions/RoutingAssertions.html[built-in assertions] designed to make testing routes simpler:
+
+* +assert_generates+
+* +assert_recognizes+
+* +assert_routing+
+
+==== The +assert_generates+ Assertion
+
+Use +assert_generates+ to assert that a particular set of options generate a particular path. You can use this with default routes or custom routes
+
+[source, ruby]
+-------------------------------------------------------
+assert_generates("/photo/1", { :controller => "photos", :action => "show", :id => "1" })
+assert_generates("/about", :controller => "pages", :action => "about")
+-------------------------------------------------------
+
+==== The +assert_recognizes+ Assertion
+
+The +assert_recognizes+ assertion is the inverse of +assert_generates+. It asserts that Rails recognizes the given path and routes it to a particular spot in your application.
+
+[source, ruby]
+-------------------------------------------------------
+assert_recognizes({ :controller => "photos", :action => "show", :id => "1" }, "/photo/1")
+-------------------------------------------------------
+
+You can supply a +:method+ argument to specify the HTTP verb:
+
+[source, ruby]
+-------------------------------------------------------
+assert_recognizes({ :controller => "photos", :action => "create" }, { :path => "photos", :method => :post })
+-------------------------------------------------------
+
+You can also use the RESTful helpers to test recognition of a RESTful route:
+
+[source, ruby]
+-------------------------------------------------------
+assert_recognizes(new_photo_url, { :path => "photos", :method => :post })
+-------------------------------------------------------
+
+==== The +assert_routing+ Assertion
+
+The +assert_routing+ assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of +assert_generates+ and +assert_recognizes+.
+
+[source, ruby]
+-------------------------------------------------------
+assert_recognizes({ :path => "photos", :method => :post }, { :controller => "photos", :action => "create" })
+------------------------------------------------------- \ No newline at end of file