rails 4.0.0 → 4.2.11.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -23
- data/guides/CHANGELOG.md +108 -6
- data/guides/Rakefile +21 -6
- data/guides/assets/images/akshaysurve.jpg +0 -0
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/icons/README +1 -1
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +36 -34
- data/guides/assets/stylesheets/main.css +6 -2
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +47 -0
- data/guides/bug_report_templates/action_controller_master.rb +54 -0
- data/guides/bug_report_templates/active_record_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_master.rb +3 -2
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides.rb +23 -4
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/helpers.rb +4 -2
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/source/2_2_release_notes.md +3 -3
- data/guides/source/2_3_release_notes.md +12 -12
- data/guides/source/3_0_release_notes.md +10 -13
- data/guides/source/3_1_release_notes.md +7 -4
- data/guides/source/3_2_release_notes.md +17 -14
- data/guides/source/4_0_release_notes.md +110 -54
- data/guides/source/4_1_release_notes.md +730 -0
- data/guides/source/4_2_release_notes.md +877 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +6 -2
- data/guides/source/action_controller_overview.md +223 -57
- data/guides/source/action_mailer_basics.md +129 -76
- data/guides/source/action_view_overview.md +247 -246
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +374 -20
- data/guides/source/active_record_basics.md +46 -45
- data/guides/source/active_record_callbacks.md +83 -28
- data/guides/source/{migrations.md → active_record_migrations.md} +191 -275
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +382 -300
- data/guides/source/active_record_validations.md +64 -55
- data/guides/source/active_support_core_extensions.md +229 -187
- data/guides/source/active_support_instrumentation.md +23 -22
- data/guides/source/api_documentation_guidelines.md +167 -15
- data/guides/source/asset_pipeline.md +768 -294
- data/guides/source/association_basics.md +188 -96
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +45 -11
- data/guides/source/command_line.md +96 -65
- data/guides/source/configuring.md +404 -70
- data/guides/source/contributing_to_ruby_on_rails.md +270 -130
- data/guides/source/credits.html.erb +7 -3
- data/guides/source/debugging_rails_applications.md +471 -284
- data/guides/source/development_dependencies_install.md +115 -21
- data/guides/source/documents.yaml +31 -9
- data/guides/source/engines.md +737 -291
- data/guides/source/form_helpers.md +137 -89
- data/guides/source/generators.md +60 -28
- data/guides/source/getting_started.md +1007 -596
- data/guides/source/i18n.md +178 -96
- data/guides/source/index.html.erb +2 -1
- data/guides/source/initialization.md +248 -104
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +14 -22
- data/guides/source/layouts_and_rendering.md +78 -46
- data/guides/source/maintenance_policy.md +78 -0
- data/guides/source/nested_model_forms.md +10 -7
- data/guides/source/plugins.md +66 -57
- data/guides/source/rails_application_templates.md +49 -12
- data/guides/source/rails_on_rack.md +50 -60
- data/guides/source/routing.md +190 -139
- data/guides/source/ruby_on_rails_guides_guidelines.md +12 -13
- data/guides/source/security.md +134 -83
- data/guides/source/testing.md +322 -200
- data/guides/source/upgrading_ruby_on_rails.md +834 -37
- data/guides/source/working_with_javascript_in_rails.md +36 -26
- data/guides/w3c_validator.rb +2 -0
- metadata +93 -116
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
- data/guides/assets/images/getting_started/new_post.png +0 -0
- data/guides/assets/images/getting_started/post_with_comments.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/code/getting_started/Gemfile +0 -43
- data/guides/code/getting_started/Gemfile.lock +0 -150
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -16
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -17
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -47
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -3
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -58
- data/guides/code/getting_started/public/422.html +0 -58
- data/guides/code/getting_started/public/500.html +0 -57
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- data/guides/code/getting_started/test/test_helper.rb +0 -15
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -5,7 +5,6 @@ This guide covers Rails integration with Rack and interfacing with other Rack co
|
|
5
5
|
|
6
6
|
After reading this guide, you will know:
|
7
7
|
|
8
|
-
* How to create Rails Metal applications.
|
9
8
|
* How to use Rack Middlewares in your Rails applications.
|
10
9
|
* Action Pack's internal Middleware stack.
|
11
10
|
* How to define a custom Middleware stack.
|
@@ -19,7 +18,7 @@ Introduction to Rack
|
|
19
18
|
|
20
19
|
Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
|
21
20
|
|
22
|
-
|
21
|
+
* [Rack API Documentation](http://rack.github.io/)
|
23
22
|
|
24
23
|
Explaining Rack is not really in the scope of this guide. In case you are not familiar with Rack's basics, you should check out the [Resources](#resources) section below.
|
25
24
|
|
@@ -28,10 +27,9 @@ Rails on Rack
|
|
28
27
|
|
29
28
|
### Rails Application's Rack Object
|
30
29
|
|
31
|
-
`
|
30
|
+
`Rails.application` is the primary Rack application object of a Rails
|
32
31
|
application. Any Rack compliant web server should be using
|
33
|
-
`
|
34
|
-
application. `Rails.application` refers to the same application object.
|
32
|
+
`Rails.application` object to serve a Rails application.
|
35
33
|
|
36
34
|
### `rails server`
|
37
35
|
|
@@ -82,9 +80,8 @@ To use `rackup` instead of Rails' `rails server`, you can put the following insi
|
|
82
80
|
|
83
81
|
```ruby
|
84
82
|
# Rails.root/config.ru
|
85
|
-
require ::File.expand_path('../config/environment',
|
83
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
86
84
|
|
87
|
-
use Rack::Debugger
|
88
85
|
use Rack::ContentLength
|
89
86
|
run Rails.application
|
90
87
|
```
|
@@ -101,6 +98,10 @@ To find out more about different `rackup` options:
|
|
101
98
|
$ rackup --help
|
102
99
|
```
|
103
100
|
|
101
|
+
### Development and auto-reloading
|
102
|
+
|
103
|
+
Middlewares are loaded once and are not monitored for changes. You will have to restart the server for changes to be reflected in the running application.
|
104
|
+
|
104
105
|
Action Dispatcher Middleware Stack
|
105
106
|
----------------------------------
|
106
107
|
|
@@ -113,12 +114,13 @@ NOTE: `ActionDispatch::MiddlewareStack` is Rails equivalent of `Rack::Builder`,
|
|
113
114
|
Rails has a handy rake task for inspecting the middleware stack in use:
|
114
115
|
|
115
116
|
```bash
|
116
|
-
$ rake middleware
|
117
|
+
$ bin/rake middleware
|
117
118
|
```
|
118
119
|
|
119
120
|
For a freshly generated Rails application, this might produce something like:
|
120
121
|
|
121
122
|
```ruby
|
123
|
+
use Rack::Sendfile
|
122
124
|
use ActionDispatch::Static
|
123
125
|
use Rack::Lock
|
124
126
|
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838>
|
@@ -131,6 +133,7 @@ use ActionDispatch::DebugExceptions
|
|
131
133
|
use ActionDispatch::RemoteIp
|
132
134
|
use ActionDispatch::Reloader
|
133
135
|
use ActionDispatch::Callbacks
|
136
|
+
use ActiveRecord::Migration::CheckPending
|
134
137
|
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
135
138
|
use ActiveRecord::QueryCache
|
136
139
|
use ActionDispatch::Cookies
|
@@ -140,10 +143,10 @@ use ActionDispatch::ParamsParser
|
|
140
143
|
use Rack::Head
|
141
144
|
use Rack::ConditionalGet
|
142
145
|
use Rack::ETag
|
143
|
-
run
|
146
|
+
run Rails.application.routes
|
144
147
|
```
|
145
148
|
|
146
|
-
|
149
|
+
The default middlewares shown here (and some others) are each summarized in the [Internal Middlewares](#internal-middleware-stack) section, below.
|
147
150
|
|
148
151
|
### Configuring Middleware Stack
|
149
152
|
|
@@ -181,27 +184,26 @@ You can swap an existing middleware in the middleware stack using `config.middle
|
|
181
184
|
config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions
|
182
185
|
```
|
183
186
|
|
184
|
-
####
|
185
|
-
|
186
|
-
The middleware stack behaves just like a normal `Enumerable`. You can use any `Enumerable` methods to manipulate or interrogate the stack. The middleware stack also implements some `Array` methods including `[]`, `unshift` and `delete`. Methods described in the section above are just convenience methods.
|
187
|
+
#### Deleting a Middleware
|
187
188
|
|
188
|
-
|
189
|
+
Add the following lines to your application configuration:
|
189
190
|
|
190
191
|
```ruby
|
191
192
|
# config/application.rb
|
192
193
|
config.middleware.delete "Rack::Lock"
|
193
194
|
```
|
194
195
|
|
195
|
-
And now if you inspect the middleware stack, you'll find that `Rack::Lock`
|
196
|
+
And now if you inspect the middleware stack, you'll find that `Rack::Lock` is
|
197
|
+
not a part of it.
|
196
198
|
|
197
199
|
```bash
|
198
|
-
$ rake middleware
|
200
|
+
$ bin/rake middleware
|
199
201
|
(in /Users/lifo/Rails/blog)
|
200
202
|
use ActionDispatch::Static
|
201
203
|
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000001c304c8>
|
202
204
|
use Rack::Runtime
|
203
205
|
...
|
204
|
-
run
|
206
|
+
run Rails.application.routes
|
205
207
|
```
|
206
208
|
|
207
209
|
If you want to remove session related middleware, do the following:
|
@@ -224,112 +226,100 @@ config.middleware.delete "Rack::MethodOverride"
|
|
224
226
|
|
225
227
|
Much of Action Controller's functionality is implemented as Middlewares. The following list explains the purpose of each of them:
|
226
228
|
|
227
|
-
|
229
|
+
**`Rack::Sendfile`**
|
230
|
+
|
231
|
+
* Sets server specific X-Sendfile header. Configure this via `config.action_dispatch.x_sendfile_header` option.
|
232
|
+
|
233
|
+
**`ActionDispatch::Static`**
|
228
234
|
|
229
|
-
* Used to serve static
|
235
|
+
* Used to serve static files. Disabled if `config.serve_static_files` is `false`.
|
230
236
|
|
231
|
-
|
237
|
+
**`Rack::Lock`**
|
232
238
|
|
233
239
|
* Sets `env["rack.multithread"]` flag to `false` and wraps the application within a Mutex.
|
234
240
|
|
235
|
-
|
241
|
+
**`ActiveSupport::Cache::Strategy::LocalCache::Middleware`**
|
236
242
|
|
237
243
|
* Used for memory caching. This cache is not thread safe.
|
238
244
|
|
239
|
-
|
245
|
+
**`Rack::Runtime`**
|
240
246
|
|
241
247
|
* Sets an X-Runtime header, containing the time (in seconds) taken to execute the request.
|
242
248
|
|
243
|
-
|
249
|
+
**`Rack::MethodOverride`**
|
244
250
|
|
245
251
|
* Allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PUT and DELETE HTTP method types.
|
246
252
|
|
247
|
-
|
253
|
+
**`ActionDispatch::RequestId`**
|
248
254
|
|
249
255
|
* Makes a unique `X-Request-Id` header available to the response and enables the `ActionDispatch::Request#uuid` method.
|
250
256
|
|
251
|
-
|
257
|
+
**`Rails::Rack::Logger`**
|
252
258
|
|
253
259
|
* Notifies the logs that the request has began. After request is complete, flushes all the logs.
|
254
260
|
|
255
|
-
|
261
|
+
**`ActionDispatch::ShowExceptions`**
|
256
262
|
|
257
263
|
* Rescues any exception returned by the application and calls an exceptions app that will wrap it in a format for the end user.
|
258
264
|
|
259
|
-
|
265
|
+
**`ActionDispatch::DebugExceptions`**
|
260
266
|
|
261
267
|
* Responsible for logging exceptions and showing a debugging page in case the request is local.
|
262
268
|
|
263
|
-
|
269
|
+
**`ActionDispatch::RemoteIp`**
|
264
270
|
|
265
271
|
* Checks for IP spoofing attacks.
|
266
272
|
|
267
|
-
|
273
|
+
**`ActionDispatch::Reloader`**
|
268
274
|
|
269
275
|
* Provides prepare and cleanup callbacks, intended to assist with code reloading during development.
|
270
276
|
|
271
|
-
|
277
|
+
**`ActionDispatch::Callbacks`**
|
272
278
|
|
273
|
-
*
|
279
|
+
* Provides callbacks to be executed before and after dispatching the request.
|
274
280
|
|
275
|
-
|
281
|
+
**`ActiveRecord::Migration::CheckPending`**
|
282
|
+
|
283
|
+
* Checks pending migrations and raises `ActiveRecord::PendingMigrationError` if any migrations are pending.
|
284
|
+
|
285
|
+
**`ActiveRecord::ConnectionAdapters::ConnectionManagement`**
|
276
286
|
|
277
287
|
* Cleans active connections after each request, unless the `rack.test` key in the request environment is set to `true`.
|
278
288
|
|
279
|
-
|
289
|
+
**`ActiveRecord::QueryCache`**
|
280
290
|
|
281
291
|
* Enables the Active Record query cache.
|
282
292
|
|
283
|
-
|
293
|
+
**`ActionDispatch::Cookies`**
|
284
294
|
|
285
295
|
* Sets cookies for the request.
|
286
296
|
|
287
|
-
|
297
|
+
**`ActionDispatch::Session::CookieStore`**
|
288
298
|
|
289
299
|
* Responsible for storing the session in cookies.
|
290
300
|
|
291
|
-
|
301
|
+
**`ActionDispatch::Flash`**
|
292
302
|
|
293
303
|
* Sets up the flash keys. Only available if `config.action_controller.session_store` is set to a value.
|
294
304
|
|
295
|
-
|
305
|
+
**`ActionDispatch::ParamsParser`**
|
296
306
|
|
297
307
|
* Parses out parameters from the request into `params`.
|
298
308
|
|
299
|
-
|
309
|
+
**`Rack::Head`**
|
300
310
|
|
301
311
|
* Converts HEAD requests to `GET` requests and serves them as so.
|
302
312
|
|
303
|
-
|
313
|
+
**`Rack::ConditionalGet`**
|
304
314
|
|
305
315
|
* Adds support for "Conditional `GET`" so that server responds with nothing if page wasn't changed.
|
306
316
|
|
307
|
-
|
317
|
+
**`Rack::ETag`**
|
308
318
|
|
309
319
|
* Adds ETag header on all String bodies. ETags are used to validate cache.
|
310
320
|
|
311
321
|
TIP: It's possible to use any of the above middlewares in your custom Rack stack.
|
312
322
|
|
313
|
-
### Using Rack Builder
|
314
|
-
|
315
|
-
The following shows how to replace use `Rack::Builder` instead of the Rails supplied `MiddlewareStack`.
|
316
|
-
|
317
|
-
<strong>Clear the existing Rails middleware stack</strong>
|
318
|
-
|
319
|
-
```ruby
|
320
|
-
# config/application.rb
|
321
|
-
config.middleware.clear
|
322
|
-
```
|
323
|
-
|
324
|
-
<br />
|
325
|
-
<strong>Add a `config.ru` file to `Rails.root`</strong>
|
326
|
-
|
327
|
-
```ruby
|
328
|
-
# config.ru
|
329
|
-
use MyOwnStackFromScratch
|
330
|
-
run Rails.application
|
331
|
-
```
|
332
|
-
|
333
323
|
Resources
|
334
324
|
---------
|
335
325
|
|
data/guides/source/routing.md
CHANGED
@@ -36,7 +36,7 @@ the request is dispatched to the `patients` controller's `show` action with `{ i
|
|
36
36
|
|
37
37
|
### Generating Paths and URLs from Code
|
38
38
|
|
39
|
-
You can also generate paths and URLs.
|
39
|
+
You can also generate paths and URLs. If the route above is modified to be:
|
40
40
|
|
41
41
|
```ruby
|
42
42
|
get '/patients/:id', to: 'patients#show', as: 'patient'
|
@@ -89,15 +89,15 @@ resources :photos
|
|
89
89
|
|
90
90
|
creates seven different routes in your application, all mapping to the `Photos` controller:
|
91
91
|
|
92
|
-
| HTTP Verb | Path | Action
|
93
|
-
| --------- | ---------------- |
|
94
|
-
| GET | /photos | index
|
95
|
-
| GET | /photos/new | new
|
96
|
-
| POST | /photos | create
|
97
|
-
| GET | /photos/:id | show
|
98
|
-
| GET | /photos/:id/edit | edit
|
99
|
-
| PATCH/PUT | /photos/:id | update
|
100
|
-
| DELETE | /photos/:id | destroy
|
92
|
+
| HTTP Verb | Path | Controller#Action | Used for |
|
93
|
+
| --------- | ---------------- | ----------------- | -------------------------------------------- |
|
94
|
+
| GET | /photos | photos#index | display a list of all photos |
|
95
|
+
| GET | /photos/new | photos#new | return an HTML form for creating a new photo |
|
96
|
+
| POST | /photos | photos#create | create a new photo |
|
97
|
+
| GET | /photos/:id | photos#show | display a specific photo |
|
98
|
+
| GET | /photos/:id/edit | photos#edit | return an HTML form for editing a photo |
|
99
|
+
| PATCH/PUT | /photos/:id | photos#update | update a specific photo |
|
100
|
+
| DELETE | /photos/:id | photos#destroy | delete a specific photo |
|
101
101
|
|
102
102
|
NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
|
103
103
|
|
@@ -138,7 +138,7 @@ Sometimes, you have a resource that clients always look up without referencing a
|
|
138
138
|
get 'profile', to: 'users#show'
|
139
139
|
```
|
140
140
|
|
141
|
-
Passing a `String` to `
|
141
|
+
Passing a `String` to `get` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action:
|
142
142
|
|
143
143
|
```ruby
|
144
144
|
get 'profile', to: :show
|
@@ -152,14 +152,14 @@ resource :geocoder
|
|
152
152
|
|
153
153
|
creates six different routes in your application, all mapping to the `Geocoders` controller:
|
154
154
|
|
155
|
-
| HTTP Verb | Path | Action
|
156
|
-
| --------- | -------------- |
|
157
|
-
| GET | /geocoder/new | new | return an HTML form for creating the geocoder |
|
158
|
-
| POST | /geocoder | create | create the new geocoder |
|
159
|
-
| GET | /geocoder | show | display the one and only geocoder resource |
|
160
|
-
| GET | /geocoder/edit | edit | return an HTML form for editing the geocoder |
|
161
|
-
| PATCH/PUT | /geocoder | update | update the one and only geocoder resource |
|
162
|
-
| DELETE | /geocoder | destroy | delete the geocoder resource |
|
155
|
+
| HTTP Verb | Path | Controller#Action | Used for |
|
156
|
+
| --------- | -------------- | ----------------- | --------------------------------------------- |
|
157
|
+
| GET | /geocoder/new | geocoders#new | return an HTML form for creating the geocoder |
|
158
|
+
| POST | /geocoder | geocoders#create | create the new geocoder |
|
159
|
+
| GET | /geocoder | geocoders#show | display the one and only geocoder resource |
|
160
|
+
| GET | /geocoder/edit | geocoders#edit | return an HTML form for editing the geocoder |
|
161
|
+
| PATCH/PUT | /geocoder | geocoders#update | update the one and only geocoder resource |
|
162
|
+
| DELETE | /geocoder | geocoders#destroy | delete the geocoder resource |
|
163
163
|
|
164
164
|
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. So that, for example, `resource :photo` and `resources :photos` creates both singular and plural routes that map to the same controller (`PhotosController`).
|
165
165
|
|
@@ -171,67 +171,75 @@ A singular resourceful route generates these helpers:
|
|
171
171
|
|
172
172
|
As with plural resources, the same helpers ending in `_url` will also include the host, port and path prefix.
|
173
173
|
|
174
|
+
WARNING: A [long-standing bug](https://github.com/rails/rails/issues/1769) prevents `form_for` from working automatically with singular resources. As a workaround, specify the URL for the form directly, like so:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
form_for @geocoder, url: geocoder_path do |f|
|
178
|
+
```
|
179
|
+
|
174
180
|
### Controller Namespaces and Routing
|
175
181
|
|
176
182
|
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:
|
177
183
|
|
178
184
|
```ruby
|
179
185
|
namespace :admin do
|
180
|
-
resources :
|
186
|
+
resources :articles, :comments
|
181
187
|
end
|
182
188
|
```
|
183
189
|
|
184
|
-
This will create a number of routes for each of the `
|
190
|
+
This will create a number of routes for each of the `articles` and `comments` controller. For `Admin::ArticlesController`, Rails will create:
|
185
191
|
|
186
|
-
| HTTP Verb | Path
|
187
|
-
| --------- |
|
188
|
-
| GET | /admin/
|
189
|
-
| GET | /admin/
|
190
|
-
| POST | /admin/
|
191
|
-
| GET | /admin/
|
192
|
-
| GET | /admin/
|
193
|
-
| PATCH/PUT | /admin/
|
194
|
-
| DELETE | /admin/
|
192
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
193
|
+
| --------- | ------------------------ | ---------------------- | ---------------------------- |
|
194
|
+
| GET | /admin/articles | admin/articles#index | admin_articles_path |
|
195
|
+
| GET | /admin/articles/new | admin/articles#new | new_admin_article_path |
|
196
|
+
| POST | /admin/articles | admin/articles#create | admin_articles_path |
|
197
|
+
| GET | /admin/articles/:id | admin/articles#show | admin_article_path(:id) |
|
198
|
+
| GET | /admin/articles/:id/edit | admin/articles#edit | edit_admin_article_path(:id) |
|
199
|
+
| PATCH/PUT | /admin/articles/:id | admin/articles#update | admin_article_path(:id) |
|
200
|
+
| DELETE | /admin/articles/:id | admin/articles#destroy | admin_article_path(:id) |
|
195
201
|
|
196
|
-
If you want to route `/
|
202
|
+
If you want to route `/articles` (without the prefix `/admin`) to `Admin::ArticlesController`, you could use:
|
197
203
|
|
198
204
|
```ruby
|
199
205
|
scope module: 'admin' do
|
200
|
-
resources :
|
206
|
+
resources :articles, :comments
|
201
207
|
end
|
202
208
|
```
|
203
209
|
|
204
210
|
or, for a single case:
|
205
211
|
|
206
212
|
```ruby
|
207
|
-
resources :
|
213
|
+
resources :articles, module: 'admin'
|
208
214
|
```
|
209
215
|
|
210
|
-
If you want to route `/admin/
|
216
|
+
If you want to route `/admin/articles` to `ArticlesController` (without the `Admin::` module prefix), you could use:
|
211
217
|
|
212
218
|
```ruby
|
213
219
|
scope '/admin' do
|
214
|
-
resources :
|
220
|
+
resources :articles, :comments
|
215
221
|
end
|
216
222
|
```
|
217
223
|
|
218
224
|
or, for a single case:
|
219
225
|
|
220
226
|
```ruby
|
221
|
-
resources :
|
227
|
+
resources :articles, path: '/admin/articles'
|
222
228
|
```
|
223
229
|
|
224
|
-
In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `
|
230
|
+
In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `ArticlesController`:
|
225
231
|
|
226
|
-
| HTTP Verb | Path
|
227
|
-
| --------- |
|
228
|
-
| GET | /admin/
|
229
|
-
| GET | /admin/
|
230
|
-
| POST | /admin/
|
231
|
-
| GET | /admin/
|
232
|
-
| GET | /admin/
|
233
|
-
| PATCH/PUT | /admin/
|
234
|
-
| DELETE | /admin/
|
232
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
233
|
+
| --------- | ------------------------ | -------------------- | ---------------------- |
|
234
|
+
| GET | /admin/articles | articles#index | articles_path |
|
235
|
+
| GET | /admin/articles/new | articles#new | new_article_path |
|
236
|
+
| POST | /admin/articles | articles#create | articles_path |
|
237
|
+
| GET | /admin/articles/:id | articles#show | article_path(:id) |
|
238
|
+
| GET | /admin/articles/:id/edit | articles#edit | edit_article_path(:id) |
|
239
|
+
| PATCH/PUT | /admin/articles/:id | articles#update | article_path(:id) |
|
240
|
+
| DELETE | /admin/articles/:id | articles#destroy | article_path(:id) |
|
241
|
+
|
242
|
+
TIP: _If you need to use a different controller namespace inside a `namespace` block you can specify an absolute controller path, e.g: `get '/foo' => '/foo#index'`._
|
235
243
|
|
236
244
|
### Nested Resources
|
237
245
|
|
@@ -257,15 +265,15 @@ end
|
|
257
265
|
|
258
266
|
In addition to the routes for magazines, this declaration will also route ads to an `AdsController`. The ad URLs require a magazine:
|
259
267
|
|
260
|
-
| HTTP Verb | Path | Action
|
261
|
-
| --------- | ------------------------------------ |
|
262
|
-
| GET | /magazines/:magazine_id/ads | index
|
263
|
-
| GET | /magazines/:magazine_id/ads/new | new
|
264
|
-
| POST | /magazines/:magazine_id/ads | create
|
265
|
-
| GET | /magazines/:magazine_id/ads/:id | show
|
266
|
-
| GET | /magazines/:magazine_id/ads/:id/edit | edit
|
267
|
-
| PATCH/PUT | /magazines/:magazine_id/ads/:id | update
|
268
|
-
| DELETE | /magazines/:magazine_id/ads/:id | destroy
|
268
|
+
| HTTP Verb | Path | Controller#Action | Used for |
|
269
|
+
| --------- | ------------------------------------ | ----------------- | -------------------------------------------------------------------------- |
|
270
|
+
| GET | /magazines/:magazine_id/ads | ads#index | display a list of all ads for a specific magazine |
|
271
|
+
| GET | /magazines/:magazine_id/ads/new | ads#new | return an HTML form for creating a new ad belonging to a specific magazine |
|
272
|
+
| POST | /magazines/:magazine_id/ads | ads#create | create a new ad belonging to a specific magazine |
|
273
|
+
| GET | /magazines/:magazine_id/ads/:id | ads#show | display a specific ad belonging to a specific magazine |
|
274
|
+
| GET | /magazines/:magazine_id/ads/:id/edit | ads#edit | return an HTML form for editing an ad belonging to a specific magazine |
|
275
|
+
| PATCH/PUT | /magazines/:magazine_id/ads/:id | ads#update | update a specific ad belonging to a specific magazine |
|
276
|
+
| DELETE | /magazines/:magazine_id/ads/:id | ads#destroy | delete a specific ad belonging to a specific magazine |
|
269
277
|
|
270
278
|
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)`).
|
271
279
|
|
@@ -296,7 +304,7 @@ TIP: _Resources should never be nested more than 1 level deep._
|
|
296
304
|
One way to avoid deep nesting (as recommended above) is to generate the collection actions scoped under the parent, so as to get a sense of the hierarchy, but to not nest the member actions. In other words, to only build routes with the minimal amount of information to uniquely identify the resource, like this:
|
297
305
|
|
298
306
|
```ruby
|
299
|
-
resources :
|
307
|
+
resources :articles do
|
300
308
|
resources :comments, only: [:index, :new, :create]
|
301
309
|
end
|
302
310
|
resources :comments, only: [:show, :edit, :update, :destroy]
|
@@ -305,7 +313,7 @@ resources :comments, only: [:show, :edit, :update, :destroy]
|
|
305
313
|
This idea strikes a balance between descriptive routes and deep nesting. There exists shorthand syntax to achieve just that, via the `:shallow` option:
|
306
314
|
|
307
315
|
```ruby
|
308
|
-
resources :
|
316
|
+
resources :articles do
|
309
317
|
resources :comments, shallow: true
|
310
318
|
end
|
311
319
|
```
|
@@ -313,7 +321,7 @@ end
|
|
313
321
|
This will generate the exact same routes as the first example. You can also specify the `:shallow` option in the parent resource, in which case all of the nested resources will be shallow:
|
314
322
|
|
315
323
|
```ruby
|
316
|
-
resources :
|
324
|
+
resources :articles, shallow: true do
|
317
325
|
resources :comments
|
318
326
|
resources :quotes
|
319
327
|
resources :drafts
|
@@ -324,7 +332,7 @@ The `shallow` method of the DSL creates a scope inside of which every nesting is
|
|
324
332
|
|
325
333
|
```ruby
|
326
334
|
shallow do
|
327
|
-
resources :
|
335
|
+
resources :articles do
|
328
336
|
resources :comments
|
329
337
|
resources :quotes
|
330
338
|
resources :drafts
|
@@ -332,11 +340,11 @@ shallow do
|
|
332
340
|
end
|
333
341
|
```
|
334
342
|
|
335
|
-
There
|
343
|
+
There exist two options for `scope` to customize shallow routes. `:shallow_path` prefixes member paths with the specified parameter:
|
336
344
|
|
337
345
|
```ruby
|
338
346
|
scope shallow_path: "sekret" do
|
339
|
-
resources :
|
347
|
+
resources :articles do
|
340
348
|
resources :comments, shallow: true
|
341
349
|
end
|
342
350
|
end
|
@@ -344,21 +352,21 @@ end
|
|
344
352
|
|
345
353
|
The comments resource here will have the following routes generated for it:
|
346
354
|
|
347
|
-
| HTTP Verb | Path
|
348
|
-
| --------- |
|
349
|
-
| GET | /
|
350
|
-
| POST | /
|
351
|
-
| GET | /
|
352
|
-
| GET | /sekret/comments/:id/edit(.:format)
|
353
|
-
| GET | /sekret/comments/:id(.:format)
|
354
|
-
| PATCH/PUT | /sekret/comments/:id(.:format)
|
355
|
-
| DELETE | /sekret/comments/:id(.:format)
|
355
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
356
|
+
| --------- | -------------------------------------------- | ----------------- | ------------------------ |
|
357
|
+
| GET | /articles/:article_id/comments(.:format) | comments#index | article_comments_path |
|
358
|
+
| POST | /articles/:article_id/comments(.:format) | comments#create | article_comments_path |
|
359
|
+
| GET | /articles/:article_id/comments/new(.:format) | comments#new | new_article_comment_path |
|
360
|
+
| GET | /sekret/comments/:id/edit(.:format) | comments#edit | edit_comment_path |
|
361
|
+
| GET | /sekret/comments/:id(.:format) | comments#show | comment_path |
|
362
|
+
| PATCH/PUT | /sekret/comments/:id(.:format) | comments#update | comment_path |
|
363
|
+
| DELETE | /sekret/comments/:id(.:format) | comments#destroy | comment_path |
|
356
364
|
|
357
365
|
The `:shallow_prefix` option adds the specified parameter to the named helpers:
|
358
366
|
|
359
367
|
```ruby
|
360
368
|
scope shallow_prefix: "sekret" do
|
361
|
-
resources :
|
369
|
+
resources :articles do
|
362
370
|
resources :comments, shallow: true
|
363
371
|
end
|
364
372
|
end
|
@@ -366,19 +374,19 @@ end
|
|
366
374
|
|
367
375
|
The comments resource here will have the following routes generated for it:
|
368
376
|
|
369
|
-
| HTTP Verb | Path
|
370
|
-
| --------- |
|
371
|
-
| GET | /
|
372
|
-
| POST | /
|
373
|
-
| GET | /
|
374
|
-
| GET | /comments/:id/edit(.:format)
|
375
|
-
| GET | /comments/:id(.:format)
|
376
|
-
| PATCH/PUT | /comments/:id(.:format)
|
377
|
-
| DELETE | /comments/:id(.:format)
|
377
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
378
|
+
| --------- | -------------------------------------------- | ----------------- | --------------------------- |
|
379
|
+
| GET | /articles/:article_id/comments(.:format) | comments#index | article_comments_path |
|
380
|
+
| POST | /articles/:article_id/comments(.:format) | comments#create | article_comments_path |
|
381
|
+
| GET | /articles/:article_id/comments/new(.:format) | comments#new | new_article_comment_path |
|
382
|
+
| GET | /comments/:id/edit(.:format) | comments#edit | edit_sekret_comment_path |
|
383
|
+
| GET | /comments/:id(.:format) | comments#show | sekret_comment_path |
|
384
|
+
| PATCH/PUT | /comments/:id(.:format) | comments#update | sekret_comment_path |
|
385
|
+
| DELETE | /comments/:id(.:format) | comments#destroy | sekret_comment_path |
|
378
386
|
|
379
387
|
### Routing concerns
|
380
388
|
|
381
|
-
Routing Concerns allows you to declare common routes that can be reused inside
|
389
|
+
Routing Concerns allows you to declare common routes that can be reused inside other resources and routes. To define a concern:
|
382
390
|
|
383
391
|
```ruby
|
384
392
|
concern :commentable do
|
@@ -395,7 +403,7 @@ These concerns can be used in resources to avoid code duplication and share beha
|
|
395
403
|
```ruby
|
396
404
|
resources :messages, concerns: :commentable
|
397
405
|
|
398
|
-
resources :
|
406
|
+
resources :articles, concerns: [:commentable, :image_attachable]
|
399
407
|
```
|
400
408
|
|
401
409
|
The above is equivalent to:
|
@@ -405,7 +413,7 @@ resources :messages do
|
|
405
413
|
resources :comments
|
406
414
|
end
|
407
415
|
|
408
|
-
resources :
|
416
|
+
resources :articles do
|
409
417
|
resources :comments
|
410
418
|
resources :images, only: :index
|
411
419
|
end
|
@@ -414,7 +422,7 @@ end
|
|
414
422
|
Also you can use them in any place that you want inside the routes, for example in a scope or namespace call:
|
415
423
|
|
416
424
|
```ruby
|
417
|
-
namespace :
|
425
|
+
namespace :articles do
|
418
426
|
concerns :commentable
|
419
427
|
end
|
420
428
|
```
|
@@ -479,7 +487,10 @@ end
|
|
479
487
|
|
480
488
|
This will recognize `/photos/1/preview` with GET, and route to the `preview` action of `PhotosController`, with the resource id value passed in `params[:id]`. It will also create the `preview_photo_url` and `preview_photo_path` helpers.
|
481
489
|
|
482
|
-
Within the block of member routes, each route name specifies the HTTP verb
|
490
|
+
Within the block of member routes, each route name specifies the HTTP verb
|
491
|
+
will be recognized. You can use `get`, `patch`, `put`, `post`, or `delete` here
|
492
|
+
. If you don't have multiple `member` routes, you can also pass `:on` to a
|
493
|
+
route, eliminating the block:
|
483
494
|
|
484
495
|
```ruby
|
485
496
|
resources :photos do
|
@@ -600,6 +611,8 @@ get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
|
|
600
611
|
|
601
612
|
Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`.
|
602
613
|
|
614
|
+
NOTE: You cannot override defaults via query parameters - this is for security reasons. The only defaults that can be overridden are dynamic segments via substitution in the URL path.
|
615
|
+
|
603
616
|
### Naming Routes
|
604
617
|
|
605
618
|
You can specify a name for any route using the `:as` option:
|
@@ -620,7 +633,7 @@ This will define a `user_path` method that will be available in controllers, hel
|
|
620
633
|
|
621
634
|
### HTTP Verb Constraints
|
622
635
|
|
623
|
-
In general, you should use the `get`, `post`, `put`
|
636
|
+
In general, you should use the `get`, `post`, `put`, `patch` and `delete` methods to constrain a route to a particular verb. You can use the `match` method with the `:via` option to match multiple verbs at once:
|
624
637
|
|
625
638
|
```ruby
|
626
639
|
match 'photos', to: 'photos#show', via: [:get, :post]
|
@@ -634,6 +647,8 @@ match 'photos', to: 'photos#show', via: :all
|
|
634
647
|
|
635
648
|
NOTE: Routing both `GET` and `POST` requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to.
|
636
649
|
|
650
|
+
NOTE: 'GET' in Rails won't check for CSRF token. You should never write to the database from 'GET' requests, for more information see the [security guide](security.html#csrf-countermeasures) on CSRF countermeasures.
|
651
|
+
|
637
652
|
### Segment Constraints
|
638
653
|
|
639
654
|
You can use the `:constraints` option to enforce a format for a dynamic segment:
|
@@ -651,26 +666,26 @@ get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
|
|
651
666
|
`:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work:
|
652
667
|
|
653
668
|
```ruby
|
654
|
-
get '/:id', to: '
|
669
|
+
get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
|
655
670
|
```
|
656
671
|
|
657
672
|
However, note that you don't need to use anchors because all routes are anchored at the start.
|
658
673
|
|
659
|
-
For example, the following routes would allow for `
|
674
|
+
For example, the following routes would allow for `articles` with `to_param` values like `1-hello-world` that always begin with a number and `users` with `to_param` values like `david` that never begin with a number to share the root namespace:
|
660
675
|
|
661
676
|
```ruby
|
662
|
-
get '/:id', to: '
|
677
|
+
get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
|
663
678
|
get '/:username', to: 'users#show'
|
664
679
|
```
|
665
680
|
|
666
681
|
### Request-Based Constraints
|
667
682
|
|
668
|
-
You can also constrain a route based on any method on the
|
683
|
+
You can also constrain a route based on any method on the [Request object](action_controller_overview.html#the-request-object) that returns a `String`.
|
669
684
|
|
670
685
|
You specify a request-based constraint the same way that you specify a segment constraint:
|
671
686
|
|
672
687
|
```ruby
|
673
|
-
get 'photos', constraints: {subdomain: 'admin'}
|
688
|
+
get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }
|
674
689
|
```
|
675
690
|
|
676
691
|
You can also specify constraints in a block form:
|
@@ -683,6 +698,8 @@ namespace :admin do
|
|
683
698
|
end
|
684
699
|
```
|
685
700
|
|
701
|
+
NOTE: Request constraints work by calling a method on the [Request object](action_controller_overview.html#the-request-object) with the same name as the hash key and then compare the return value with the hash value. Therefore, constraint values should match the corresponding Request object method return type. For example: `constraints: { subdomain: 'api' }` will match an `api` subdomain as expected, however using a symbol `constraints: { subdomain: :api }` will not, because `request.subdomain` returns `'api'` as a String.
|
702
|
+
|
686
703
|
### Advanced Constraints
|
687
704
|
|
688
705
|
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:
|
@@ -698,7 +715,7 @@ class BlacklistConstraint
|
|
698
715
|
end
|
699
716
|
end
|
700
717
|
|
701
|
-
|
718
|
+
Rails.application.routes.draw do
|
702
719
|
get '*path', to: 'blacklist#index',
|
703
720
|
constraints: BlacklistConstraint.new
|
704
721
|
end
|
@@ -707,7 +724,7 @@ end
|
|
707
724
|
You can also specify constraints as a lambda:
|
708
725
|
|
709
726
|
```ruby
|
710
|
-
|
727
|
+
Rails.application.routes.draw do
|
711
728
|
get '*path', to: 'blacklist#index',
|
712
729
|
constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
|
713
730
|
end
|
@@ -741,7 +758,7 @@ get '*a/foo/*b', to: 'test#index'
|
|
741
758
|
|
742
759
|
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `'zoo/woo'`, and `params[:b]` equals `'bar/baz'`.
|
743
760
|
|
744
|
-
NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be
|
761
|
+
NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be equal to `'foo/bar'` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
|
745
762
|
|
746
763
|
```ruby
|
747
764
|
get '*pages', to: 'pages#show', format: false
|
@@ -758,20 +775,20 @@ get '*pages', to: 'pages#show', format: true
|
|
758
775
|
You can redirect any path to another path using the `redirect` helper in your router:
|
759
776
|
|
760
777
|
```ruby
|
761
|
-
get '/stories', to: redirect('/
|
778
|
+
get '/stories', to: redirect('/articles')
|
762
779
|
```
|
763
780
|
|
764
781
|
You can also reuse dynamic segments from the match in the path to redirect to:
|
765
782
|
|
766
783
|
```ruby
|
767
|
-
get '/stories/:name', to: redirect('/
|
784
|
+
get '/stories/:name', to: redirect('/articles/%{name}')
|
768
785
|
```
|
769
786
|
|
770
|
-
You can also provide a block to redirect, which receives the
|
787
|
+
You can also provide a block to redirect, which receives the symbolized path parameters and the request object:
|
771
788
|
|
772
789
|
```ruby
|
773
|
-
get '/stories/:name', to: redirect {|
|
774
|
-
get '/stories', to: redirect {|
|
790
|
+
get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
|
791
|
+
get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }
|
775
792
|
```
|
776
793
|
|
777
794
|
Please note that this redirection is a 301 "Moved Permanently" redirect. Keep in mind that some web browsers or proxy servers will cache this type of redirect, making the old page inaccessible.
|
@@ -780,7 +797,7 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl
|
|
780
797
|
|
781
798
|
### Routing to Rack Applications
|
782
799
|
|
783
|
-
Instead of a String like `'
|
800
|
+
Instead of a String like `'articles#index'`, which corresponds to the `index` action in the `ArticlesController`, you can specify any [Rack application](rails_on_rack.html) as the endpoint for a matcher:
|
784
801
|
|
785
802
|
```ruby
|
786
803
|
match '/application.js', to: Sprockets, via: :all
|
@@ -788,7 +805,19 @@ match '/application.js', to: Sprockets, via: :all
|
|
788
805
|
|
789
806
|
As long as `Sprockets` responds to `call` and returns a `[status, headers, body]`, the router won't know the difference between the Rack application and an action. This is an appropriate use of `via: :all`, as you will want to allow your Rack application to handle all verbs as it considers appropriate.
|
790
807
|
|
791
|
-
NOTE: For the curious, `'
|
808
|
+
NOTE: For the curious, `'articles#index'` actually expands out to `ArticlesController.action(:index)`, which returns a valid Rack application.
|
809
|
+
|
810
|
+
If you specify a rack application as the endpoint for a matcher remember that the route will be unchanged in the receiving application. With the following route your rack application should expect the route to be '/admin':
|
811
|
+
|
812
|
+
```ruby
|
813
|
+
match '/admin', to: AdminApp, via: :all
|
814
|
+
```
|
815
|
+
|
816
|
+
If you would prefer to have your rack application receive requests at the root path instead use mount:
|
817
|
+
|
818
|
+
```ruby
|
819
|
+
mount AdminApp, at: '/admin'
|
820
|
+
```
|
792
821
|
|
793
822
|
### Using `root`
|
794
823
|
|
@@ -803,7 +832,7 @@ You should put the `root` route at the top of the file, because it is the most p
|
|
803
832
|
|
804
833
|
NOTE: The `root` route only routes `GET` requests to the action.
|
805
834
|
|
806
|
-
You can also use root inside namespaces and scopes as well.
|
835
|
+
You can also use root inside namespaces and scopes as well. For example:
|
807
836
|
|
808
837
|
```ruby
|
809
838
|
namespace :admin do
|
@@ -824,7 +853,7 @@ get 'こんにちは', to: 'welcome#index'
|
|
824
853
|
Customizing Resourceful Routes
|
825
854
|
------------------------------
|
826
855
|
|
827
|
-
While the default routes and helpers generated by `resources :
|
856
|
+
While the default routes and helpers generated by `resources :articles` 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.
|
828
857
|
|
829
858
|
### Specifying a Controller to Use
|
830
859
|
|
@@ -836,15 +865,15 @@ resources :photos, controller: 'images'
|
|
836
865
|
|
837
866
|
will recognize incoming paths beginning with `/photos` but route to the `Images` controller:
|
838
867
|
|
839
|
-
| HTTP Verb | Path | Action
|
840
|
-
| --------- | ---------------- |
|
841
|
-
| GET | /photos | index
|
842
|
-
| GET | /photos/new | new
|
843
|
-
| POST | /photos | create
|
844
|
-
| GET | /photos/:id | show
|
845
|
-
| GET | /photos/:id/edit | edit
|
846
|
-
| PATCH/PUT | /photos/:id | update
|
847
|
-
| DELETE | /photos/:id | destroy
|
868
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
869
|
+
| --------- | ---------------- | ----------------- | -------------------- |
|
870
|
+
| GET | /photos | images#index | photos_path |
|
871
|
+
| GET | /photos/new | images#new | new_photo_path |
|
872
|
+
| POST | /photos | images#create | photos_path |
|
873
|
+
| GET | /photos/:id | images#show | photo_path(:id) |
|
874
|
+
| GET | /photos/:id/edit | images#edit | edit_photo_path(:id) |
|
875
|
+
| PATCH/PUT | /photos/:id | images#update | photo_path(:id) |
|
876
|
+
| DELETE | /photos/:id | images#destroy | photo_path(:id) |
|
848
877
|
|
849
878
|
NOTE: Use `photos_path`, `new_photo_path`, etc. to generate paths for this resource.
|
850
879
|
|
@@ -857,8 +886,8 @@ resources :user_permissions, controller: 'admin/user_permissions'
|
|
857
886
|
This will route to the `Admin::UserPermissions` controller.
|
858
887
|
|
859
888
|
NOTE: Only the directory notation is supported. Specifying the
|
860
|
-
controller with
|
861
|
-
|
889
|
+
controller with Ruby constant notation (eg. `controller: 'Admin::UserPermissions'`)
|
890
|
+
can lead to routing problems and results in
|
862
891
|
a warning.
|
863
892
|
|
864
893
|
### Specifying Constraints
|
@@ -866,7 +895,7 @@ a warning.
|
|
866
895
|
You can use the `:constraints` option to specify a required format on the implicit `id`. For example:
|
867
896
|
|
868
897
|
```ruby
|
869
|
-
resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/}
|
898
|
+
resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }
|
870
899
|
```
|
871
900
|
|
872
901
|
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.
|
@@ -894,19 +923,19 @@ resources :photos, as: 'images'
|
|
894
923
|
|
895
924
|
will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the :as option to name the helpers.
|
896
925
|
|
897
|
-
| HTTP Verb | Path | Action
|
898
|
-
| --------- | ---------------- |
|
899
|
-
| GET | /photos | index
|
900
|
-
| GET | /photos/new | new
|
901
|
-
| POST | /photos | create
|
902
|
-
| GET | /photos/:id | show
|
903
|
-
| GET | /photos/:id/edit | edit
|
904
|
-
| PATCH/PUT | /photos/:id | update
|
905
|
-
| DELETE | /photos/:id | destroy
|
926
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
927
|
+
| --------- | ---------------- | ----------------- | -------------------- |
|
928
|
+
| GET | /photos | photos#index | images_path |
|
929
|
+
| GET | /photos/new | photos#new | new_image_path |
|
930
|
+
| POST | /photos | photos#create | images_path |
|
931
|
+
| GET | /photos/:id | photos#show | image_path(:id) |
|
932
|
+
| GET | /photos/:id/edit | photos#edit | edit_image_path(:id) |
|
933
|
+
| PATCH/PUT | /photos/:id | photos#update | image_path(:id) |
|
934
|
+
| DELETE | /photos/:id | photos#destroy | image_path(:id) |
|
906
935
|
|
907
936
|
### Overriding the `new` and `edit` Segments
|
908
937
|
|
909
|
-
The `:path_names` option lets you override the automatically-generated
|
938
|
+
The `:path_names` option lets you override the automatically-generated `new` and `edit` segments in paths:
|
910
939
|
|
911
940
|
```ruby
|
912
941
|
resources :photos, path_names: { new: 'make', edit: 'change' }
|
@@ -941,7 +970,7 @@ end
|
|
941
970
|
resources :photos
|
942
971
|
```
|
943
972
|
|
944
|
-
This will provide route helpers such as `admin_photos_path`, `new_admin_photo_path
|
973
|
+
This will provide route helpers such as `admin_photos_path`, `new_admin_photo_path`, etc.
|
945
974
|
|
946
975
|
To prefix a group of route helpers, use `:as` with `scope`:
|
947
976
|
|
@@ -961,15 +990,15 @@ You can prefix routes with a named parameter also:
|
|
961
990
|
|
962
991
|
```ruby
|
963
992
|
scope ':username' do
|
964
|
-
resources :
|
993
|
+
resources :articles
|
965
994
|
end
|
966
995
|
```
|
967
996
|
|
968
|
-
This will provide you with URLs such as `/bob/
|
997
|
+
This will provide you with URLs such as `/bob/articles/1` and will allow you to reference the `username` part of the path as `params[:username]` in controllers, helpers and views.
|
969
998
|
|
970
999
|
### Restricting the Routes Created
|
971
1000
|
|
972
|
-
By default, Rails creates routes for the seven default actions (index
|
1001
|
+
By default, Rails creates routes for the seven 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:
|
973
1002
|
|
974
1003
|
```ruby
|
975
1004
|
resources :photos, only: [:index, :show]
|
@@ -999,15 +1028,15 @@ end
|
|
999
1028
|
|
1000
1029
|
Rails now creates routes to the `CategoriesController`.
|
1001
1030
|
|
1002
|
-
| HTTP Verb | Path | Action |
|
1003
|
-
| --------- | -------------------------- |
|
1004
|
-
| GET | /kategorien | index | categories_path |
|
1005
|
-
| GET | /kategorien/neu | new | new_category_path |
|
1006
|
-
| POST | /kategorien | create | categories_path |
|
1007
|
-
| GET | /kategorien/:id | show | category_path(:id) |
|
1008
|
-
| GET | /kategorien/:id/bearbeiten | edit | edit_category_path(:id) |
|
1009
|
-
| PATCH/PUT | /kategorien/:id | update | category_path(:id) |
|
1010
|
-
| DELETE | /kategorien/:id | destroy | category_path(:id) |
|
1031
|
+
| HTTP Verb | Path | Controller#Action | Named Helper |
|
1032
|
+
| --------- | -------------------------- | ------------------ | ----------------------- |
|
1033
|
+
| GET | /kategorien | categories#index | categories_path |
|
1034
|
+
| GET | /kategorien/neu | categories#new | new_category_path |
|
1035
|
+
| POST | /kategorien | categories#create | categories_path |
|
1036
|
+
| GET | /kategorien/:id | categories#show | category_path(:id) |
|
1037
|
+
| GET | /kategorien/:id/bearbeiten | categories#edit | edit_category_path(:id) |
|
1038
|
+
| PATCH/PUT | /kategorien/:id | categories#update | category_path(:id) |
|
1039
|
+
| DELETE | /kategorien/:id | categories#destroy | category_path(:id) |
|
1011
1040
|
|
1012
1041
|
### Overriding the Singular Form
|
1013
1042
|
|
@@ -1031,6 +1060,28 @@ end
|
|
1031
1060
|
|
1032
1061
|
This will create routing helpers such as `magazine_periodical_ads_url` and `edit_magazine_periodical_ad_path`.
|
1033
1062
|
|
1063
|
+
### Overriding Named Route Parameters
|
1064
|
+
|
1065
|
+
The `:param` option overrides the default resource identifier `:id` (name of
|
1066
|
+
the [dynamic segment](routing.html#dynamic-segments) used to generate the
|
1067
|
+
routes). You can access that segment from your controller using
|
1068
|
+
`params[<:param>]`.
|
1069
|
+
|
1070
|
+
```ruby
|
1071
|
+
resources :videos, param: :identifier
|
1072
|
+
```
|
1073
|
+
|
1074
|
+
```
|
1075
|
+
videos GET /videos(.:format) videos#index
|
1076
|
+
POST /videos(.:format) videos#create
|
1077
|
+
new_videos GET /videos/new(.:format) videos#new
|
1078
|
+
edit_videos GET /videos/:identifier/edit(.:format) videos#edit
|
1079
|
+
```
|
1080
|
+
|
1081
|
+
```ruby
|
1082
|
+
Video.find_by(identifier: params[:identifier])
|
1083
|
+
```
|
1084
|
+
|
1034
1085
|
Inspecting and Testing Routes
|
1035
1086
|
-----------------------------
|
1036
1087
|
|
@@ -1059,7 +1110,7 @@ edit_user GET /users/:id/edit(.:format) users#edit
|
|
1059
1110
|
You may restrict the listing to the routes that map to a particular controller setting the `CONTROLLER` environment variable:
|
1060
1111
|
|
1061
1112
|
```bash
|
1062
|
-
$ CONTROLLER=users rake routes
|
1113
|
+
$ CONTROLLER=users bin/rake routes
|
1063
1114
|
```
|
1064
1115
|
|
1065
1116
|
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.
|