You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guides/source/routing.md
+71-29Lines changed: 71 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -83,7 +83,9 @@ NOTE: The `Rails.application.routes.draw do ... end` block that wraps your route
83
83
Resource Routing: the Rails Default
84
84
-----------------------------------
85
85
86
-
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.
86
+
Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. A single call to [`resources`][] can declare all of the necessary routes for your `index`, `show`, `new`, `edit`, `create`, `update` and `destroy` actions.
@@ -200,7 +202,7 @@ As with plural resources, the same helpers ending in `_url` will also include th
200
202
201
203
### Controller Namespaces and Routing
202
204
203
-
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:
205
+
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, and place these controllers under the `app/controllers/admin` directory. You can route to such a group by using a [`namespace`][] block:
204
206
205
207
```ruby
206
208
namespace :admindo
@@ -220,29 +222,29 @@ This will create a number of routes for each of the `articles` and `comments` co
If you want to route `/articles` (without the prefix `/admin`) to `Admin::ArticlesController`, you could use:
225
+
If instead you want to route `/articles` (without the prefix `/admin`) to `Admin::ArticlesController`, you can specify the module with a [`scope`][] block:
224
226
225
227
```ruby
226
228
scope module: 'admin'do
227
229
resources :articles, :comments
228
230
end
229
231
```
230
232
231
-
or, for a single case:
233
+
This can also be done for a single route:
232
234
233
235
```ruby
234
236
resources :articles, module: 'admin'
235
237
```
236
238
237
-
If you want to route `/admin/articles` to `ArticlesController` (without the `Admin::` module prefix), you could use:
239
+
If instead you want to route `/admin/articles` to `ArticlesController` (without the `Admin::` module prefix), you can specify the path with a `scope` block:
238
240
239
241
```ruby
240
242
scope '/admin'do
241
243
resources :articles, :comments
242
244
end
243
245
```
244
246
245
-
or, for a single case:
247
+
This can also be done for a single route:
246
248
247
249
```ruby
248
250
resources :articles, path:'/admin/articles'
@@ -262,6 +264,9 @@ In each of these cases, the named routes remain the same as if you did not use `
262
264
263
265
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', to: '/foo#index'`._
It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
@@ -407,7 +412,7 @@ The comments resource here will have the following routes generated for it:
407
412
408
413
### Routing Concerns
409
414
410
-
Routing concerns allow you to declare common routes that can be reused inside other resources and routes. To define a concern:
415
+
Routing concerns allow you to declare common routes that can be reused inside other resources and routes. To define a concern, use a [`concern`][] block:
411
416
412
417
```ruby
413
418
concern :commentabledo
@@ -440,14 +445,17 @@ resources :articles do
440
445
end
441
446
```
442
447
443
-
Also you can use them in any place that you want inside the routes, for example in a `scope` or `namespace`call:
448
+
You can also use them anywhere by calling [`concerns`][]. For example, in a `scope` or `namespace`block:
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:
@@ -496,7 +504,7 @@ You are not limited to the seven routes that RESTful routing creates by default.
496
504
497
505
#### Adding Member Routes
498
506
499
-
To add a member route, just add a `member` block into the resource block:
507
+
To add a member route, just add a [`member`][] block into the resource block:
500
508
501
509
```ruby
502
510
resources :photosdo
@@ -509,7 +517,7 @@ end
509
517
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.
510
518
511
519
Within the block of member routes, each route name specifies the HTTP verb that
512
-
will be recognized. You can use `get`, `patch`, `put`, `post`, or `delete` here
520
+
will be recognized. You can use [`get`][], [`patch`][], [`put`][], [`post`][], or [`delete`][] here
513
521
. If you don't have multiple `member` routes, you can also pass `:on` to a
514
522
route, eliminating the block:
515
523
@@ -521,9 +529,17 @@ end
521
529
522
530
You can leave out the `:on` option, this will create the same member route except that the resource id value will be available in `params[:photo_id]` instead of `params[:id]`. Route helpers will also be renamed from `preview_photo_url` and `preview_photo_path` to `photo_preview_url` and `photo_preview_path`.
To add a route to the collection, use a [`collection`][] block:
527
543
528
544
```ruby
529
545
resources :photosdo
@@ -545,6 +561,8 @@ end
545
561
546
562
NOTE: If you're defining additional resource routes with a symbol as the first positional argument, be mindful that it is not equivalent to using a string. Symbols infer controller actions while strings infer paths.
To add an alternate new action using the `:on` shortcut:
@@ -620,7 +638,7 @@ get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
620
638
621
639
Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`.
622
640
623
-
You can also use `defaults` in a block format to define the defaults for multiple items:
641
+
You can also use a [`defaults`][]block to define the defaults for multiple items:
624
642
625
643
```ruby
626
644
defaults format::jsondo
@@ -630,6 +648,8 @@ end
630
648
631
649
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.
You can specify a name for any route using the `:as` option:
@@ -651,7 +671,7 @@ This will define a `user_path` method that will be available in controllers, hel
651
671
652
672
### HTTP Verb Constraints
653
673
654
-
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:
674
+
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:
655
675
656
676
```ruby
657
677
match 'photos', to:'photos#show', via: [:get, :post]
@@ -667,6 +687,8 @@ NOTE: Routing both `GET` and `POST` requests to a single action has security imp
667
687
668
688
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.
You can use the `:constraints` option to enforce a format for a dynamic segment:
@@ -706,7 +728,7 @@ You specify a request-based constraint the same way that you specify a segment c
706
728
get 'photos', to:'photos#index', constraints: { subdomain:'admin' }
707
729
```
708
730
709
-
You can also specify constraints in a block form:
731
+
You can also specify constraints by using a [`constraints`][] block:
710
732
711
733
```ruby
712
734
namespace :admindo
@@ -720,6 +742,8 @@ NOTE: Request constraints work by calling a method on the [Request object](actio
720
742
721
743
NOTE: There is an exception for the `format` constraint: while it's a method on the Request object, it's also an implicit optional parameter on every path. Segment constraints take precedence and the `format` constraint is only applied as such when enforced through a hash. For example, `get 'foo', constraints: { format: 'json' }` will match `GET /foo` because the format is optional by default. However, you can [use a lambda](#advanced-constraints) like in `get 'foo', constraints: lambda { |req| req.format == :json }` and the route will only match explicit JSON requests.
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 restricted list to the `RestrictedListController`. You could do:
@@ -821,7 +845,7 @@ get '*pages', to: 'pages#show', format: true
821
845
822
846
### Redirection
823
847
824
-
You can redirect any path to another path using the `redirect` helper in your router:
848
+
You can redirect any path to another path using the [`redirect`][] helper in your router:
825
849
826
850
```ruby
827
851
get '/stories', to: redirect('/articles')
@@ -848,6 +872,8 @@ get '/stories/:name', to: redirect('/articles/%{name}', status: 302)
848
872
849
873
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.
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:
@@ -869,15 +895,17 @@ match '/admin', to: AdminApp, via: :all
869
895
```
870
896
871
897
If you would prefer to have your Rack application receive requests at the root
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.
989
+
While the default routes and helpers generated by [`resources`][] 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.
956
990
957
991
### Specifying a Controller to Use
958
992
@@ -1139,14 +1173,16 @@ Rails now creates routes to the `CategoriesController`.
1139
1173
1140
1174
### Overriding the Singular Form
1141
1175
1142
-
If you want to define the singular form of a resource, you should add additional rules to the `Inflector`:
1176
+
If you want to define the singular form of a resource, you should add additional rules to the `Inflector` via [`inflections`][]:
The `:as` option overrides the automatically-generated name for the resource in nested route helpers. For example:
@@ -1201,7 +1237,7 @@ Breaking up *very* large route file into multiple small ones:
1201
1237
If you work in a large application with thousands of routes,
1202
1238
a single `config/routes.rb` file can become cumbersome and hard to read.
1203
1239
1204
-
Rails offers a way to break a gigantic single `routes.rb` file into multiple small ones using the `draw` macro.
1240
+
Rails offers a way to break a gigantic single `routes.rb` file into multiple small ones using the [`draw`][] macro.
1205
1241
1206
1242
```ruby
1207
1243
# config/routes.rb
@@ -1225,6 +1261,8 @@ The file needs to be located inside the `config/routes` directory or any sub-dir
1225
1261
1226
1262
You can use the normal routing DSL inside the `admin.rb` routing file, **however** you shouldn't surround it with the `Rails.application.routes.draw` block like you did in the main `config/routes.rb` file.
Drawing routes from external files can be very useful to organise a large set of routes into multiple organised ones. You could have a `admin.rb` route that contains all the routes for the admin area, another `api.rb` file to route API related resources etc...
@@ -1305,15 +1343,19 @@ TIP: You'll find that the output from `bin/rails routes` is much more readable i
1305
1343
1306
1344
### Testing Routes
1307
1345
1308
-
Routes should be included in your testing strategy (just like the rest of your application). Rails offers three [built-in assertions](https://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html) designed to make testing routes simpler:
1346
+
Routes should be included in your testing strategy (just like the rest of your application). Rails offers three built-in assertions designed to make testing routes simpler:
`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes. For example:
1358
+
[`assert_generates`][] asserts that a particular set of options generate a particular path and can be used with default routes or custom routes. For example:
`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. For example:
1367
+
[`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. For example:
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`:
1381
+
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`:
0 commit comments