routing.md 37.1 KB
Newer Older
1 2
Rails Routing from the Outside In
=================================
3 4 5

This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:

6
* Understand the code in `routes.rb`
7
* Construct your own routes, using either the preferred resourceful style or the `match` method
8
* Identify what parameters to expect an action to receive
9
* Automatically create paths and URLs using route helpers
10
* Use advanced techniques such as constraints and Rack endpoints
11

12
--------------------------------------------------------------------------------
13

14 15
The Purpose of the Rails Router
-------------------------------
16

17
The Rails router recognizes URLs and dispatches them to a controller's action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.
18

19
### Connecting URLs to Code
20

21
When your Rails application receives an incoming request
22

23
```
24
GET /patients/17
25
```
26

27
it asks the router to match it to a controller action. If the first matching route is
28

29
```ruby
30
get "/patients/:id" => "patients#show"
31
```
32

A
AvnerCohen 已提交
33
the request is dispatched to the `patients` controller's `show` action with `{ id: "17" }` in `params`.
34

35
### Generating Paths and URLs from Code
36

37 38
You can also generate paths and URLs.  If the route above is modified to be

39
```ruby
A
AvnerCohen 已提交
40
get "/patients/:id" => "patients#show", as: "patient"
41
```
42 43

If your application contains this code:
44

45
```ruby
46
@patient = Patient.find(17)
47
```
48

49
```erb
E
eparreno 已提交
50
<%= link_to "Patient Record", patient_path(@patient) %>
51
```
52

53
The router will generate the path `/patients/17`. This reduces the brittleness of your view and makes your code easier to understand. Note that the id does not need to be specified in the route helper.
54

55 56
Resource Routing: the Rails Default
-----------------------------------
57

58
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.
59

60
### Resources on the Web
61

62
Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as `GET`, `POST`, `PATCH`, `PUT` and `DELETE`. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.
63

64
When your Rails application receives an incoming request for
65

66
```
67
DELETE /photos/17
68
```
69

70
it asks the router to map it to a controller action. If the first matching route is
71

72
```ruby
73
resources :photos
74
```
75

A
AvnerCohen 已提交
76
Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: "17" }` in `params`.
77

78
### CRUD, Verbs, and Actions
79

80
In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as
81

82
```ruby
83
resources :photos
84
```
85

86
creates seven different routes in your application, all mapping to the `Photos` controller:
87

88 89 90 91 92 93 94 95 96
| HTTP Verb | Path             | action  | used for                                     |
| --------- | ---------------- | ------- | -------------------------------------------- |
| GET       | /photos          | index   | display a list of all photos                 |
| GET       | /photos/new      | new     | return an HTML form for creating a new photo |
| POST      | /photos          | create  | create a new photo                           |
| GET       | /photos/:id      | show    | display a specific photo                     |
| GET       | /photos/:id/edit | edit    | return an HTML form for editing a photo      |
| PATCH/PUT | /photos/:id      | update  | update a specific photo                      |
| DELETE    | /photos/:id      | destroy | delete a specific photo                      |
97

98
NOTE: Rails routes are matched in the order they are specified, so if you have a `resources :photos` above a `get 'photos/poll'` the `show` action's route for the `resources` line will be matched before the `get` line. To fix this, move the `get` line **above** the `resources` line so that it is matched first.
99

100
### Paths and URLs
101

102
Creating a resourceful route will also expose a number of helpers to the controllers in your application. In the case of `resources :photos`:
103

104 105 106 107
* `photos_path` returns `/photos`
* `new_photo_path` returns `/photos/new`
* `edit_photo_path(:id)` returns `/photos/:id/edit` (for instance, `edit_photo_path(10)` returns `/photos/10/edit`)
* `photo_path(:id)` returns `/photos/:id` (for instance, `photo_path(10)` returns `/photos/10`)
108

109
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.
110

111
NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
112

113
### Defining Multiple Resources at the Same Time
114

115
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`:
116

117
```ruby
118
resources :photos, :books, :videos
119
```
120

121
This works exactly the same as
122

123
```ruby
124 125 126
resources :photos
resources :books
resources :videos
127
```
128

129
### Singular Resources
130

131
Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like `/profile` to always show 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.
132

133
```ruby
134
get "profile" => "users#show"
135
```
136 137 138

This resourceful route

139
```ruby
140
resource :geocoder
141
```
142

143
creates six different routes in your application, all mapping to the `Geocoders` controller:
144

145 146 147 148 149 150 151 152
| HTTP Verb | Path           | action  | used for                                      |
| --------- | -------------- | ------- | --------------------------------------------- |
| GET       | /geocoder/new  | new     | return an HTML form for creating the geocoder |
| POST      | /geocoder      | create  | create the new geocoder                       |
| GET       | /geocoder      | show    | display the one and only geocoder resource    |
| GET       | /geocoder/edit | edit    | return an HTML form for editing the geocoder  |
| PATCH/PUT | /geocoder      | update  | update the one and only geocoder resource     |
| DELETE    | /geocoder      | destroy | delete the geocoder resource                  |
153

154
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.
155

156
A singular resourceful route generates these helpers:
157

158 159 160
* `new_geocoder_path` returns `/geocoder/new`
* `edit_geocoder_path` returns `/geocoder/edit`
* `geocoder_path` returns `/geocoder`
161

162
As with plural resources, the same helpers ending in `_url` will also include the host, port and path prefix.
163

164
### Controller Namespaces and Routing
165

166
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:
167

168
```ruby
169
namespace :admin do
170
  resources :posts, :comments
171
end
172
```
173

174
This will create a number of routes for each of the `posts` and `comments` controller. For `Admin::PostsController`, Rails will create:
175

176 177 178 179 180 181 182 183 184
| HTTP Verb | Path                  | action  | used for                  |
| --------- | --------------------- | ------- | ------------------------- |
| GET       | /admin/posts          | index   | admin_posts_path          |
| GET       | /admin/posts/new      | new     | new_admin_post_path       |
| POST      | /admin/posts          | create  | admin_posts_path          |
| GET       | /admin/posts/:id      | show    | admin_post_path(:id)      |
| GET       | /admin/posts/:id/edit | edit    | edit_admin_post_path(:id) |
| PATCH/PUT | /admin/posts/:id      | update  | admin_post_path(:id)      |
| DELETE    | /admin/posts/:id      | destroy | admin_post_path(:id)      |
185

186
If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use
187

188
```ruby
A
AvnerCohen 已提交
189
scope module: "admin" do
190 191
  resources :posts, :comments
end
192
```
193

194
or, for a single case
195

196
```ruby
A
AvnerCohen 已提交
197
resources :posts, module: "admin"
198
```
199

200
If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use
201

202
```ruby
203 204 205
scope "/admin" do
  resources :posts, :comments
end
206
```
207

208
or, for a single case
209

210
```ruby
A
AvnerCohen 已提交
211
resources :posts, path: "/admin/posts"
212
```
213

214
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 `PostsController`:
215

216 217 218 219 220 221 222 223 224
| HTTP Verb | Path                  | action  | named helper        |
| --------- | --------------------- | ------- | ------------------- |
| GET       | /admin/posts          | index   | posts_path          |
| GET       | /admin/posts/new      | new     | new_post_path       |
| POST      | /admin/posts          | create  | posts_path          |
| GET       | /admin/posts/:id      | show    | post_path(:id)      |
| GET       | /admin/posts/:id/edit | edit    | edit_post_path(:id) |
| PATCH/PUT | /admin/posts/:id      | update  | post_path(:id)      |
| DELETE    | /admin/posts/:id      | destroy | post_path(:id)      |
225

226
### Nested Resources
227 228 229

It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:

230
```ruby
231 232 233 234 235 236 237
class Magazine < ActiveRecord::Base
  has_many :ads
end

class Ad < ActiveRecord::Base
  belongs_to :magazine
end
238
```
239

240
Nested routes allow you to capture this relationship in your routing. In this case, you could include this route declaration:
241

242
```ruby
243 244
resources :magazines do
  resources :ads
245
end
246
```
247

248
In addition to the routes for magazines, this declaration will also route ads to an `AdsController`. The ad URLs require a magazine:
249

250 251 252 253 254 255 256 257 258
| HTTP Verb | Path                                 | action  | used for                                                                   |
| --------- | ------------------------------------ | ------- | -------------------------------------------------------------------------- |
| GET       | /magazines/:magazine_id/ads          | index   | display a list of all ads for a specific magazine                          |
| GET       | /magazines/:magazine_id/ads/new      | new     | return an HTML form for creating a new ad belonging to a specific magazine |
| POST      | /magazines/:magazine_id/ads          | create  | create a new ad belonging to a specific magazine                           |
| GET       | /magazines/:magazine_id/ads/:id      | show    | display a specific ad belonging to a specific magazine                     |
| GET       | /magazines/:magazine_id/ads/:id/edit | edit    | return an HTML form for editing an ad belonging to a specific magazine     |
| PATCH/PUT | /magazines/:magazine_id/ads/:id      | update  | update a specific ad belonging to a specific magazine                      |
| DELETE    | /magazines/:magazine_id/ads/:id      | destroy | delete a specific ad belonging to a specific magazine                      |
259

260
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)`).
261

262
#### Limits to Nesting
263 264 265

You can nest resources within other nested resources if you like. For example:

266
```ruby
267 268 269
resources :publishers do
  resources :magazines do
    resources :photos
270 271
  end
end
272
```
273

274
Deeply-nested resources quickly become cumbersome. In this case, for example, the application would recognize paths such as
275

276
```
277
/publishers/1/magazines/2/photos/3
278
```
279

280
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:
281

282
TIP: _Resources should never be nested more than 1 level deep._
283

284
### Routing concerns
285 286 287

Routing Concerns allows you to declare common routes that can be reused inside others resources and routes.

288
```ruby
289 290 291 292 293 294 295
concern :commentable do
  resources :comments
end

concern :image_attachable do
  resources :images, only: :index
end
296
```
297 298 299

These concerns can be used in resources to avoid code duplication and share behavior across routes.

300
```ruby
301 302 303
resources :messages, concerns: :commentable

resources :posts, concerns: [:commentable, :image_attachable]
304
```
305 306 307

Also you can use them in any place that you want inside the routes, for example in a scope or namespace call:

308
```ruby
309 310 311
namespace :posts do
  concerns :commentable
end
312
```
313

314
### Creating Paths and URLs From Objects
315

316
In addition to using the routing helpers, Rails can also create paths and URLs from an array of parameters. For example, suppose you have this set of routes:
317

318
```ruby
319 320
resources :magazines do
  resources :ads
321
end
322
```
323

324
When using `magazine_ad_path`, you can pass in instances of `Magazine` and `Ad` instead of the numeric IDs.
325

326
```erb
327
<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
328
```
329

330
You can also use `url_for` with a set of objects, and Rails will automatically determine which route you want:
331

332
```erb
333
<%= link_to "Ad details", url_for([@magazine, @ad]) %>
334
```
335

336
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:
337

338
```erb
339
<%= link_to "Ad details", [@magazine, @ad] %>
340
```
341

V
Vijay Dev 已提交
342
If you wanted to link to just a magazine:
343

344
```erb
345
<%= link_to "Magazine details", @magazine %>
346
```
347

V
Vijay Dev 已提交
348
For other actions, you just need to insert the action name as the first element of the array:
349

350
```erb
351
<%= link_to "Edit Ad", [:edit, @magazine, @ad] %>
352
```
353

354
This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style.
355

356
### Adding More RESTful Actions
357

358
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.
359

360
#### Adding Member Routes
361

362
To add a member route, just add a `member` block into the resource block:
363

364
```ruby
365 366
resources :photos do
  member do
367
    get 'preview'
368 369
  end
end
370
```
371

372
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.
373

374
Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use `get`, `patch`, `put`, `post`, or `delete` here. If you don't have multiple `member` routes, you can also pass `:on` to a route, eliminating the block:
375

376
```ruby
377
resources :photos do
A
AvnerCohen 已提交
378
  get 'preview', on: :member
379
end
380
```
381

382
#### Adding Collection Routes
383

384
To add a route to the collection:
385

386
```ruby
387 388
resources :photos do
  collection do
389
    get 'search'
390 391
  end
end
392
```
393

394
This will enable Rails to recognize paths 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.
395

396
Just as with member routes, you can pass `:on` to a route:
397

398
```ruby
399
resources :photos do
A
AvnerCohen 已提交
400
  get 'search', on: :collection
401
end
402
```
403

B
Bryan Larsen 已提交
404 405 406 407 408 409
#### Adding Routes for Additional New Actions

To add an alternate new action using the `:on` shortcut:

```ruby
resources :comments do
A
AvnerCohen 已提交
410
  get 'preview', on: :new
B
Bryan Larsen 已提交
411 412 413 414 415
end
```

This will enable Rails to recognize paths such as `/comments/new/preview` with GET, and route to the `preview` action of `CommentsController`. It will also create the `preview_new_comment_url` and `preview_new_comment_path` route helpers.

416
#### A Note of Caution
417

418
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.
419

420 421
Non-Resourceful Routes
----------------------
422

423
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.
424

425 426 427
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.

In particular, simple routing makes it very easy to map legacy URLs to new Rails actions.
428

429
### Bound Parameters
430

431
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:
432

433
```ruby
434
get ':controller(/:action(/:id))'
435
```
436

437
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#index`, since `:action` and `:id` are optional parameters, denoted by parentheses.
438

439
### Dynamic Segments
440

441
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:
442

443
```ruby
444
get ':controller/:action/:id/:user_id'
445
```
446

447
An incoming path 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"`.
448

449
NOTE: You can't use `:namespace` or `:module` with a `:controller` path segment. If you need to do this then use a constraint on :controller that matches the namespace you require. e.g:
450

451
```ruby
A
AvnerCohen 已提交
452
get ':controller(/:action(/:id))', controller: /admin\/[^\/]+/
453
```
454

A
AvnerCohen 已提交
455
TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, `id: /[^\/]+/` allows anything except a slash.
456

457
### Static Segments
458

459
You can specify static segments when creating a route:
460

461
```ruby
462
get ':controller/:action/:id/with_user/:user_id'
463
```
464

A
AvnerCohen 已提交
465
This route would respond to paths such as `/photos/show/1/with_user/2`. In this case, `params` would be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`.
466

467
### The Query String
468

469
The `params` will also include any parameters from the query string. For example, with this route:
470

471
```ruby
472
get ':controller/:action/:id'
473
```
474

A
AvnerCohen 已提交
475
An incoming path of `/photos/show/1?user_id=2` will be dispatched to the `show` action of the `Photos` controller. `params` will be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`.
476

477
### Defining Defaults
478

479
You do not need to explicitly use the `:controller` and `:action` symbols within a route. You can supply them as defaults:
480

481
```ruby
482
get 'photos/:id' => 'photos#show'
483
```
484

485
With this route, Rails will match an incoming path of `/photos/12` to the `show` action of `PhotosController`.
486

487
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:
488

489
```ruby
A
AvnerCohen 已提交
490
get 'photos/:id' => 'photos#show', defaults: { format: 'jpg' }
491
```
492

493
Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`.
494

495
### Naming Routes
496

497
You can specify a name for any route using the `:as` option.
498

499
```ruby
A
AvnerCohen 已提交
500
get 'exit' => 'sessions#destroy', as: :logout
501
```
502

503
This will create `logout_path` and `logout_url` as named helpers in your application. Calling `logout_path` will return `/exit`
504

505 506
You can also use this to override routing methods defined by resources, like this:

507
```ruby
A
AvnerCohen 已提交
508
get ':username', to: "users#show", as: :user
509
```
510

511
This will define a `user_path` method that will be available in controllers, helpers and views that will go to a route such as `/bob`. Inside the `show` action of `UsersController`, `params[:username]` will contain the username for the user. Change `:username` in the route definition if you do not want your parameter name to be `:username`.
512

513
### HTTP Verb Constraints
514

515
In general, you should use the `get`, `post`, `put` 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:
516

517
```ruby
A
AvnerCohen 已提交
518
match 'photos' => 'photos#show', via: [:get, :post]
519
```
520

A
AvnerCohen 已提交
521
You can match all verbs to a particular route using `via: :all`:
522

523
```ruby
A
AvnerCohen 已提交
524
match 'photos' => 'photos#show', via: :all
525
```
526

527
You should avoid routing all verbs to an action unless you have a good reason to, as routing both `GET` requests and `POST` requests to a single action has security implications.
528

529
### Segment Constraints
530

531
You can use the `:constraints` option to enforce a format for a dynamic segment:
532

533
```ruby
A
AvnerCohen 已提交
534
get 'photos/:id' => 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
535
```
536

537
This route would match paths such as `/photos/A12345`. You can more succinctly express the same route this way:
538

539
```ruby
A
AvnerCohen 已提交
540
get 'photos/:id' => 'photos#show', id: /[A-Z]\d{5}/
541
```
542

543
`:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work:
544

545
```ruby
A
AvnerCohen 已提交
546
get '/:id' => 'posts#show', constraints: {id: /^\d/}
547
```
548 549 550

However, note that you don't need to use anchors because all routes are anchored at the start.

551
For example, the following routes would allow for `posts` 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:
552

553
```ruby
A
AvnerCohen 已提交
554
get '/:id' => 'posts#show', constraints: { id: /\d.+/ }
555
get '/:username' => 'users#show'
556
```
557

558
### Request-Based Constraints
559

560
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`.
561 562 563

You specify a request-based constraint the same way that you specify a segment constraint:

564
```ruby
A
AvnerCohen 已提交
565
get "photos", constraints: {subdomain: "admin"}
566
```
567

V
Vijay Dev 已提交
568
You can also specify constraints in a block form:
569

570
```ruby
571
namespace :admin do
A
AvnerCohen 已提交
572
  constraints subdomain: "admin" do
573 574 575
    resources :photos
  end
end
576
```
577

578
### Advanced Constraints
579

580
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:
581

582
```ruby
583 584 585 586 587 588 589 590 591 592 593
class BlacklistConstraint
  def initialize
    @ips = Blacklist.retrieve_ips
  end

  def matches?(request)
    @ips.include?(request.remote_ip)
  end
end

TwitterClone::Application.routes.draw do
594
  get "*path" => "blacklist#index",
A
AvnerCohen 已提交
595
    constraints: BlacklistConstraint.new
596
end
597
```
598

599 600
You can also specify constraints as a lambda:

601
```ruby
602
TwitterClone::Application.routes.draw do
603
  get "*path" => "blacklist#index",
A
AvnerCohen 已提交
604
    constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
605
end
606
```
607

608
Both the `matches?` method and the lambda gets the `request` object as an argument.
609

610
### Route Globbing
611 612 613

Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example

614
```ruby
615
get 'photos/*other' => 'photos#unknown'
616
```
617

618
This route would match `photos/12` or `/photos/long/path/to/12`, setting `params[:other]` to `"12"` or `"long/path/to/12"`.
619

620
Wildcard segments can occur anywhere in a route. For example,
621

622
```ruby
623
get 'books/*section/:title' => 'books#show'
624
```
625

626
would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `"some/section"`, and `params[:title]` equals `"last-words-a-memoir"`.
627

628
Technically a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example,
629

630
```ruby
631
get '*a/foo/*b' => 'test#index'
632
```
633

634
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `"zoo/woo"`, and `params[:b]` equals `"bar/baz"`.
635

636
NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route:
637

638
```ruby
639
get '*pages' => 'pages#show'
640
```
641

A
AvnerCohen 已提交
642
NOTE: By requesting `"/foo/bar.json"`, your `params[:pages]` will be equals 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:
643

644
```ruby
A
AvnerCohen 已提交
645
get '*pages' => 'pages#show', format: false
646
```
647

A
AvnerCohen 已提交
648
NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply `format: true` like this:
649

650
```ruby
A
AvnerCohen 已提交
651
get '*pages' => 'pages#show', format: true
652
```
653

654
### Redirection
655

656
You can redirect any path to another path using the `redirect` helper in your router:
657

658
```ruby
659
get "/stories" => redirect("/posts")
660
```
661 662 663

You can also reuse dynamic segments from the match in the path to redirect to:

664
```ruby
665
get "/stories/:name" => redirect("/posts/%{name}")
666
```
667

668
You can also provide a block to redirect, which receives the params and the request object:
669

670
```ruby
671
get "/stories/:name" => redirect {|params, req| "/posts/#{params[:name].pluralize}" }
672
get "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }
673
```
674

675
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.
676

677
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.
678

679
### Routing to Rack Applications
680

681
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.
682

683
```ruby
A
AvnerCohen 已提交
684
match "/application.js" => Sprockets, via: :all
685
```
686

A
AvnerCohen 已提交
687
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.
688

689
NOTE: For the curious, `"posts#index"` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application.
690

691
### Using `root`
692

693
You can specify what Rails should route `"/"` to with the `root` method:
694

695
```ruby
A
AvnerCohen 已提交
696
root to: 'pages#main'
697
root 'pages#main' # shortcut for the above
698
```
699

700
You should put the `root` route at the top of the file, because it is the most popular route and should be matched first. You also need to delete the `public/index.html` file for the root route to take effect.
701

702
NOTE: The `root` route only routes `GET` requests to the action.
703

704
### Unicode character routes
705 706 707

You can specify unicode character routes directly. For example

708
```ruby
709
match 'こんにちは' => 'welcome#index'
710
```
711

712 713
Customizing Resourceful Routes
------------------------------
714

715
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.
716

717
### Specifying a Controller to Use
718

719
The `:controller` option lets you explicitly specify a controller to use for the resource. For example:
720

721
```ruby
A
AvnerCohen 已提交
722
resources :photos, controller: "images"
723
```
724

725
will recognize incoming paths beginning with `/photos` but route to the `Images` controller:
726

727 728 729 730 731 732 733 734 735
| HTTP Verb | Path             | action  | named helper         |
| --------- | ---------------- | ------- | -------------------- |
| GET       | /photos          | index   | photos_path          |
| GET       | /photos/new      | new     | new_photo_path       |
| POST      | /photos          | create  | photos_path          |
| GET       | /photos/:id      | show    | photo_path(:id)      |
| GET       | /photos/:id/edit | edit    | edit_photo_path(:id) |
| PATCH/PUT | /photos/:id      | update  | photo_path(:id)      |
| DELETE    | /photos/:id      | destroy | photo_path(:id)      |
736

737
NOTE: Use `photos_path`, `new_photo_path`, etc. to generate paths for this resource.
738

739
### Specifying Constraints
740

741
You can use the `:constraints` option to specify a required format on the implicit `id`. For example:
742

743
```ruby
A
AvnerCohen 已提交
744
resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/}
745
```
746

747
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.
748

749
You can specify a single constraint to apply to a number of routes by using the block form:
750

751
```ruby
A
AvnerCohen 已提交
752
constraints(id: /[A-Z][A-Z][0-9]+/) do
753 754 755
  resources :photos
  resources :accounts
end
756
```
757

758
NOTE: Of course, you can use the more advanced constraints available in non-resourceful routes in this context.
759

A
AvnerCohen 已提交
760
TIP: By default the `:id` parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an `:id` add a constraint which overrides this - for example `id: /[^\/]+/` allows anything except a slash.
761

762
### Overriding the Named Helpers
763

764
The `:as` option lets you override the normal naming for the named route helpers. For example:
765

766
```ruby
A
AvnerCohen 已提交
767
resources :photos, as: "images"
768
```
769

770
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.
771

772 773 774 775 776 777 778 779 780
| HTTP Verb | Path             | action  | named helper         |
| --------- | ---------------- | ------- | -------------------- |
| GET       | /photos          | index   | images_path          |
| GET       | /photos/new      | new     | new_image_path       |
| POST      | /photos          | create  | images_path          |
| GET       | /photos/:id      | show    | image_path(:id)      |
| GET       | /photos/:id/edit | edit    | edit_image_path(:id) |
| PATCH/PUT | /photos/:id      | update  | image_path(:id)      |
| DELETE    | /photos/:id      | destroy | image_path(:id)      |
781

782
### Overriding the `new` and `edit` Segments
783

784
The `:path_names` option lets you override the automatically-generated "new" and "edit" segments in paths:
785

786
```ruby
A
AvnerCohen 已提交
787
resources :photos, path_names: { new: 'make', edit: 'change' }
788
```
789

790
This would cause the routing to recognize paths such as
791

792
```
793 794
/photos/make
/photos/1/change
795
```
796

797
NOTE: The actual action names aren't changed by this option. The two paths shown would still route to the `new` and `edit` actions.
798

799
TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can use a scope.
800

801
```ruby
A
AvnerCohen 已提交
802
scope path_names: { new: "make" } do
803
  # rest of your routes
804
end
805
```
806

807
### Prefixing the Named Route Helpers
808

809
You can use the `:as` option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope.
810

811
```ruby
812
scope "admin" do
A
AvnerCohen 已提交
813
  resources :photos, as: "admin_photos"
814
end
815

816
resources :photos
817
```
818

819
This will provide route helpers such as `admin_photos_path`, `new_admin_photo_path` etc.
820

821
To prefix a group of route helpers, use `:as` with `scope`:
822

823
```ruby
A
AvnerCohen 已提交
824
scope "admin", as: "admin" do
825 826 827 828
  resources :photos, :accounts
end

resources :photos, :accounts
829
```
830

831
This will generate routes such as `admin_photos_path` and `admin_accounts_path` which map to `/admin/photos` and `/admin/accounts` respectively.
832

833
NOTE: The `namespace` scope will automatically add `:as` as well as `:module` and `:path` prefixes.
834

835 836
You can prefix routes with a named parameter also:

837
```ruby
838 839 840
scope ":username" do
  resources :posts
end
841
```
842

843
This will provide you with URLs such as `/bob/posts/1` and will allow you to reference the `username` part of the path as `params[:username]` in controllers, helpers and views.
844

845
### Restricting the Routes Created
846

847
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:
848

849
```ruby
A
AvnerCohen 已提交
850
resources :photos, only: [:index, :show]
851
```
852

853
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.
854

855
The `:except` option specifies a route or list of routes that Rails should _not_ create:
856

857
```ruby
A
AvnerCohen 已提交
858
resources :photos, except: :destroy
859
```
860

861
In this case, Rails will create all of the normal routes except the route for `destroy` (a `DELETE` request to `/photos/:id`).
862

863
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.
864

865
### Translated Paths
866

867
Using `scope`, we can alter path names generated by resources:
868

869
```ruby
A
AvnerCohen 已提交
870 871
scope(path_names: { new: "neu", edit: "bearbeiten" }) do
  resources :categories, path: "kategorien"
872
end
873
```
874

875
Rails now creates routes to the `CategoriesController`.
876

877 878 879 880 881 882 883 884 885
| HTTP Verb | Path                       | action  | used for                |
| --------- | -------------------------- | ------- | ----------------------- |
| GET       | /kategorien                | index   | categories_path         |
| GET       | /kategorien/neu            | new     | new_category_path       |
| POST      | /kategorien                | create  | categories_path         |
| GET       | /kategorien/:id            | show    | category_path(:id)      |
| GET       | /kategorien/:id/bearbeiten | edit    | edit_category_path(:id) |
| PATCH/PUT | /kategorien/:id            | update  | category_path(:id)      |
| DELETE    | /kategorien/:id            | destroy | category_path(:id)      |
886

887
### Overriding the Singular Form
888

889
If you want to define the singular form of a resource, you should add additional rules to the `Inflector`.
890

891
```ruby
892 893 894
ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'tooth', 'teeth'
end
895
```
896

897
### Using `:as` in Nested Resources
898

899
The `:as` option overrides the automatically-generated name for the resource in nested route helpers. For example,
900

901
```ruby
902
resources :magazines do
A
AvnerCohen 已提交
903
  resources :ads, as: 'periodical_ads'
904
end
905
```
906

907
This will create routing helpers such as `magazine_periodical_ads_url` and `edit_magazine_periodical_ad_path`.
908

909 910
Inspecting and Testing Routes
-----------------------------
911

912
Rails offers facilities for inspecting and testing your routes.
913

914
### Seeing Existing Routes
915

916
To get a complete list of the available routes in your application, visit `http://localhost:3000/rails/info/routes` in your browser while your server is running in the **development** environment. You can also execute the `rake routes` command in your terminal to produce the same output.
V
Vijay Dev 已提交
917

918
Both methods will list all of your routes, in the same order that they appear in `routes.rb`. For each route, you'll see:
919 920 921

* The route name (if any)
* The HTTP verb used (if the route doesn't respond to all verbs)
922 923
* The URL pattern to match
* The routing parameters for the route
924

925
For example, here's a small section of the `rake routes` output for a RESTful route:
926

927
```
928 929 930 931
    users GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
 new_user GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit
932
```
933

934
You may restrict the listing to the routes that map to a particular controller setting the `CONTROLLER` environment variable:
935

P
Prem Sichanugrist 已提交
936
```bash
937
$ CONTROLLER=users rake routes
938
```
939

940
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.
941

942
### Testing Routes
943

944
Routes should be included in your testing strategy (just like the rest of your application). Rails offers three [built-in assertions](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html) designed to make testing routes simpler:
945

946 947 948
* `assert_generates`
* `assert_recognizes`
* `assert_routing`
949

950
#### The `assert_generates` Assertion
951

952
`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes.
953

954
```ruby
A
AvnerCohen 已提交
955 956
assert_generates "/photos/1", { controller: "photos", action: "show", id: "1" }
assert_generates "/about", controller: "pages", action: "about"
957
```
958

959
#### The `assert_recognizes` Assertion
960

961
`assert_recognizes` is the inverse of `assert_generates`. It asserts that a given path is recognized and routes it to a particular spot in your application.
962

963
```ruby
A
AvnerCohen 已提交
964
assert_recognizes({ controller: "photos", action: "show", id: "1" }, "/photos/1")
965
```
966

967
You can supply a `:method` argument to specify the HTTP verb:
968

969
```ruby
A
AvnerCohen 已提交
970
assert_recognizes({ controller: "photos", action: "create" }, { path: "photos", method: :post })
971
```
972

973
#### The `assert_routing` Assertion
974

975
The `assert_routing` assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of `assert_generates` and `assert_recognizes`.
976

977
```ruby
A
AvnerCohen 已提交
978
assert_routing({ path: "photos", method: :post }, { controller: "photos", action: "create" })
979
```