Skip to content

Commit 2d3dbd6

Browse files
jonathanhefnereugeneius
authored andcommitted
Merge pull request #40593 from jonathanhefner/guide-routing-link-api
Link to API docs in Routing guide [ci-skip]
1 parent f7f985f commit 2d3dbd6

File tree

1 file changed

+71
-29
lines changed

1 file changed

+71
-29
lines changed

guides/source/routing.md

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ NOTE: The `Rails.application.routes.draw do ... end` block that wraps your route
8383
Resource Routing: the Rails Default
8484
-----------------------------------
8585

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.
87+
88+
[`resources`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources
8789

8890
### Resources on the Web
8991

@@ -200,7 +202,7 @@ As with plural resources, the same helpers ending in `_url` will also include th
200202

201203
### Controller Namespaces and Routing
202204

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:
204206

205207
```ruby
206208
namespace :admin do
@@ -220,29 +222,29 @@ This will create a number of routes for each of the `articles` and `comments` co
220222
| PATCH/PUT | /admin/articles/:id | admin/articles#update | admin_article_path(:id) |
221223
| DELETE | /admin/articles/:id | admin/articles#destroy | admin_article_path(:id) |
222224

223-
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:
224226

225227
```ruby
226228
scope module: 'admin' do
227229
resources :articles, :comments
228230
end
229231
```
230232

231-
or, for a single case:
233+
This can also be done for a single route:
232234

233235
```ruby
234236
resources :articles, module: 'admin'
235237
```
236238

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:
238240

239241
```ruby
240242
scope '/admin' do
241243
resources :articles, :comments
242244
end
243245
```
244246

245-
or, for a single case:
247+
This can also be done for a single route:
246248

247249
```ruby
248250
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 `
262264

263265
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'`._
264266

267+
[`namespace`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-namespace
268+
[`scope`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-scope
269+
265270
### Nested Resources
266271

267272
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:
407412

408413
### Routing Concerns
409414

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:
411416

412417
```ruby
413418
concern :commentable do
@@ -440,14 +445,17 @@ resources :articles do
440445
end
441446
```
442447

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:
444449

445450
```ruby
446451
namespace :articles do
447452
concerns :commentable
448453
end
449454
```
450455

456+
[`concern`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Concerns.html#method-i-concern
457+
[`concerns`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Concerns.html#method-i-concerns
458+
451459
### Creating Paths and URLs from Objects
452460

453461
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.
496504

497505
#### Adding Member Routes
498506

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:
500508

501509
```ruby
502510
resources :photos do
@@ -509,7 +517,7 @@ end
509517
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.
510518

511519
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
513521
. If you don't have multiple `member` routes, you can also pass `:on` to a
514522
route, eliminating the block:
515523

@@ -521,9 +529,17 @@ end
521529

522530
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`.
523531

532+
[`delete`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-delete
533+
[`get`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-get
534+
[`member`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-member
535+
[`patch`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-patch
536+
[`post`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-post
537+
[`put`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-put
538+
[`put`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html#method-i-put
539+
524540
#### Adding Collection Routes
525541

526-
To add a route to the collection:
542+
To add a route to the collection, use a [`collection`][] block:
527543

528544
```ruby
529545
resources :photos do
@@ -545,6 +561,8 @@ end
545561

546562
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.
547563

564+
[`collection`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-collection
565+
548566
#### Adding Routes for Additional New Actions
549567

550568
To add an alternate new action using the `:on` shortcut:
@@ -620,7 +638,7 @@ get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
620638

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

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:
624642

625643
```ruby
626644
defaults format: :json do
@@ -630,6 +648,8 @@ end
630648

631649
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.
632650

651+
[`defaults`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-defaults
652+
633653
### Naming Routes
634654

635655
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
651671

652672
### HTTP Verb Constraints
653673

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:
655675

656676
```ruby
657677
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
667687

668688
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.
669689

690+
[`match`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Base.html#method-i-match
691+
670692
### Segment Constraints
671693

672694
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
706728
get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }
707729
```
708730

709-
You can also specify constraints in a block form:
731+
You can also specify constraints by using a [`constraints`][] block:
710732

711733
```ruby
712734
namespace :admin do
@@ -720,6 +742,8 @@ NOTE: Request constraints work by calling a method on the [Request object](actio
720742

721743
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.
722744

745+
[`constraints`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-constraints
746+
723747
### Advanced Constraints
724748

725749
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
821845

822846
### Redirection
823847

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:
825849

826850
```ruby
827851
get '/stories', to: redirect('/articles')
@@ -848,6 +872,8 @@ get '/stories/:name', to: redirect('/articles/%{name}', status: 302)
848872

849873
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.
850874

875+
[`redirect`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Redirection.html#method-i-redirect
876+
851877
### Routing to Rack Applications
852878

853879
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
869895
```
870896

871897
If you would prefer to have your Rack application receive requests at the root
872-
path instead, use `mount`:
898+
path instead, use [`mount`][]:
873899

874900
```ruby
875901
mount AdminApp, at: '/admin'
876902
```
877903

904+
[`mount`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Base.html#method-i-mount
905+
878906
### Using `root`
879907

880-
You can specify what Rails should route `'/'` to with the `root` method:
908+
You can specify what Rails should route `'/'` to with the [`root`][] method:
881909

882910
```ruby
883911
root to: 'pages#main'
@@ -898,6 +926,8 @@ end
898926
root to: "home#index"
899927
```
900928

929+
[`root`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-root
930+
901931
### Unicode Character Routes
902932

903933
You can specify unicode character routes directly. For example:
@@ -908,7 +938,7 @@ get 'こんにちは', to: 'welcome#index'
908938

909939
### Direct Routes
910940

911-
You can create custom URL helpers directly. For example:
941+
You can create custom URL helpers directly by calling [`direct`][]. For example:
912942

913943
```ruby
914944
direct :homepage do
@@ -931,9 +961,11 @@ direct :main do
931961
end
932962
```
933963

964+
[`direct`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/CustomUrls.html#method-i-direct
965+
934966
### Using `resolve`
935967

936-
The `resolve` method allows customizing polymorphic mapping of models. For example:
968+
The [`resolve`][] method allows customizing polymorphic mapping of models. For example:
937969

938970
``` ruby
939971
resource :basket
@@ -949,10 +981,12 @@ resolve("Basket") { [:basket] }
949981

950982
This will generate the singular URL `/basket` instead of the usual `/baskets/:id`.
951983

984+
[`resolve`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/CustomUrls.html#method-i-resolve
985+
952986
Customizing Resourceful Routes
953987
------------------------------
954988

955-
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.
956990

957991
### Specifying a Controller to Use
958992

@@ -1139,14 +1173,16 @@ Rails now creates routes to the `CategoriesController`.
11391173

11401174
### Overriding the Singular Form
11411175

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`][]:
11431177

11441178
```ruby
11451179
ActiveSupport::Inflector.inflections do |inflect|
11461180
inflect.irregular 'tooth', 'teeth'
11471181
end
11481182
```
11491183

1184+
[`inflections`]: https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-inflections
1185+
11501186
### Using `:as` in Nested Resources
11511187

11521188
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:
12011237
If you work in a large application with thousands of routes,
12021238
a single `config/routes.rb` file can become cumbersome and hard to read.
12031239

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.
12051241

12061242
```ruby
12071243
# config/routes.rb
@@ -1225,6 +1261,8 @@ The file needs to be located inside the `config/routes` directory or any sub-dir
12251261

12261262
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.
12271263

1264+
[`draw`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-draw
1265+
12281266
### When to use and not use this feature
12291267

12301268
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
13051343

13061344
### Testing Routes
13071345

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:
1347+
1348+
* [`assert_generates`][]
1349+
* [`assert_recognizes`][]
1350+
* [`assert_routing`][]
13091351

1310-
* `assert_generates`
1311-
* `assert_recognizes`
1312-
* `assert_routing`
1352+
[`assert_generates`]: https://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_generates
1353+
[`assert_recognizes`]: https://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes
1354+
[`assert_routing`]: https://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_routing
13131355

13141356
#### The `assert_generates` Assertion
13151357

1316-
`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:
13171359

13181360
```ruby
13191361
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
@@ -1322,7 +1364,7 @@ assert_generates '/about', controller: 'pages', action: 'about'
13221364

13231365
#### The `assert_recognizes` Assertion
13241366

1325-
`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:
13261368

13271369
```ruby
13281370
assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
@@ -1336,7 +1378,7 @@ assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos',
13361378

13371379
#### The `assert_routing` Assertion
13381380

1339-
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`:
13401382

13411383
```ruby
13421384
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })

0 commit comments

Comments
 (0)