railties 3.0.0.beta2 → 3.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/CHANGELOG +6 -2
  2. data/guides/{images → assets/images}/belongs_to.png +0 -0
  3. data/guides/{images → assets/images}/book_icon.gif +0 -0
  4. data/guides/{images → assets/images}/bullet.gif +0 -0
  5. data/guides/{images → assets/images}/challenge.png +0 -0
  6. data/guides/{images → assets/images}/chapters_icon.gif +0 -0
  7. data/guides/{images → assets/images}/check_bullet.gif +0 -0
  8. data/guides/{images → assets/images}/credits_pic_blank.gif +0 -0
  9. data/guides/{images → assets/images}/csrf.png +0 -0
  10. data/guides/{images → assets/images}/customized_error_messages.png +0 -0
  11. data/guides/{images → assets/images}/edge_badge.png +0 -0
  12. data/guides/{images → assets/images}/error_messages.png +0 -0
  13. data/guides/{images → assets/images}/feature_tile.gif +0 -0
  14. data/guides/{images → assets/images}/footer_tile.gif +0 -0
  15. data/guides/{images → assets/images}/fxn.png +0 -0
  16. data/guides/{images → assets/images}/grey_bullet.gif +0 -0
  17. data/guides/{images → assets/images}/habtm.png +0 -0
  18. data/guides/{images → assets/images}/has_many.png +0 -0
  19. data/guides/{images → assets/images}/has_many_through.png +0 -0
  20. data/guides/{images → assets/images}/has_one.png +0 -0
  21. data/guides/{images → assets/images}/has_one_through.png +0 -0
  22. data/guides/{images → assets/images}/header_backdrop.png +0 -0
  23. data/guides/{images → assets/images}/header_tile.gif +0 -0
  24. data/guides/{images → assets/images}/i18n/demo_localized_pirate.png +0 -0
  25. data/guides/{images → assets/images}/i18n/demo_translated_en.png +0 -0
  26. data/guides/{images → assets/images}/i18n/demo_translated_pirate.png +0 -0
  27. data/guides/{images → assets/images}/i18n/demo_translation_missing.png +0 -0
  28. data/guides/{images → assets/images}/i18n/demo_untranslated.png +0 -0
  29. data/guides/{images → assets/images}/icons/README +0 -0
  30. data/guides/{images → assets/images}/icons/callouts/1.png +0 -0
  31. data/guides/{images → assets/images}/icons/callouts/10.png +0 -0
  32. data/guides/{images → assets/images}/icons/callouts/11.png +0 -0
  33. data/guides/{images → assets/images}/icons/callouts/12.png +0 -0
  34. data/guides/{images → assets/images}/icons/callouts/13.png +0 -0
  35. data/guides/{images → assets/images}/icons/callouts/14.png +0 -0
  36. data/guides/{images → assets/images}/icons/callouts/15.png +0 -0
  37. data/guides/{images → assets/images}/icons/callouts/2.png +0 -0
  38. data/guides/{images → assets/images}/icons/callouts/3.png +0 -0
  39. data/guides/{images → assets/images}/icons/callouts/4.png +0 -0
  40. data/guides/{images → assets/images}/icons/callouts/5.png +0 -0
  41. data/guides/{images → assets/images}/icons/callouts/6.png +0 -0
  42. data/guides/{images → assets/images}/icons/callouts/7.png +0 -0
  43. data/guides/{images → assets/images}/icons/callouts/8.png +0 -0
  44. data/guides/{images → assets/images}/icons/callouts/9.png +0 -0
  45. data/guides/{images → assets/images}/icons/caution.png +0 -0
  46. data/guides/{images → assets/images}/icons/example.png +0 -0
  47. data/guides/{images → assets/images}/icons/home.png +0 -0
  48. data/guides/{images → assets/images}/icons/important.png +0 -0
  49. data/guides/{images → assets/images}/icons/next.png +0 -0
  50. data/guides/{images → assets/images}/icons/note.png +0 -0
  51. data/guides/{images → assets/images}/icons/prev.png +0 -0
  52. data/guides/{images → assets/images}/icons/tip.png +0 -0
  53. data/guides/{images → assets/images}/icons/up.png +0 -0
  54. data/guides/{images → assets/images}/icons/warning.png +0 -0
  55. data/guides/assets/images/jaimeiniesta.jpg +0 -0
  56. data/guides/{images → assets/images}/nav_arrow.gif +0 -0
  57. data/guides/{images → assets/images}/polymorphic.png +0 -0
  58. data/guides/{images → assets/images}/posts_index.png +0 -0
  59. data/guides/{images → assets/images}/rails_guides_logo.gif +0 -0
  60. data/guides/{images → assets/images}/rails_logo_remix.gif +0 -0
  61. data/guides/{images → assets/images}/rails_welcome.png +0 -0
  62. data/guides/{images → assets/images}/session_fixation.png +0 -0
  63. data/guides/{images → assets/images}/tab_grey.gif +0 -0
  64. data/guides/{images → assets/images}/tab_info.gif +0 -0
  65. data/guides/{images → assets/images}/tab_note.gif +0 -0
  66. data/guides/{images → assets/images}/tab_red.gif +0 -0
  67. data/guides/{images → assets/images}/tab_yellow.gif +0 -0
  68. data/guides/{images → assets/images}/tab_yellow.png +0 -0
  69. data/guides/{images → assets/images}/validation_error_messages.png +0 -0
  70. data/guides/{files → assets}/javascripts/code_highlighter.js +0 -0
  71. data/guides/{files → assets}/javascripts/guides.js +0 -0
  72. data/guides/{files → assets}/javascripts/highlighters.js +0 -0
  73. data/guides/{files → assets}/stylesheets/main.css +26 -15
  74. data/guides/{files → assets}/stylesheets/print.css +0 -0
  75. data/guides/{files → assets}/stylesheets/reset.css +0 -0
  76. data/guides/{files → assets}/stylesheets/style.css +0 -0
  77. data/guides/{files → assets}/stylesheets/syntax.css +0 -0
  78. data/guides/rails_guides/generator.rb +79 -29
  79. data/guides/rails_guides/helpers.rb +2 -2
  80. data/guides/rails_guides/indexer.rb +24 -11
  81. data/guides/source/2_2_release_notes.textile +1 -1
  82. data/guides/source/3_0_release_notes.textile +27 -1
  83. data/guides/source/action_controller_overview.textile +7 -7
  84. data/guides/source/action_view_overview.textile +15 -15
  85. data/guides/source/active_record_querying.textile +4 -3
  86. data/guides/source/active_support_core_extensions.textile +6 -6
  87. data/guides/source/activerecord_validations_callbacks.textile +1 -1
  88. data/guides/source/association_basics.textile +83 -82
  89. data/guides/source/command_line.textile +16 -12
  90. data/guides/source/configuring.textile +1 -1
  91. data/guides/source/contribute.textile +1 -1
  92. data/guides/source/contributing_to_rails.textile +3 -4
  93. data/guides/source/credits.html.erb +64 -0
  94. data/guides/source/debugging_rails_applications.textile +2 -1
  95. data/guides/source/form_helpers.textile +15 -13
  96. data/guides/source/getting_started.textile +9 -8
  97. data/guides/source/index.html.erb +154 -0
  98. data/guides/source/initialization.textile +4138 -0
  99. data/guides/source/layout.html.erb +15 -7
  100. data/guides/source/layouts_and_rendering.textile +6 -5
  101. data/guides/source/nested_model_forms.textile +3 -3
  102. data/guides/source/performance_testing.textile +4 -4
  103. data/guides/source/plugins.textile +15 -14
  104. data/guides/source/rails_on_rack.textile +1 -1
  105. data/guides/source/routing.textile +379 -490
  106. data/guides/source/security.textile +5 -5
  107. data/guides/source/testing.textile +3 -2
  108. data/lib/rails.rb +7 -2
  109. data/lib/rails/application.rb +9 -2
  110. data/lib/rails/application/configuration.rb +19 -10
  111. data/lib/rails/application/finisher.rb +4 -0
  112. data/lib/rails/backtrace_cleaner.rb +1 -1
  113. data/{bin/rails → lib/rails/cli.rb} +0 -0
  114. data/lib/rails/commands/runner.rb +1 -1
  115. data/lib/rails/configuration.rb +12 -0
  116. data/lib/rails/engine.rb +6 -10
  117. data/lib/rails/engine/configuration.rb +2 -3
  118. data/lib/rails/generators.rb +1 -6
  119. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +0 -7
  120. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +10 -1
  121. data/lib/rails/generators/erb/scaffold/templates/show.html.erb +2 -0
  122. data/lib/rails/generators/migration.rb +3 -3
  123. data/lib/rails/generators/rails/app/app_generator.rb +1 -1
  124. data/lib/rails/generators/rails/app/templates/Gemfile +2 -0
  125. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +1 -0
  126. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +14 -0
  127. data/lib/rails/generators/rails/app/templates/config/application.rb +4 -1
  128. data/lib/rails/generators/rails/app/templates/config/boot.rb +5 -13
  129. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +3 -0
  130. data/lib/rails/generators/rails/app/templates/config/initializers/{cookie_verification_secret.rb.tt → secret_token.rb.tt} +1 -1
  131. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -3
  132. data/lib/rails/generators/rails/app/templates/public/index.html +2 -1
  133. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +41 -32
  134. data/lib/rails/generators/rails/app/templates/test/{test_helper.rb → test_helper.rb.tt} +2 -0
  135. data/lib/rails/generators/rails/model/USAGE +15 -0
  136. data/lib/rails/generators/rails/stylesheets/templates/scaffold.css +3 -8
  137. data/lib/rails/paths.rb +17 -5
  138. data/lib/rails/plugin.rb +1 -1
  139. data/lib/rails/railtie.rb +3 -25
  140. data/lib/rails/test_unit/testing.rake +11 -7
  141. data/lib/rails/version.rb +1 -1
  142. data/lib/rails/webrick_server.rb +2 -2
  143. metadata +93 -92
  144. data/guides/source/credits.textile.erb +0 -60
  145. data/guides/source/index.textile.erb +0 -139
  146. data/lib/rails/generators/erb/scaffold/templates/layout.html.erb +0 -17
  147. data/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory +0 -0
@@ -1,19 +1,27 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
1
4
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
2
5
  <head>
3
6
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
4
7
 
5
8
  <title><%= yield(:page_title) || 'Ruby on Rails guides' %></title>
6
9
 
7
- <link rel="stylesheet" type="text/css" href="files/stylesheets/style.css" />
8
- <link rel="stylesheet" type="text/css" href="files/stylesheets/syntax.css" />
9
- <link rel="stylesheet" type="text/css" href="files/stylesheets/print.css" media="print" />
10
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
11
+ <link rel="stylesheet" type="text/css" href="stylesheets/syntax.css" />
12
+ <link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
10
13
 
11
- <script type="text/javascript" src="files/javascripts/guides.js"></script>
12
- <script type="text/javascript" src="files/javascripts/code_highlighter.js"></script>
13
- <script type="text/javascript" src="files/javascripts/highlighters.js"></script>
14
+ <script type="text/javascript" src="javascripts/guides.js"></script>
15
+ <script type="text/javascript" src="javascripts/code_highlighter.js"></script>
16
+ <script type="text/javascript" src="javascripts/highlighters.js"></script>
14
17
 
15
18
  </head>
16
19
  <body class="guide">
20
+ <% if @edge %>
21
+ <div>
22
+ <img src="images/edge_badge.png" alt="edge-badge" id="edge-badge" />
23
+ </div>
24
+ <% end %>
17
25
  <div id="topNav">
18
26
  <div class="wrapper">
19
27
  <strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
@@ -101,7 +109,7 @@
101
109
  <hr class="hide" />
102
110
  <div id="footer">
103
111
  <div class="wrapper">
104
- <p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</a></p>
112
+ <p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
105
113
  <p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
106
114
  </div>
107
115
  </div>
@@ -510,7 +510,7 @@ def show
510
510
  end
511
511
  </ruby>
512
512
 
513
- Make sure you use +and return+ and not +&& return+ because while the former will work, the latter will not due to operator precedence in the Ruby Language.
513
+ Make sure you use +and return+ and not +&amp;&amp; return+ because while the former will work, the latter will not due to operator precedence in the Ruby Language.
514
514
 
515
515
  Note that the implicit render done by ActionController detects if +render+ has been called, and thus avoids this error. Therefore, the following will work without errors:
516
516
 
@@ -747,7 +747,7 @@ You can even use dynamic paths such as +cache/#{current_site}/main/display+.
747
747
 
748
748
  h5. Linking to CSS Files with +stylesheet_link_tag+
749
749
 
750
- The +stylesheet_link_tag+ helper returns an HTML +<link>+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.cs+:
750
+ The +stylesheet_link_tag+ helper returns an HTML +&lt;link&gt;+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.cs+:
751
751
 
752
752
  <erb>
753
753
  <%= stylesheet_link_tag "main" %>
@@ -1037,7 +1037,7 @@ You can also pass local variables into partials, making them even more powerful
1037
1037
  * +_form.html.erb+
1038
1038
 
1039
1039
  <erb>
1040
- <% form_for(zone) do |f| %>
1040
+ <%= form_for(zone) do |f| %>
1041
1041
  <p>
1042
1042
  <b>Zone name</b><br />
1043
1043
  <%= f.text_field :name %>
@@ -1181,11 +1181,11 @@ On pages generated by +NewsController+, you want to hide the top menu and add a
1181
1181
  <% content_for :stylesheets do %>
1182
1182
  #top_menu {display: none}
1183
1183
  #right_menu {float: right; background-color: yellow; color: black}
1184
- <% end -%>
1184
+ <% end %>
1185
1185
  <% content_for :content do %>
1186
1186
  <div id="right_menu">Right menu items here</div>
1187
1187
  <%= yield(:news_content) or yield %>
1188
- <% end -%>
1188
+ <% end %>
1189
1189
  <%= render :file => 'layouts/application' %>
1190
1190
  </erb>
1191
1191
 
@@ -1197,6 +1197,7 @@ h3. Changelog
1197
1197
 
1198
1198
  "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/15
1199
1199
 
1200
+ * April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
1200
1201
  * January 25, 2010: Rails 3.0 Update by "Mikel Lindsaar":credits.html#raasdnil
1201
1202
  * December 27, 2008: Merge patch from Rodrigo Rosenfeld Rosas covering subtemplates
1202
1203
  * December 27, 2008: Information on new rendering defaults by "Mike Gunderloy":credits.html#mgunderloy
@@ -122,7 +122,7 @@ h5. Standard form
122
122
  Start out with a regular RESTful form:
123
123
 
124
124
  <erb>
125
- <% form_for @person do |f| %>
125
+ <%= form_for @person do |f| %>
126
126
  <%= f.text_field :name %>
127
127
  <% end %>
128
128
  </erb>
@@ -140,7 +140,7 @@ h5. Nested form for a single associated object
140
140
  Now add a nested form for the +address+ association:
141
141
 
142
142
  <erb>
143
- <% form_for @person do |f| %>
143
+ <%= form_for @person do |f| %>
144
144
  <%= f.text_field :name %>
145
145
 
146
146
  <% f.fields_for :address do |af| %>
@@ -181,7 +181,7 @@ h5. Nested form for a collection of associated objects
181
181
  The form code for an association collection is pretty similar to that of a single associated object:
182
182
 
183
183
  <erb>
184
- <% form_for @person do |f| %>
184
+ <%= form_for @person do |f| %>
185
185
  <%= f.text_field :name %>
186
186
 
187
187
  <% f.fields_for :projects do |pf| %>
@@ -213,11 +213,11 @@ h4. Understanding the Output
213
213
 
214
214
  Performance tests generate different outputs inside +tmp/performance+ directory depending on their mode and metric.
215
215
 
216
- h5. Benchmarking
216
+ h5(#output-benchmarking). Benchmarking
217
217
 
218
218
  In benchmarking mode, performance tests generate two types of outputs:
219
219
 
220
- h6. Command Line
220
+ h6(#output-command-line). Command Line
221
221
 
222
222
  This is the primary form of output in benchmarking mode. Example:
223
223
 
@@ -258,7 +258,7 @@ measurement,created_at,app,rails,ruby,platform
258
258
  0.00771250000000012,2009-01-09T15:46:03Z,,2.3.0.master.859e150,ruby-1.8.6.110,i686-darwin9.0.0
259
259
  </shell>
260
260
 
261
- h5. Profiling
261
+ h5(#output-profiling). Profiling
262
262
 
263
263
  In profiling mode, you can choose from four types of output.
264
264
 
@@ -330,7 +330,7 @@ h5. Apply the Patch
330
330
 
331
331
  h5. Configure and Install
332
332
 
333
- The following will install ruby in your home directory's +/rubygc+ directory. Make sure to replace +<homedir>+ with a full patch to your actual home directory.
333
+ The following will install ruby in your home directory's +/rubygc+ directory. Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home directory.
334
334
 
335
335
  <shell>
336
336
  [lifo@null ruby-version]$ ./configure --prefix=/<homedir>/rubygc
@@ -35,14 +35,14 @@ h4. Create the Basic Application
35
35
 
36
36
  The examples in this guide require that you have a working rails application. To create a simple rails app execute:
37
37
 
38
- <pre>
38
+ <shell>
39
39
  gem install rails
40
40
  rails yaffle_guide
41
41
  cd yaffle_guide
42
42
  rails generate scaffold bird name:string
43
43
  rake db:migrate
44
44
  rails server
45
- </pre>
45
+ </shell>
46
46
 
47
47
  Then navigate to http://localhost:3000/birds. Make sure you have a functioning rails app before continuing.
48
48
 
@@ -56,22 +56,22 @@ Rails ships with a plugin generator which creates a basic plugin skeleton. Pass
56
56
  This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as well as standard 'lib', 'task', and 'test' directories.
57
57
 
58
58
  Examples:
59
- <pre>
59
+ <shell>
60
60
  rails generate plugin yaffle
61
61
  rails generate plugin yaffle --with-generator
62
- </pre>
62
+ </shell>
63
63
 
64
64
  To get more detailed help on the plugin generator, type +rails generate plugin+.
65
65
 
66
66
  Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the +--with-generator+ option now:
67
67
 
68
- <pre>
68
+ <shell>
69
69
  rails generate plugin yaffle --with-generator
70
- </pre>
70
+ </shell>
71
71
 
72
72
  You should see the following output:
73
73
 
74
- <pre>
74
+ <shell>
75
75
  create vendor/plugins/yaffle/lib
76
76
  create vendor/plugins/yaffle/tasks
77
77
  create vendor/plugins/yaffle/test
@@ -89,20 +89,20 @@ create vendor/plugins/yaffle/generators/yaffle
89
89
  create vendor/plugins/yaffle/generators/yaffle/templates
90
90
  create vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb
91
91
  create vendor/plugins/yaffle/generators/yaffle/USAGE
92
- </pre>
92
+ </shell>
93
93
 
94
94
  h4. Organize Your Files
95
95
 
96
96
  To make it easy to organize your files and to make the plugin more compatible with GemPlugins, start out by altering your file system to look like this:
97
97
 
98
- <pre>
98
+ <shell>
99
99
  |-- lib
100
100
  | |-- yaffle
101
101
  | `-- yaffle.rb
102
102
  `-- rails
103
103
  |
104
104
  `-- init.rb
105
- </pre>
105
+ </shell>
106
106
 
107
107
  *vendor/plugins/yaffle/init.rb*
108
108
 
@@ -124,7 +124,7 @@ h4. Test Setup
124
124
 
125
125
  *vendor/plugins/yaffle/test/database.yml:*
126
126
 
127
- <pre>
127
+ <yaml>
128
128
  sqlite:
129
129
  :adapter: sqlite
130
130
  :dbfile: vendor/plugins/yaffle/test/yaffle_plugin.sqlite.db
@@ -146,7 +146,7 @@ mysql:
146
146
  :username: root
147
147
  :password: password
148
148
  :database: yaffle_plugin_test
149
- </pre>
149
+ </yaml>
150
150
 
151
151
  For this guide you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following:
152
152
 
@@ -239,10 +239,10 @@ end
239
239
 
240
240
  To run this, go to the plugin directory and run +rake+:
241
241
 
242
- <pre>
242
+ <shell>
243
243
  cd vendor/plugins/yaffle
244
244
  rake
245
- </pre>
245
+ </shell>
246
246
 
247
247
  You should see output like:
248
248
 
@@ -1511,4 +1511,5 @@ h3. Changelog
1511
1511
 
1512
1512
  "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/32-update-plugins-guide
1513
1513
 
1514
+ * April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
1514
1515
  * November 17, 2008: Major revision by Jeff Dean
@@ -28,7 +28,7 @@ h3. Rails on Rack
28
28
 
29
29
  h4. Rails Application's Rack Object
30
30
 
31
- <tt>ActionController::Dispatcher.new</tt> is the primary Rack application object of a Rails application. Any Rack compliant web server should be using +ActionController::Dispatcher.new+ object to serve a Rails application.</p>
31
+ <tt>ActionController::Dispatcher.new</tt> is the primary Rack application object of a Rails application. Any Rack compliant web server should be using +ActionController::Dispatcher.new+ object to serve a Rails application.
32
32
 
33
33
  h4. +rails server+
34
34
 
@@ -2,180 +2,111 @@ h2. Rails Routing from the Outside In
2
2
 
3
3
  This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:
4
4
 
5
- * Understand the purpose of routing
6
- * Decipher the code in +routes.rb+
7
- * Construct your own routes, using either the @match@ method or the preferred RESTful style
8
- * Identify how a route will map to a controller and action
5
+ * Understand the code in +routes.rb+
6
+ * Construct your own routes, using either the preferred resourceful style or with the @match@ method
7
+ * Identify what parameters to expect an action to receive
8
+ * Automatically create URLs using route helpers
9
+ * Use advanced techniques such as constraints and Rack endpoints
9
10
 
10
11
  endprologue.
11
12
 
12
- h3. The Dual Purpose of Routing
13
+ h3. The Purpose of the Rails Router
13
14
 
14
- 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.
15
+ The Rails router recognizes URLs and dispatches them to a controller's action. It can also generate URLs, avoiding the need to hardcode URL strings in your views.
15
16
 
16
17
  h4. Connecting URLs to Code
17
18
 
18
- When your Rails application receives an incoming HTTP request, say
19
+ When your Rails application receives an incoming request
19
20
 
20
- <pre>
21
+ <plain>
21
22
  GET /patients/17
22
- </pre>
23
-
24
- 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.
25
-
26
- h4. Generating URLs from Code
27
-
28
- Routing also works in reverse. If your application contains this code:
29
-
30
- <ruby>
31
- @patient = Patient.find(17)
32
- </ruby>
33
-
34
- <erb>
35
- <%= link_to "Patient Record", patient_path(@patient) %>
36
- </erb>
37
-
38
- Then the routing engine is the piece that translates that to a link to a URL such as +http://example.com/patients/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.
39
-
40
- NOTE: Patient needs to be declared as a Restful resource for this style of translation to be available.
41
-
42
- h3. Quick Tour of +routes.rb+
43
-
44
- 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.
45
-
46
- h4. Processing the File
47
-
48
- In format, +routes.rb+ is nothing more than one big block sent to +ApplicationName::Application.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:
49
-
50
- * RESTful Routes
51
- * Named Routes
52
- * Nested Routes
53
- * Regular Routes
54
- * Default Routes
23
+ </plain>
55
24
 
56
- Each of these types of route is covered in more detail later in this guide.
57
-
58
- 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, and then proceeds to the next. If there is no matching route, then Rails returns HTTP status 404 to the caller.
59
-
60
- h4. RESTful Routes
61
-
62
- RESTful routes take advantage of the built-in REST orientation of Rails to wrap up a lot of routing information with a single declaration. A RESTful route looks like this:
25
+ it asks the router to match it to a controller action. If the first matching route is
63
26
 
64
27
  <ruby>
65
- resources :books
28
+ match "/patients/:id" => "patients#show"
66
29
  </ruby>
67
30
 
68
- h4. Named Routes
69
-
70
- Named routes give you very readable links in your code, as well as handling incoming requests. Here's a typical named route:
31
+ the request is dispatched to the +patients+ controller's +show+ action with <tt>{ :id => "17" }</tt> in +params+.
71
32
 
72
- <ruby>
73
- match 'login' => 'sessions#new', :as => 'login'
74
- </ruby>
33
+ h4. Generating URLs from Code
75
34
 
76
- If you're coming from Rails 2, this route will be equivalent to:
35
+ You can also generate routes. If your application contains this code:
77
36
 
78
37
  <ruby>
79
- map.login '/login', :controller => 'sessions', :action => 'new'
38
+ @patient = Patient.find(17)
80
39
  </ruby>
81
40
 
82
- You will also notice that +sessions#new+ is a shorthand for +:controller => 'sessions', :action => 'new'+. By declaring a named route such as this, you can use +login_path+ or +login_url+ in your controllers and views to generate the URLs for this route.
41
+ <erb>
42
+ <%= link_to "Patient Record", patients_path(@patient.id) %>
43
+ </erb>
83
44
 
84
- h4. Nested Routes
45
+ The router will generate the path +/patients/17+. This reduces the brittleness of your view and makes your code easier to understand.
85
46
 
86
- 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:
47
+ h3. Resource Routing: the Rails Default
87
48
 
88
- <ruby>
89
- resources :assemblies do
90
- resources :parts
91
- end
92
- </ruby>
49
+ Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+ actions, a resourceful route declares them in a single line of code.
93
50
 
94
- h4. Regular Routes
51
+ h4. Resources on the Web
95
52
 
96
- In many applications, you'll also see non-RESTful routing, which explicitly connects the parts of a URL to a particular action. For example,
53
+ Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as +GET+, +POST+, +PUT+ and +DELETE+. Each method is a request to perform an operation on the resource. A resource route maps a number of related request to the actions in a single controller.
97
54
 
98
- <ruby>
99
- match 'parts/:number' => 'inventory#show'
100
- </ruby>
55
+ When your Rails application receives an incoming request for
101
56
 
102
- h4. Default Routes
57
+ <plain>
58
+ DELETE /photos/17
59
+ </plain>
103
60
 
104
- The default route is a safety net that catches otherwise-unrouted requests. Many Rails applications will contain this default route:
61
+ it asks the router to map it to a controller action. If the first matching route is
105
62
 
106
63
  <ruby>
107
- match ':controller(/:action(/:id(.:format)))'
64
+ resources :photos
108
65
  </ruby>
109
66
 
110
- In Rails 3, this route is commented out advising to use RESTful routes as much as possible. So if you're using RESTful routing for everything in your application, you will probably want to leave it like that.
111
-
112
- h3. RESTful Routing: the Rails Default
113
-
114
- 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.
115
-
116
- h4. What is REST?
117
-
118
- The foundation of RESTful routing is generally considered to be Roy Fielding's doctoral thesis, "Architectural Styles and the Design of Network-based Software Architectures":http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm. 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:
119
-
120
- * Using resource identifiers (which, for the purposes of discussion, you can think of as URLs) to represent resources
121
- * Transferring representations of the state of that resource between system components.
122
-
123
- For example, to a Rails application a request such as this:
124
-
125
- <pre>
126
- DELETE /photos/17
127
- </pre>
128
-
129
- 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.
67
+ Rails would dispatch that request to the +destroy+ method on the +photos+ controller with <tt>{ :id => "17" }</tt> in +params+.
130
68
 
131
69
  h4. CRUD, Verbs, and Actions
132
70
 
133
- 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
71
+ In Rails, a resourceful route provides a mapping between HTTP verbs and URLs and controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as
134
72
 
135
73
  <ruby>
136
74
  resources :photos
137
75
  </ruby>
138
76
 
139
- creates seven different routes in your application:
140
-
141
- |_.HTTP verb|_.URL |_.controller|_.action |_.used for|
142
- |GET |/photos |Photos |index |display a list of all photos|
143
- |GET |/photos/new |Photos |new |return an HTML form for creating a new photo|
144
- |POST |/photos |Photos |create |create a new photo|
145
- |GET |/photos/1 |Photos |show |display a specific photo|
146
- |GET |/photos/1/edit |Photos |edit |return an HTML form for editing a photo|
147
- |PUT |/photos/1 |Photos |update |update a specific photo|
148
- |DELETE |/photos/1 |Photos |destroy |delete a specific photo|
77
+ creates seven different routes in your application, all mapping to the +Photos+ controller:
149
78
 
150
- 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]+.
79
+ |_. Verb |_.URL |_.action |_.used for|
80
+ |GET |/photos |index |display a list of all photos|
81
+ |GET |/photos/new |new |return an HTML form for creating a new photo|
82
+ |POST |/photos |create |create a new photo|
83
+ |GET |/photos/:id |show |display a specific photo|
84
+ |GET |/photos/:id/edit |edit |return an HTML form for editing a photo|
85
+ |PUT |/photos/:id |update |update a specific photo|
86
+ |DELETE |/photos/:id |destroy |delete a specific photo|
151
87
 
152
88
  h4. URLs and Paths
153
89
 
154
- Creating a RESTful route will also make available a pile of helpers within your application, something that requires explicit mention otherwise:
90
+ Creating a resourceful route will also expose a number of helpers to the controllers in your application. In the case of +resources :photos+:
155
91
 
156
- * +photos_url+ and +photos_path+ map to the path for the index and create actions
157
- * +new_photo_url+ and +new_photo_path+ map to the path for the new action
158
- * +edit_photo_url+ and +edit_photo_path+ map to the path for the edit action
159
- * +photo_url+ and +photo_path+ map to the path for the show, update, and destroy actions
92
+ * +photos_path+ returns +/photos+
93
+ * +new_photo_path+ returns +/photos/new+
94
+ * +edit_photo_path+ returns +/photos/edit+
95
+ * +photo_path(id)+ returns +/photos/:id+ (for instance, +photo_path(10)+ returns +/photos/10+)
160
96
 
161
- 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.
97
+ Each of these helpers has a corresponding +_url+ helper (such as +photos_url+) which returns the same path prefixed with the current host, port and path prefix.
162
98
 
163
- 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:
164
-
165
- <ruby>
166
- photos_url # => "http://www.example.com/photos"
167
- photos_path # => "/photos"
168
- </ruby>
99
+ NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
169
100
 
170
101
  h4. Defining Multiple Resources at the Same Time
171
102
 
172
- If you need to create routes for more than one RESTful resource, you can save a bit of typing by defining them all with a single call to +resources+:
103
+ If you need to create routes for more than one resource, you can save a bit of typing by defining them all with a single call to +resources+:
173
104
 
174
105
  <ruby>
175
106
  resources :photos, :books, :videos
176
107
  </ruby>
177
108
 
178
- This has exactly the same effect as
109
+ This works exactly the same as
179
110
 
180
111
  <ruby>
181
112
  resources :photos
@@ -185,659 +116,615 @@ resources :videos
185
116
 
186
117
  h4. Singular Resources
187
118
 
188
- You can also apply RESTful routing to singleton resources within your application. In this case, you use +resource+ instead of +resources+ and the route generation is slightly different. For example, a routing entry of
119
+ Sometimes, you have a resource that clients always look up without referencing an ID. A common example, +/profile+ always shows the profile of the currently logged in user. In this case, you can use a singular resource to map +/profile+ (rather than +/profile/:id+) to the +show+ action.
189
120
 
190
121
  <ruby>
191
122
  resource :geocoder
192
123
  </ruby>
193
124
 
194
- creates six different routes in your application:
195
-
196
- |_.HTTP verb|_.URL |_.controller|_.action |_.used for|
197
- |GET |/geocoder/new |Geocoders |new |return an HTML form for creating the new geocoder|
198
- |POST |/geocoder |Geocoders |create |create the new geocoder|
199
- |GET |/geocoder |Geocoders |show |display the one and only geocoder resource|
200
- |GET |/geocoder/edit |Geocoders |edit |return an HTML form for editing the geocoder|
201
- |PUT |/geocoder |Geocoders |update |update the one and only geocoder resource|
202
- |DELETE |/geocoder |Geocoders |destroy |delete the geocoder resource|
203
-
204
- NOTE: Even though the name of the resource is singular in +routes.rb+, the matching controller is still plural.
125
+ creates six different routes in your application, all mapping to the +Geocoders+ controller:
205
126
 
206
- A singular RESTful route generates an abbreviated set of helpers:
127
+ |_. Verb |_.URL |_.action |_.used for|
128
+ |GET |/geocoder/new |new |return an HTML form for creating the geocoder|
129
+ |POST |/geocoder |create |create the new geocoder|
130
+ |GET |/geocoder |show |display the one and only geocoder resource|
131
+ |GET |/geocoder/edit |edit |return an HTML form for editing the geocoder|
132
+ |PUT |/geocoder |update |update the one and only geocoder resource|
133
+ |DELETE |/geocoder |destroy |delete the geocoder resource|
207
134
 
208
- * +new_geocoder_url+ and +new_geocoder_path+ map to the path for the new action
209
- * +edit_geocoder_url+ and +edit_geocoder_path+ map to the path for the edit action
210
- * +geocoder_url+ and +geocoder_path+ map to the path for the create, show, update, and destroy actions
135
+ NOTE: Because you might want to use the same controller for a singular route (+/account+) and a plural route (+/accounts/45+), singular resources map to plural controllers.
211
136
 
212
- h4. Customizing Resources
137
+ A singular resourceful route generates these helpers:
213
138
 
214
- 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:
139
+ * +new_geocoder_path+ returns +/geocoder/new+
140
+ * +edit_geocoder_path+ returns +/geocoder/edit+
141
+ * +geocoder_path+ returns +/geocoder+
215
142
 
216
- * +:controller+
217
- * +:singular+
218
- * +:requirements+
219
- * +:conditions+
220
- * +:as+
221
- * +:path_names+
222
- * +:only+
223
- * +:except+
143
+ As with plural resources, the same helpers ending in +_url+ will also include the host, port and path prefix.
224
144
 
225
- You can also add additional routes via the +member+ and +collection+ blocks, which are discussed later in this guide.
226
-
227
- h5. Using +:controller+
145
+ h4. Controller Namespaces and Routing
228
146
 
229
- The +:controller+ option lets you use a controller name that is different from the public-facing resource name. For example, this routing entry:
147
+ You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an +Admin::+ namespace. You would place these controllers under the +app/controllers/admin+ directory, and you can group them together in your router:
230
148
 
231
149
  <ruby>
232
- resources :photos, :controller => "images"
150
+ namespace "admin" do
151
+ resources :posts, :comments
152
+ end
233
153
  </ruby>
234
154
 
235
- will recognize incoming URLs containing +photo+ but route the requests to the Images controller:
155
+ This will create a number of routes for each of the +posts+ and +comments+ controller. For +Admin::PostsController+, Rails will create:
236
156
 
237
- |_.HTTP verb|_.URL |_.controller|_.action |_.used for|
238
- |GET |/photos |Images |index |display a list of all images|
239
- |GET |/photos/new |Images |new |return an HTML form for creating a new image|
240
- |POST |/photos |Images |create |create a new image|
241
- |GET |/photos/1 |Images |show |display a specific image|
242
- |GET |/photos/1/edit |Images |edit |return an HTML form for editing an image|
243
- |PUT |/photos/1 |Images |update |update a specific image|
244
- |DELETE |/photos/1 |Images |destroy |delete a specific image|
157
+ |_. Verb |_.URL |_.action |_. helper |
158
+ |GET |/admin/photos |index | admin_photos_path |
159
+ |GET |/admin/photos/new |new | new_admin_photos_path |
160
+ |POST |/admin/photos |create | admin_photos_path |
161
+ |GET |/admin/photos/1 |show | admin_photo_path(id) |
162
+ |GET |/admin/photos/1/edit |edit | edit_admin_photo_path(id) |
163
+ |PUT |/admin/photos/1 |update | admin_photo_path(id) |
164
+ |DELETE |/admin/photos/1 |destroy | admin_photo_path(id) |
245
165
 
246
- 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+, +new_photo_path+, and so on.
247
-
248
- h4. Controller Namespaces and Routing
249
-
250
- Rails allows you to group your controllers into namespaces by saving them in folders underneath +app/controllers+. The +:controller+ option provides a convenient way to use these routes. For example, you might have a resource whose controller is purely for admin users in the +admin+ folder:
166
+ If you want to route +/photos+ (without the prefix +/admin+) to +Admin::PostsController+, you could use
251
167
 
252
168
  <ruby>
253
- resources :photos, :controller => "admin/photos"
169
+ scope :module => "admin" do
170
+ resources :posts, :comments
171
+ end
254
172
  </ruby>
255
173
 
256
- If you use controller namespaces, you need to be aware of a subtlety in the Rails routing code: it always tries to preserve as much of the namespace from the previous request as possible. For example, if you are on a view generated from the +photo_path+ helper, and you follow a link generated with +&lt;%= link_to "show", photo_path(1) %&gt;+ you will end up on the view generated by +admin/photos/show+, but you will also end up in the same place if you have +&lt;%= link_to "show", {:controller => "photos", :action => "show"} %&gt;+ because Rails will generate the show URL relative to the current URL.
257
-
258
- TIP: If you want to guarantee that a link goes to a top-level controller, use a preceding slash to anchor the controller name: +&lt;%= link_to "show", {:controller => "/photos", :action => "show"} %&gt;+
259
-
260
- You can also specify a controller namespace with the +:namespace+ option instead of a path:
174
+ or, for a single case
261
175
 
262
176
  <ruby>
263
- resources :adminphotos, :namespace => "admin", :controller => "photos"
177
+ resources :posts, :module => "admin"
264
178
  </ruby>
265
179
 
266
- This can be especially useful when map multiple namespaced routes together using +namespace+ block by:
180
+ If you want to route +/admin/photos+ to +PostsController+ (without the +Admin::+ module prefix), you could use
267
181
 
268
182
  <ruby>
269
- namespace :admin do
270
- resources :photos, :videos
183
+ scope "/admin" do
184
+ resources :posts, :comments
271
185
  end
272
186
  </ruby>
273
187
 
274
- That would give you routing for +admin/photos+ and +admin/videos+ controllers.
275
-
276
- The difference between generating routes through +namespace+ and the +:controller+ key is that the +namespace+ will add +admin+ to the generated helpers as well, so the above route generates +admin_photos_path+.
277
-
278
- h5. Using +:singular+
279
-
280
- 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:
188
+ or, for a single case
281
189
 
282
190
  <ruby>
283
- resources :teeth, :singular => "tooth"
191
+ resources :posts, :path => "/admin"
284
192
  </ruby>
285
193
 
286
- TIP: Depending on the other code in your application, you may prefer to add additional rules to the +Inflector+ class instead.
287
-
288
- h5. Using +:requirements+
194
+ In each of these cases, the named routes remain the same as if you did not use +scope+. In the last case, the following URLs map to +PostsController+:
289
195
 
290
- You can use the +:requirements+ option in a RESTful route to impose a format on the implied +:id+ parameter in the singular routes. For example:
196
+ |_. Verb |_.URL |_.action |_. helper |
197
+ |GET |photos |index | photos_path |
198
+ |GET |photos/new |new | photos_path |
199
+ |POST |photos |create | photos_path |
200
+ |GET |photos/1 |show | photo_path(id) |
201
+ |GET |photos/1/edit |edit | dmin_photo_path(id) |
202
+ |PUT |photos/1 |update | photo_path(id) |
203
+ |DELETE |photos/1 |destroy | photo_path(id) |
291
204
 
292
- <ruby>
293
- resources :photos, :requirements => {:id => /[A-Z][A-Z][0-9]+/}
294
- </ruby>
295
-
296
- 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.
205
+ h4. Nested Resources
297
206
 
298
- h5. Using +:conditions+
207
+ It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
299
208
 
300
- 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.)
209
+ <ruby>
210
+ class Magazine < ActiveRecord::Base
211
+ has_many :ads
212
+ end
301
213
 
302
- h5. Using +:as+
214
+ class Ad < ActiveRecord::Base
215
+ belongs_to :magazine
216
+ end
217
+ </ruby>
303
218
 
304
- The +:as+ option lets you override the normal naming for the actual generated paths. For example:
219
+ Nested routes allow you to capture this relationship in your routing. In this case, you could include this route declaration:
305
220
 
306
221
  <ruby>
307
- resources :photos, :as => "images"
222
+ resources :magazines do
223
+ resources :ads
224
+ end
308
225
  </ruby>
309
226
 
310
- will recognize incoming URLs containing +image+ but route the requests to the Photos controller:
227
+ In addition to the routes for magazines, this declaration will also route ads to an +AdsController+. The ad URLs require a magazine:
311
228
 
312
- |_.HTTP verb|_.URL |_.controller|_.action |_:used for|
313
- |GET |/images |Photos |index |display a list of all photos|
314
- |GET |/images/new |Photos |new |return an HTML form for creating a new photo|
315
- |POST |/images |Photos |create |create a new photo|
316
- |GET |/images/1 |Photos |show |display a specific photo|
317
- |GET |/images/1/edit |Photos |edit |return an HTML form for editing a photo|
318
- |PUT |/images/1 |Photos |update |update a specific photo|
319
- |DELETE |/images/1 |Photos |destroy |delete a specific photo|
229
+ |_.Verb |_.URL |_.action |_.used for|
230
+ |GET |/magazines/1/ads |index |display a list of all ads for a specific magazine|
231
+ |GET |/magazines/1/ads/new |new |return an HTML form for creating a new ad belonging to a specific magazine|
232
+ |POST |/magazines/1/ads |create |create a new ad belonging to a specific magazine|
233
+ |GET |/magazines/1/ads/1 |show |display a specific ad belonging to a specific magazine|
234
+ |GET |/magazines/1/ads/1/edit |edit |return an HTML form for editing an ad belonging to a specific magazine|
235
+ |PUT |/magazines/1/ads/1 |update |update a specific ad belonging to a specific magazine|
236
+ |DELETE |/magazines/1/ads/1 |destroy |delete a specific ad belonging to a specific magazine|
320
237
 
321
- 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+, +new_photo_path+, and so on.
322
238
 
323
- h5. Using +:path_names+
239
+ This will also create routing helpers such as +magazine_ads_url+ and +edit_magazine_ad_path+. These helpers take an instance of Magazine as the first parameter (+magazine_ads_url(@magazine)+).
324
240
 
325
- The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in URLs:
241
+ h5. Limits to Nesting
242
+
243
+ You can nest resources within other nested resources if you like. For example:
326
244
 
327
245
  <ruby>
328
- resources :photos, :path_names => { :new => 'make', :edit => 'change' }
246
+ resources :publishers do
247
+ resources :magazines do
248
+ resources :photos
249
+ end
250
+ end
329
251
  </ruby>
330
252
 
331
- This would cause the routing to recognize URLs such as
253
+ Deeply-nested resources quickly become cumbersome. In this case, for example, the application would recognize URLs such as
332
254
 
333
255
  <pre>
334
- /photos/make
335
- /photos/1/change
256
+ /publishers/1/magazines/2/photos/3
336
257
  </pre>
337
258
 
338
- NOTE: The actual action names aren't changed by this option; the two URLs shown would still route to the new and edit actions.
339
-
340
- TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can set a default in your environment:
259
+ The corresponding route helper would be +publisher_magazine_photo_url+, requiring you to specify objects at all three levels. Indeed, this situation is confusing enough that a popular "article":http://weblog.jamisbuck.org/2007/2/5/nesting-resources by Jamis Buck proposes a rule of thumb for good Rails design:
341
260
 
342
- <ruby>
343
- config.action_controller.resources_path_names = { :new => 'make', :edit => 'change' }
344
- </ruby>
261
+ TIP: _Resources should never be nested more than 1 level deep._
345
262
 
346
- h5. Using +:path_prefix+
263
+ h4. Creating URLs From Objects
347
264
 
348
- 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:
265
+ In addition to using the routing helpers, Rails can also create URLs from an array of parameters. For example, suppose you have this set of routes:
349
266
 
350
267
  <ruby>
351
- resources :photos, :path_prefix => '/photographers/:photographer_id'
268
+ resources :magazines do
269
+ resources :ads
270
+ end
352
271
  </ruby>
353
272
 
354
- Routes recognized by this entry would include:
273
+ When using +magazine_ad_path+, you can pass in instances of +Magazine+ and +Ad+ instead of the numeric IDs.
355
274
 
356
- <pre>
357
- /photographers/1/photos/2
358
- /photographers/1/photos
359
- </pre>
360
-
361
- NOTE: In most cases, it's simpler to recognize URLs of this sort by creating nested resources, as discussed in the next section.
275
+ <erb>
276
+ <%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
277
+ </erb>
362
278
 
363
- NOTE: You can also use +:path_prefix+ with non-RESTful routes.
279
+ You can also use +url_for+ with a set of objects, and Rails will automatically determine which route you want:
364
280
 
365
- h5. Using +:name_prefix+
281
+ <erb>
282
+ <%= link_to "Ad details", url_for(@magazine, @ad) %>
283
+ </erb>
366
284
 
367
- 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:
285
+ In this case, Rails will see that +@magazine+ is a +Magazine+ and +@ad+ is an +Ad+ and will therefore use the +magazine_ad_path+ helper. In helpers like +link_to+, you can specify just the object in place of the full +url_for+ call:
368
286
 
369
- <ruby>
370
- resources :photos, :path_prefix => '/photographers/:photographer_id',
371
- :name_prefix => 'photographer_'
372
- resources :photos, :path_prefix => '/agencies/:agency_id',
373
- :name_prefix => 'agency_'
374
- </ruby>
287
+ <erb>
288
+ <%= link_to "Ad details", [@magazine, @ad] %>
289
+ </erb>
375
290
 
376
- This combination will give you route helpers such as +photographer_photos_path+ and +agency_edit_photo_path+ to use in your code.
291
+ If you wanted to link to just a magazine, you could leave out the +Array+:
377
292
 
378
- NOTE: You can also use +:name_prefix+ with non-RESTful routes.
293
+ <erb>
294
+ <%= link_to "Magazine details", @magazine %>
295
+ </erb>
379
296
 
380
- h5. Using +:only+ and +:except+
297
+ This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style.
381
298
 
382
- By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the +:only+ and +:except+ options to fine-tune this behavior. The +:only+ option specifies that only certain routes should be generated:
299
+ h4. Adding More RESTful Actions
383
300
 
384
- <ruby>
385
- resources :photos, :only => [:index, :show]
386
- </ruby>
301
+ You are not limited to the seven routes that RESTful routing creates by default. If you like, you may add additional routes that apply to the collection or individual members of the collection.
387
302
 
388
- With this declaration, a +GET+ request to +/photos+ would succeed, but a +POST+ request to +/photos+ (which would ordinarily be routed to the create action) will fail.
303
+ h5. Adding Member Routes
389
304
 
390
- The +:except+ option specifies a route or list of routes that should _not_ be generated:
305
+ To add a member route, just add +member+ block into resource block:
391
306
 
392
307
  <ruby>
393
- resources :photos, :except => :destroy
308
+ resources :photos do
309
+ member do
310
+ get :preview
311
+ end
312
+ end
394
313
  </ruby>
395
314
 
396
- In this case, all of the normal routes except the route for +destroy+ (a +DELETE+ request to +/photos/<em>id</em>+) will be generated.
315
+ This will recognize +/photos/1/preview+ with GET, and route to the +preview+ action of +PhotosController+. It will also create the +preview_photo_url+ and +preview_photo_path+ helpers.
397
316
 
398
- In addition to an action or a list of actions, you can also supply the special symbols +:all+ or +:none+ to the +:only+ and +:except+ options.
317
+ Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, or +delete+ here. If you don't have multiple +member+ routes, you can also passing +:on+ to a route.
399
318
 
400
- TIP: If your application has many RESTful routes, using +:only+ and +:except+ to generate only the routes that you actually need can cut down on memory use and speed up the routing process.
319
+ <ruby>
320
+ resources :photos do
321
+ get :preview, :on => :member
322
+ end
323
+ </ruby>
401
324
 
402
- h4. Nested Resources
325
+ h5. Adding Collection Routes
403
326
 
404
- It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
327
+ To add a route to the collection:
405
328
 
406
329
  <ruby>
407
- class Magazine < ActiveRecord::Base
408
- has_many :ads
409
- end
410
-
411
- class Ad < ActiveRecord::Base
412
- belongs_to :magazine
330
+ resources :photos do
331
+ collection do
332
+ get :search
333
+ end
413
334
  end
414
335
  </ruby>
415
336
 
416
- 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:
337
+ This will enable Rails to recognize URLs such as +/photos/search+ with GET, and route to the +search+ action of +PhotosController+. It will also create the +search_photos_url+ and +search_photos_path+ route helpers.
338
+
339
+ Just as with member routes, you can pass +:on+ to a route.
417
340
 
418
341
  <ruby>
419
- resources :magazines do
420
- resources :ads
342
+ resources :photos do
343
+ get :search, :on => :collection
421
344
  end
422
345
  </ruby>
423
346
 
424
- TIP: Further below you'll learn about a convenient shortcut for this construct:<br/>+resources :magazines, :has_many => :ads+
425
-
426
- 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:
347
+ h5. A Note of Caution
427
348
 
428
- |_.HTTP verb|_.URL |_.controller|_.action |_.used for|
429
- |GET |/magazines/1/ads |Ads |index |display a list of all ads for a specific magazine|
430
- |GET |/magazines/1/ads/new |Ads |new |return an HTML form for creating a new ad belonging to a specific magazine|
431
- |POST |/magazines/1/ads |Ads |create |create a new ad belonging to a specific magazine|
432
- |GET |/magazines/1/ads/1 |Ads |show |display a specific ad belonging to a specific magazine|
433
- |GET |/magazines/1/ads/1/edit |Ads |edit |return an HTML form for editing an ad belonging to a specific magazine|
434
- |PUT |/magazines/1/ads/1 |Ads |update |update a specific ad belonging to a specific magazine|
435
- |DELETE |/magazines/1/ads/1 |Ads |destroy |delete a specific ad belonging to a specific magazine|
349
+ If you find yourself adding many extra actions to a resourceful route, it's time to stop and ask yourself whether you're disguising the presence of another resource.
436
350
 
351
+ h3. Non-Resourceful Routes
437
352
 
438
- This will also create routing helpers such as +magazine_ads_url+ and +edit_magazine_ad_path+.
353
+ In addition to resource routing, Rails has powerful support for routing arbitrary URLs to actions. Here, you don't get groups of routes automatically generated by resourceful routing. Instead, you set up each route within your application separately.
439
354
 
440
- h5. Using +:name_prefix+
355
+ While you should usually use resourceful routing, there are still many places where the simpler routing is more appropriate. There's no need to try to shoehorn every last piece of your application into a resourceful framework if that's not a good fit.
441
356
 
442
- The +:name_prefix+ option overrides the automatically-generated prefix in nested route helpers. For example,
357
+ In particular, simple routing makes it very easy to map legacy URLs to new Rails actions.
443
358
 
444
- <ruby>
445
- resources :magazines do
446
- resources :ads, :name_prefix => 'periodical'
447
- end
448
- </ruby>
359
+ h4. Bound Parameters
449
360
 
450
- 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:
361
+ 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:
451
362
 
452
363
  <ruby>
453
- resources :magazines do
454
- resources :ads, :name_prefix => nil
455
- end
364
+ match ':controller(/:action(/:id))'
456
365
  </ruby>
457
366
 
458
- This will create routing helpers such as +ads_url+ and +edit_ad_path+. Note that calling these will still require supplying an article id:
367
+ 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 +PhotosController+, and to make the final parameter +"1"+ available as +params[:id]+. This route will also route the incoming request of +/photos+ to +PhotosController+, since +:action+ and +:id+ are optional parameters, denoted by parentheses.
459
368
 
460
- <ruby>
461
- ads_url(@magazine)
462
- edit_ad_path(@magazine, @ad)
463
- </ruby>
464
-
465
- h5. Using +:has_one+ and +:has_many+
369
+ h4. Dynamic Segments
466
370
 
467
- 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:
371
+ You can set up as many dynamic segments within a regular route as you like. Anything other than +:controller+ or +:action+ will be available to the action as part of +params+. If you set up this route:
468
372
 
469
373
  <ruby>
470
- resources :photos, :has_one => :photographer, :has_many => [:publications, :versions]
374
+ match ':controller/:action/:id/:user_id'
471
375
  </ruby>
472
376
 
473
- This has the same effect as this set of declarations:
377
+ An incoming URL of +/photos/show/1/2+ will be dispatched to the +show+ action of the +PhotosController+. +params[:id]+ will be +"1"+, and +params[:user_id]+ will be +"2"+.
474
378
 
475
- <ruby>
476
- resources :photos do
477
- resource :photographer
478
- resources :publications
479
- resources :versions
480
- end
481
- </ruby>
482
-
483
- h5. Limits to Nesting
379
+ h4. Static Segments
484
380
 
485
- You can nest resources within other nested resources if you like. For example:
381
+ You can specify static segments when creating a route.
486
382
 
487
383
  <ruby>
488
- resources :publishers do
489
- resources :magazines do
490
- resources :photos
491
- end
492
- end
384
+ match ':controller/:action/:id/with_user/:user_id'
493
385
  </ruby>
494
386
 
495
- 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
496
-
497
- <pre>
498
- /publishers/1/magazines/2/photos/3
499
- </pre>
500
-
501
- The corresponding route helper would be +publisher_magazine_photo_url+, requiring you to specify objects at all three levels. Indeed, this situation is confusing enough that a popular "article":http://weblog.jamisbuck.org/2007/2/5/nesting-resources by Jamis Buck proposes a rule of thumb for good Rails design:
502
-
503
- TIP: _Resources should never be nested more than 1 level deep._
387
+ This route would respond to URLs such as +/photos/show/1/with_user/2+. In this case, +params+ would be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>.
504
388
 
505
- h5. Shallow Nesting
389
+ h4. The Query String
506
390
 
507
- 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:
391
+ The +params+ will also include any parameters from the query string. For example, with this route:
508
392
 
509
393
  <ruby>
510
- resources :publishers, :shallow => true do
511
- resources :magazines do
512
- resources :photos
513
- end
514
- end
394
+ match ':controller/:action/:id
515
395
  </ruby>
516
396
 
517
- This will enable recognition of (among others) these routes:
397
+ An incoming URL of +/photos/show/1?user_id=2+ will be dispatched to the +show+ action of the +Photos+ controller. +params+ will be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>.
518
398
 
519
- <pre>
520
- /publishers/1 ==> publisher_path(1)
521
- /publishers/1/magazines ==> publisher_magazines_path(1)
522
- /magazines/2 ==> magazine_path(2)
523
- /magazines/2/photos ==> magazines_photos_path(2)
524
- /photos/3 ==> photo_path(3)
525
- </pre>
399
+ h4. Defining Defaults
526
400
 
527
- With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with. If you like, you can combine shallow nesting with the +:has_one+ and +:has_many+ options:
401
+ You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply them as defaults:
528
402
 
529
403
  <ruby>
530
- resources :publishers, :has_many => { :magazines => :photos }, :shallow => true
404
+ match 'photos/:id' => 'photos#show'
531
405
  </ruby>
532
406
 
533
- h4. Route Generation from Arrays
407
+ With this route, Rails will match an incoming URL of +/photos/12+ to the +show+ action of +PhotosController+.
534
408
 
535
- In addition to using the generated routing helpers, Rails can also generate RESTful routes from an array of parameters. For example, suppose you have a set of routes generated with these entries in routes.rb:
409
+ You can also define other defaults in a route by supplying a hash for the +:defaults+ option. This even applies to parameters that you do not specify as dynamic segments. For example:
536
410
 
537
411
  <ruby>
538
- resources :magazines do
539
- resources :ads
540
- end
412
+ match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
541
413
  </ruby>
542
414
 
543
- Rails will generate helpers such as magazine_ad_path that you can use in building links:
415
+ Rails would match +photos/12+ to the +show+ action of +PhotosController+, and set +params[:format]+ to +"jpg"+.
544
416
 
545
- <ruby>
546
- <%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
547
- </ruby>
417
+ h4. Naming Routes
548
418
 
549
- Another way to refer to the same route is with an array of objects:
419
+ You can specify a name for any route using the +:as+ option.
550
420
 
551
421
  <ruby>
552
- <%= link_to "Ad details", [@magazine, @ad] %>
422
+ match 'logout' => 'sessions#destroy', :as => :logout
553
423
  </ruby>
554
424
 
555
- This format is especially useful when you might not know until runtime which of several types of object will be used in a particular link.
425
+ This will create +logout_path+ and +logout_url+ as named helpers in your application. Calling +logout_path+ will return +/logout+
556
426
 
557
- h4. Namespaced Resources
427
+ h4. Segment Constraints
558
428
 
559
- It's possible to do some quite complex things by combining +:path_prefix+ and +:name_prefix+. For example, you can use the combination of these two options to move administrative resources to their own folder in your application:
429
+ You can use the +:constraints+ option to enforce a format for a dynamic segment:
560
430
 
561
431
  <ruby>
562
- resources :photos, :path_prefix => 'admin', :controller => 'admin/photos'
563
- resources :tags, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_tags'
564
- resources :ratings, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_ratings'
432
+ match 'photo/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ }
565
433
  </ruby>
566
434
 
567
- The good news is that if you find yourself using this level of complexity, you can stop. Rails supports _namespaced resources_ to make placing resources in their own folder a snap. Here's the namespaced version of those same three routes:
435
+ This route would match URLs such as +/photo/A12345+. You can more succinctly express the same route this way:
568
436
 
569
437
  <ruby>
570
- namespace :admin do
571
- resources :photos, :has_many => { :tags, :ratings }
572
- end
438
+ match 'photo/:id' => 'photos#show', :id => /[A-Z]\d{5}/
573
439
  </ruby>
574
440
 
575
- As you can see, the namespaced version is much more succinct than the one that spells everything out - but it still creates the same routes. For example, you'll get +admin_photos_url+ that expects to find an +Admin::PhotosController+ and that matches +admin/photos+, and +admin_photos_ratings_path+ that matches +/admin/photos/_photo_id_/ratings+, expecting to use +Admin::RatingsController+. Even though you're not specifying +path_prefix+ explicitly, the routing code will calculate the appropriate +path_prefix+ from the route nesting.
576
-
577
- h4. Adding More RESTful Actions
441
+ h4. Request-Based Constraints
578
442
 
579
- 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).
580
-
581
- h5. Adding Member Routes
443
+ You can also constrain a route based on any method on the <a href="action_controller_overview.html#the-request-object">Request</a> object that returns a +String+.
582
444
 
583
- To add a member route, just add +member+ block into resource block:
445
+ You specify a request-based constraint the same way that you specify a segment constraint:
584
446
 
585
447
  <ruby>
586
- resources :photos do
587
- member do
588
- get :preview
589
- end
590
- end
448
+ match "photo", :constraints => {:subdomain => "admin"}
591
449
  </ruby>
592
450
 
593
- 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 the +preview_photo_url+ and +preview_photo_path+ route helpers.
594
-
595
- Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, +delete+, or +any+ here. If you don't have multiple +member+ route, you can also passing +:on+ to the routing.
451
+ You can also specify constrains in a block form:
596
452
 
597
453
  <ruby>
598
- resources :photos do
599
- get :preview, :on => :member
454
+ namespace "admin" do
455
+ constraints :subdomain => "admin" do
456
+ resources :photos
457
+ end
600
458
  end
601
459
  </ruby>
602
460
 
603
- h5. Adding Collection Routes
461
+ h4. Advanced Constraints
604
462
 
605
- To add a collection route, use the +:collection+ option:
463
+ If you have a more advanced constraint, you can provide an object that responds to +matches?+ that Rails should use. Let's say you wanted to route all users on a blacklist to the +BlacklistController+. You could do:
606
464
 
607
465
  <ruby>
608
- resources :photos do
609
- collection do
610
- get :search
466
+ class BlacklistConstraint
467
+ def initialize
468
+ @ips = Blacklist.retrieve_ips
611
469
  end
612
- end
613
- </ruby>
614
470
 
615
- 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 the +search_photos_url+ and +search_photos_path+ route helpers.
616
-
617
- Just as with member routes, you can passing +:on+ to the routing.
471
+ def matches?(request)
472
+ @ips.include?(request.remote_ip)
473
+ end
474
+ end
618
475
 
619
- <ruby>
620
- resources :photos do
621
- get :search, :on => :collection
476
+ TwitterClone::Application.routes.draw do
477
+ match "*path" => "blacklist#index",
478
+ :constraints => BlacklistConstraint.new
622
479
  end
623
480
  </ruby>
624
481
 
625
- h5. Adding New Routes
482
+ h4. Route Globbing
626
483
 
627
- As of writing, Rails 3 has deprecated +:new+ option from routing. You will need to explicit define the route using +match+ method
484
+ Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
628
485
 
629
486
  <ruby>
630
- resources :photos
631
- match 'photos/new/upload' => 'photos#upload', :as => 'upload_new_photos'
487
+ match 'photo/*other' => 'photos#unknown'
632
488
  </ruby>
633
489
 
634
- h5. A Note of Caution
490
+ This route would match +photo/12+ or +/photo/long/path/to/12+, setting +params[:other]+ to +"12"+ or +"long/path/to/12"+.
635
491
 
636
- 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.
492
+ h4. Redirection
637
493
 
638
- h3. Regular Routes
494
+ You can redirect any path to another path using the +redirect+ helper in your router:
639
495
 
640
- 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.
496
+ <ruby>
497
+ match "/stories" => redirect("/posts")
498
+ </ruby>
641
499
 
642
- 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.
500
+ You can also reuse dynamic segments from the match in the path to redirect to:
643
501
 
644
- h4. Bound Parameters
502
+ <ruby>
503
+ match "/stories/:name" => redirect("/posts/%{name}")
504
+ </ruby>
645
505
 
646
- 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:
506
+ You can also provide a block to redirect, which receives the params and (optionally) the request object:
647
507
 
648
508
  <ruby>
649
- match ':controller(/:action(/:id))'
509
+ match "/stories/:name" => redirect {|params| "/posts/#{params[:name].pluralize}" }
510
+ match "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }
650
511
  </ruby>
651
512
 
652
- 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]+.
513
+ In all of these cases, if you don't provide the leading host (+http://www.example.com+), Rails will take those details from the current request.
653
514
 
654
- h4. Wildcard Components
515
+ h4. Routing to Rack Applications
655
516
 
656
- 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:
517
+ Instead of a String, like +"posts#index"+, which corresponds to the +index+ action in the +PostsController+, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher.
657
518
 
658
519
  <ruby>
659
- match ':controller/:action/:id/:user_id'
520
+ match "/application.js" => Sprockets
660
521
  </ruby>
661
522
 
662
- 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.
523
+ As long as +Sprockets+ responds to +call+ and returns a <tt>[status, headers, body]</tt>, the router won't know the difference between the Rack application and an action.
663
524
 
664
- h4. Static Text
525
+ NOTE: For the curious, +"posts#index"+ actually expands out to +PostsController.action(:index)+, which returns a valid Rack application.
665
526
 
666
- You can specify static text when creating a route. In this case, the static text is used only for matching the incoming requests:
527
+ h4. Using +root+
528
+
529
+ You can specify what Rails should route +"/"+ to with the +root+ method:
667
530
 
668
531
  <ruby>
669
- match ':controller/:action/:id/with_user/:user_id'
532
+ root :to => 'pages#main'
670
533
  </ruby>
671
534
 
672
- This route would respond to URLs such as +/photos/show/1/with_user/2+.
535
+ You should put the +root+ route at the end of the file.
536
+
537
+ h3. Customizing Resourceful Routes
538
+
539
+ While the default routes and helpers generated by +resources :posts+ will usually serve you well, you may want to customize them in some way. Rails allows you to customize virtually any generic part of the resourceful helpers.
673
540
 
674
- h4. Querystring Parameters
541
+ h4. Specifying a Controller to Use
675
542
 
676
- Rails routing automatically picks up querystring parameters and makes them available in the +params+ hash. For example, with this route:
543
+ The +:controller+ option lets you explicitly specify a controller to use for the resource. For example:
677
544
 
678
545
  <ruby>
679
- match ':controller/:action/:id
546
+ resources :photos, :controller => "images"
680
547
  </ruby>
681
548
 
682
- 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.
549
+ will recognize incoming URLs beginning with +/photo+ but route to the +Images+ controller:
683
550
 
684
- h4. Defining Defaults
551
+ |_. Verb |_.URL |_.action |
552
+ |GET |/photos |index |
553
+ |GET |/photos/new |new |
554
+ |POST |/photos |create |
555
+ |GET |/photos/1 |show |
556
+ |GET |/photos/1/edit |edit |
557
+ |PUT |/photos/1 |update |
558
+ |DELETE |/photos/1 |destroy |
559
+
560
+ NOTE: Use +photos_path+, +new_photos_path+, etc. to generate URLs for this resource.
561
+
562
+ h4. Specifying Constraints
685
563
 
686
- You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply defaults for these two parameters by putting it after +=>+:
564
+ You can use the +:constraints+ option to specify a required format on the implicit +id+. For example:
687
565
 
688
566
  <ruby>
689
- match 'photos/:id' => 'photos#show'
567
+ resources :photos, :constraints => {:id => /[A-Z][A-Z][0-9]+/}
690
568
  </ruby>
691
569
 
692
- With this route, an incoming URL of +/photos/12+ would be dispatched to the +show+ action within the +Photos+ controller.
570
+ This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, the router would no longer match +/photos/1+ to this route. Instead, +/photos/RR27+ would match.
693
571
 
694
- You can also define other defaults in a route by supplying a hash for the +:defaults+ option. This even applies to parameters that are not explicitly defined elsewhere in the route. For example:
572
+ You can specify a single constraint to a apply to a number of routes by using the block form:
695
573
 
696
574
  <ruby>
697
- match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
575
+ constraints(:id => /[A-Z][A-Z][0-9]+/) do
576
+ resources :photos
577
+ resources :accounts
578
+ end
698
579
  </ruby>
699
580
 
700
- With this route, an incoming URL of +photos/12+ would be dispatched to the +show+ action within the +Photos+ controller, and +params[:format]+ will be set to +jpg+.
581
+ NOTE: Of course, you can use the more advanced constraints available in non-resourceful routes in this context
701
582
 
702
- h4. Named Routes
583
+ h4. Overriding the Named Helpers
703
584
 
704
- Regular routes need not use the +connect+ method. You can use any other name here to create a _named route_. For example,
585
+ The +:as+ option lets you override the normal naming for the named route helpers. For example:
705
586
 
706
587
  <ruby>
707
- match 'logout' => 'sessions#destroy', :as => :logout
588
+ resources :photos, :as => "images"
708
589
  </ruby>
709
590
 
710
- This will do two things. First, requests to +/logout+ will be sent to the +destroy+ action of the +Sessions+ controller. Second, Rails will maintain the +logout_path+ and +logout_url+ helpers for use within your code.
591
+ will recognize incoming URLs beginning with +/photos+ and route the requests to +PhotosController+:
592
+
593
+ |_.HTTP verb|_.URL |_.action |_.named helper |
594
+ |GET |/photos |index | images_path_ |
595
+ |GET |/photos/new |new | new_image_path |
596
+ |POST |/photos |create | images_path |
597
+ |GET |/photos/1 |show | image_path |
598
+ |GET |/photos/1/edit |edit | edit_image_path |
599
+ |PUT |/photos/1 |update | image_path |
600
+ |DELETE |/photos/1 |destroy | image_path |
711
601
 
712
- h4. Route Requirements
602
+ h4. Overriding the +new+ and +edit+ Segments
713
603
 
714
- You can use the +:requirements+ option to enforce a format for any parameter in a route:
604
+ The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in URLs:
715
605
 
716
606
  <ruby>
717
- match 'photo/:id' => 'photos#show', :requirements => { :id => /[A-Z]\d{5}/ }
607
+ resources :photos, :path_names => { :new => 'make', :edit => 'change' }
718
608
  </ruby>
719
609
 
720
- This route would respond to URLs such as +/photo/A12345+. You can more succinctly express the same route this way:
610
+ This would cause the routing to recognize URLs such as
721
611
 
722
- <ruby>
723
- match 'photo/:id' => 'photos#show', :id => /[A-Z]\d{5}/
724
- </ruby>
612
+ <plain>
613
+ /photos/make
614
+ /photos/1/change
615
+ </plain>
725
616
 
726
- h4. Route Conditions
617
+ NOTE: The actual action names aren't changed by this option. The two URLs shown would still route to the new and edit actions.
727
618
 
728
- Route conditions (introduced with the +:conditions+ option) are designed to implement restrictions on routes. Currently, the only supported restriction is +:method+:
619
+ TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can use a scope:
729
620
 
730
621
  <ruby>
731
- match 'photo/:id' => 'photos#show', :conditions => { :method => :get }
622
+ scope :path_names => { :new => "make" } do
623
+ # rest of your routes
624
+ end
732
625
  </ruby>
733
626
 
734
- As with conditions in RESTful routes, you can specify +:get+, +:post+, +:put+, +:delete+, or +:any+ for the acceptable method.
735
-
736
- h4. Route Globbing
627
+ h4. Overriding the Named Helper Prefix
737
628
 
738
- Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
629
+ You can use the :name_prefix option to add a prefix to the named route helpers that Rails generates for a route. You can use this option to prevent collisions between routes using a path scope.
739
630
 
740
631
  <ruby>
741
- match 'photo/*other' => 'photos#unknown'
742
- </ruby>
632
+ scope "admin" do
633
+ resources :photos, :name_prefix => "admin"
634
+ end
743
635
 
744
- 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]+.
636
+ resources :photos
637
+ </ruby>
745
638
 
746
- h4. Route Options
639
+ This will provide route helpers such as +photographer_photos_path+.
747
640
 
748
- You can use +:with_options+ to simplify defining groups of similar routes:
641
+ You could specify a name prefix to use for a group of routes in the scope:
749
642
 
750
643
  <ruby>
751
- map.with_options :controller => 'photo' do |photo|
752
- photo.list '', :action => 'index'
753
- photo.delete ':id/delete', :action => 'delete'
754
- photo.edit ':id/edit', :action => 'edit'
644
+ scope "admin", :name_prefix => "admin" do
645
+ resources :photos, :accounts
755
646
  end
756
- </ruby>
757
647
 
758
- The importance of +map.with_options+ has declined with the introduction of RESTful routes.
648
+ resources :photos, :accounts
649
+ </ruby>
759
650
 
760
- h3. Formats and +respond_to+
651
+ NOTE: The +namespace+ scope will automatically add a +:name_prefix+ as well as +:module+ and +:path+ prefixes.
761
652
 
762
- 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.
653
+ h4. Restricting the Routes Created
763
654
 
764
- For instance, consider the second of the default routes in the boilerplate +routes.rb+ file:
655
+ By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the +:only+ and +:except+ options to fine-tune this behavior. The +:only+ option tells Rails to create only the specified routes:
765
656
 
766
657
  <ruby>
767
- match ':controller(/:action(/:id(.:format)))'
658
+ resources :photos, :only => [:index, :show]
768
659
  </ruby>
769
660
 
770
- This route matches requests such as +/photo/edit/1.xml+ or +/photo/show/2.rss+. Within the appropriate action code, you can issue different responses depending on the requested format:
661
+ Now, a +GET+ request to +/photos+ would succeed, but a +POST+ request to +/photos+ (which would ordinarily be routed to the +create+ action) will fail.
662
+
663
+ The +:except+ option specifies a route or list of routes that Rails should _not_ create:
771
664
 
772
665
  <ruby>
773
- respond_to do |format|
774
- format.html # return the default template for HTML
775
- format.xml { render :xml => @photo.to_xml }
776
- end
666
+ resources :photos, :except => :destroy
777
667
  </ruby>
778
668
 
779
- h4. Specifying the Format with an HTTP Header
780
-
781
- If there is no +:format+ parameter in the route, Rails will automatically look at the HTTP Accept header to determine the desired format.
782
-
783
- h4. Recognized MIME types
669
+ In this case, Rails will create all of the normal routes except the route for +destroy+ (a +DELETE+ request to +/photos/:id+).
784
670
 
785
- 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:
786
-
787
- <ruby>
788
- Mime::Type.register "image/jpg", :jpg
789
- </ruby>
671
+ TIP: If your application has many RESTful routes, using +:only+ and +:except+ to generate only the routes that you actually need can cut down on memory use and speed up the routing process.
790
672
 
791
- h3. The Default Routes
673
+ h4. Translated Paths
792
674
 
793
- When you create a new Rails application, +routes.rb+ is initialized with a default route:
675
+ Using +scope+, we can alter path names generated by resources:
794
676
 
795
677
  <ruby>
796
- match ':controller(/:action(/:id(.:format)))'
678
+ scope(:path_names => { :new => "neu", :edit => "bearbeiten" }) do
679
+ resources :categories, :path => "kategorien"
680
+ end
797
681
  </ruby>
798
682
 
799
- These routes provide reasonable defaults for many URLs, if you're not using RESTful routing.
683
+ Rails now creates routes to the +CategoriesControlleR+.
800
684
 
801
- 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 to prevent access to your controllers through the wrong verbs. If you've had the default routes enabled during development, though, you need to be sure that you haven't unwittingly depended on them somewhere in your application - otherwise you may find mysterious failures when you disable them.
685
+ |_.HTTP verb|_.URL |_.action |
686
+ |GET |/kategorien |index |
687
+ |GET |/kategorien/neu |new |
688
+ |POST |/kategorien |create |
689
+ |GET |/kategorien/1 |show |
690
+ |GET |/kategorien/:id/bearbeiten |edit |
691
+ |PUT |/kategorien/1 |update |
692
+ |DELETE |/kategorien/1 |destroy |
802
693
 
803
- h3. The Empty Route
694
+ h4. Overriding the Singular Form
804
695
 
805
- 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.
806
-
807
- h4. Using +root+
808
-
809
- The preferred way to set up the empty route is with the +root+ command:
696
+ If you want to customize the singular name of the route in the named helpers, you can use the +:singular+ option.
810
697
 
811
698
  <ruby>
812
- root :to => 'pages#main'
699
+ resources :teeth, :singular => "tooth"
813
700
  </ruby>
814
701
 
815
- The use of the +root+ method tells Rails that this route applies to requests for the root of the site.
702
+ TIP: If you want to define the singular form of a word for your entire application, you should add additional rules to the +Inflector+ instead.
816
703
 
817
- Because of the top-down processing of the file, the named route must be specified _before_ the call to +root+.
704
+ h4(#nested-name-prefix). Using +:name_prefix+ in Nested Resources
818
705
 
819
- h4. Connecting the Empty String
820
-
821
- You can also specify an empty route by explicitly connecting the empty string:
706
+ The +:name_prefix+ option overrides the automatically-generated prefix for the parent resource in nested route helpers. For example,
822
707
 
823
708
  <ruby>
824
- match '' => 'pages#main'
709
+ resources :magazines do
710
+ resources :ads, :name_prefix => 'periodical'
711
+ end
825
712
  </ruby>
826
713
 
827
- 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.
714
+ This will create routing helpers such as +periodical_ads_url+ and +periodical_edit_ad_path+.
828
715
 
829
716
  h3. Inspecting and Testing Routes
830
717
 
831
- 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.
718
+ Rails offers facilities for inspecting and testing your routes.
832
719
 
833
720
  h4. Seeing Existing Routes with +rake+
834
721
 
835
- 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:
722
+ If you want a complete list of all of the available routes in your application, run +rake routes+ command. This will print all of your routes, in the same order that they appear in +routes.rb+. For each route, you'll see:
836
723
 
837
724
  * The route name (if any)
838
725
  * The HTTP verb used (if the route doesn't respond to all verbs)
839
- * The URL pattern
840
- * The routing parameters that will be generated by this URL
726
+ * The URL pattern to match
727
+ * The routing parameters for the route
841
728
 
842
729
  For example, here's a small section of the +rake routes+ output for a RESTful route:
843
730
 
@@ -881,7 +768,7 @@ You can supply a +:method+ argument to specify the HTTP verb:
881
768
  assert_recognizes({ :controller => "photos", :action => "create" }, { :path => "photos", :method => :post })
882
769
  </ruby>
883
770
 
884
- You can also use the RESTful helpers to test recognition of a RESTful route:
771
+ You can also use the resourceful helpers to test recognition of a RESTful route:
885
772
 
886
773
  <ruby>
887
774
  assert_recognizes new_photo_url, { :path => "photos", :method => :post }
@@ -899,6 +786,8 @@ h3. Changelog
899
786
 
900
787
  "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/3
901
788
 
789
+ * April 10, 2010: Updated guide to remove outdated and superfluous information, and to provide information about new features, by "Yehuda Katz":http://www.yehudakatz.com
790
+ * April 2, 2010: Updated guide to match new Routing DSL in Rails 3, by "Rizwan Reza":http://www.rizwanreza.com/
902
791
  * Febuary 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
903
792
  * October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by "Mike Gunderloy":credits.html#mgunderloy
904
793
  * September 23, 2008: Added section on namespaced controllers and routing, by "Mike Gunderloy":credits.html#mgunderloy