aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/routing.md
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source/routing.md')
-rw-r--r--guides/source/routing.md128
1 files changed, 64 insertions, 64 deletions
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 469fcf49fb..53f037c25b 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -27,17 +27,17 @@ GET /patients/17
it asks the router to match it to a controller action. If the first matching route is
```ruby
-get "/patients/:id" => "patients#show"
+get '/patients/:id', to: 'patients#show'
```
-the request is dispatched to the `patients` controller's `show` action with `{ id: "17" }` in `params`.
+the request is dispatched to the `patients` controller's `show` action with `{ id: '17' }` in `params`.
### Generating Paths and URLs from Code
You can also generate paths and URLs. If the route above is modified to be
```ruby
-get "/patients/:id" => "patients#show", as: "patient"
+get '/patients/:id', to: 'patients#show', as: 'patient'
```
If your application contains this code:
@@ -47,7 +47,7 @@ If your application contains this code:
```
```erb
-<%= link_to "Patient Record", patient_path(@patient) %>
+<%= link_to 'Patient Record', patient_path(@patient) %>
```
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.
@@ -73,7 +73,7 @@ it asks the router to map it to a controller action. If the first matching route
resources :photos
```
-Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: "17" }` in `params`.
+Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: '17' }` in `params`.
### CRUD, Verbs, and Actions
@@ -131,7 +131,7 @@ resources :videos
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.
```ruby
-get "profile" => "users#show"
+get 'profile', to: 'users#show'
```
This resourceful route
@@ -186,7 +186,7 @@ This will create a number of routes for each of the `posts` and `comments` contr
If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use
```ruby
-scope module: "admin" do
+scope module: 'admin' do
resources :posts, :comments
end
```
@@ -194,13 +194,13 @@ end
or, for a single case
```ruby
-resources :posts, module: "admin"
+resources :posts, module: 'admin'
```
If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use
```ruby
-scope "/admin" do
+scope '/admin' do
resources :posts, :comments
end
```
@@ -208,7 +208,7 @@ end
or, for a single case
```ruby
-resources :posts, path: "/admin/posts"
+resources :posts, path: '/admin/posts'
```
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`:
@@ -324,31 +324,31 @@ end
When using `magazine_ad_path`, you can pass in instances of `Magazine` and `Ad` instead of the numeric IDs.
```erb
-<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
+<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
```
You can also use `url_for` with a set of objects, and Rails will automatically determine which route you want:
```erb
-<%= link_to "Ad details", url_for([@magazine, @ad]) %>
+<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
```
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:
```erb
-<%= link_to "Ad details", [@magazine, @ad] %>
+<%= link_to 'Ad details', [@magazine, @ad] %>
```
If you wanted to link to just a magazine:
```erb
-<%= link_to "Magazine details", @magazine %>
+<%= link_to 'Magazine details', @magazine %>
```
For other actions, you just need to insert the action name as the first element of the array:
```erb
-<%= link_to "Edit Ad", [:edit, @magazine, @ad] %>
+<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
```
This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style.
@@ -462,7 +462,7 @@ You can specify static segments when creating a route:
get ':controller/:action/:id/with_user/:user_id'
```
-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" }`.
+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' }`.
### The Query String
@@ -472,14 +472,14 @@ The `params` will also include any parameters from the query string. For example
get ':controller/:action/:id'
```
-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" }`.
+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' }`.
### Defining Defaults
You do not need to explicitly use the `:controller` and `:action` symbols within a route. You can supply them as defaults:
```ruby
-get 'photos/:id' => 'photos#show'
+get 'photos/:id', to: 'photos#show'
```
With this route, Rails will match an incoming path of `/photos/12` to the `show` action of `PhotosController`.
@@ -487,7 +487,7 @@ With this route, Rails will match an incoming path of `/photos/12` to the `show`
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:
```ruby
-get 'photos/:id' => 'photos#show', defaults: { format: 'jpg' }
+get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
```
Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`.
@@ -497,7 +497,7 @@ Rails would match `photos/12` to the `show` action of `PhotosController`, and se
You can specify a name for any route using the `:as` option.
```ruby
-get 'exit' => 'sessions#destroy', as: :logout
+get 'exit', to: 'sessions#destroy', as: :logout
```
This will create `logout_path` and `logout_url` as named helpers in your application. Calling `logout_path` will return `/exit`
@@ -505,7 +505,7 @@ This will create `logout_path` and `logout_url` as named helpers in your applica
You can also use this to override routing methods defined by resources, like this:
```ruby
-get ':username', to: "users#show", as: :user
+get ':username', to: 'users#show', as: :user
```
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`.
@@ -515,13 +515,13 @@ This will define a `user_path` method that will be available in controllers, hel
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:
```ruby
-match 'photos' => 'photos#show', via: [:get, :post]
+match 'photos', to: 'photos#show', via: [:get, :post]
```
You can match all verbs to a particular route using `via: :all`:
```ruby
-match 'photos' => 'photos#show', via: :all
+match 'photos', to: 'photos#show', via: :all
```
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.
@@ -531,19 +531,19 @@ You should avoid routing all verbs to an action unless you have a good reason to
You can use the `:constraints` option to enforce a format for a dynamic segment:
```ruby
-get 'photos/:id' => 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
+get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
```
This route would match paths such as `/photos/A12345`. You can more succinctly express the same route this way:
```ruby
-get 'photos/:id' => 'photos#show', id: /[A-Z]\d{5}/
+get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
```
`:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work:
```ruby
-get '/:id' => 'posts#show', constraints: {id: /^\d/}
+get '/:id', to: 'posts#show', constraints: {id: /^\d/}
```
However, note that you don't need to use anchors because all routes are anchored at the start.
@@ -551,8 +551,8 @@ However, note that you don't need to use anchors because all routes are anchored
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:
```ruby
-get '/:id' => 'posts#show', constraints: { id: /\d.+/ }
-get '/:username' => 'users#show'
+get '/:id', to: 'posts#show', constraints: { id: /\d.+/ }
+get '/:username', to: 'users#show'
```
### Request-Based Constraints
@@ -562,14 +562,14 @@ You can also constrain a route based on any method on the <a href="action_contro
You specify a request-based constraint the same way that you specify a segment constraint:
```ruby
-get "photos", constraints: {subdomain: "admin"}
+get 'photos', constraints: {subdomain: 'admin'}
```
You can also specify constraints in a block form:
```ruby
namespace :admin do
- constraints subdomain: "admin" do
+ constraints subdomain: 'admin' do
resources :photos
end
end
@@ -591,7 +591,7 @@ class BlacklistConstraint
end
TwitterClone::Application.routes.draw do
- get "*path" => "blacklist#index",
+ get '*path', to: 'blacklist#index',
constraints: BlacklistConstraint.new
end
```
@@ -600,7 +600,7 @@ You can also specify constraints as a lambda:
```ruby
TwitterClone::Application.routes.draw do
- get "*path" => "blacklist#index",
+ get '*path', to: 'blacklist#index',
constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
end
```
@@ -612,7 +612,7 @@ Both the `matches?` method and the lambda gets the `request` object as an argume
Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
```ruby
-get 'photos/*other' => 'photos#unknown'
+get 'photos/*other', to: 'photos#unknown'
```
This route would match `photos/12` or `/photos/long/path/to/12`, setting `params[:other]` to `"12"` or `"long/path/to/12"`.
@@ -620,35 +620,35 @@ This route would match `photos/12` or `/photos/long/path/to/12`, setting `params
Wildcard segments can occur anywhere in a route. For example,
```ruby
-get 'books/*section/:title' => 'books#show'
+get 'books/*section/:title', to: 'books#show'
```
-would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `"some/section"`, and `params[:title]` equals `"last-words-a-memoir"`.
+would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `'some/section'`, and `params[:title]` equals `'last-words-a-memoir'`.
Technically a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example,
```ruby
-get '*a/foo/*b' => 'test#index'
+get '*a/foo/*b', to: 'test#index'
```
-would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `"zoo/woo"`, and `params[:b]` equals `"bar/baz"`.
+would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `'zoo/woo'`, and `params[:b]` equals `'bar/baz'`.
NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route:
```ruby
-get '*pages' => 'pages#show'
+get '*pages', to: 'pages#show'
```
-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:
+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:
```ruby
-get '*pages' => 'pages#show', format: false
+get '*pages', to: 'pages#show', format: false
```
NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply `format: true` like this:
```ruby
-get '*pages' => 'pages#show', format: true
+get '*pages', to: 'pages#show', format: true
```
### Redirection
@@ -656,20 +656,20 @@ get '*pages' => 'pages#show', format: true
You can redirect any path to another path using the `redirect` helper in your router:
```ruby
-get "/stories" => redirect("/posts")
+get '/stories', to: redirect('/posts')
```
You can also reuse dynamic segments from the match in the path to redirect to:
```ruby
-get "/stories/:name" => redirect("/posts/%{name}")
+get '/stories/:name', to: redirect('/posts/%{name}')
```
You can also provide a block to redirect, which receives the params and the request object:
```ruby
-get "/stories/:name" => redirect {|params, req| "/posts/#{params[:name].pluralize}" }
-get "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }
+get '/stories/:name', to: redirect {|params, req| "/posts/#{params[:name].pluralize}" }
+get '/stories', to: redirect {|p, req| "/posts/#{req.subdomain}" }
```
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.
@@ -678,19 +678,19 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl
### Routing to Rack Applications
-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.
+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.
```ruby
-match "/application.js" => Sprockets, via: :all
+match '/application.js', to: Sprockets, via: :all
```
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.
-NOTE: For the curious, `"posts#index"` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application.
+NOTE: For the curious, `'posts#index'` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application.
### Using `root`
-You can specify what Rails should route `"/"` to with the `root` method:
+You can specify what Rails should route `'/'` to with the `root` method:
```ruby
root to: 'pages#main'
@@ -706,7 +706,7 @@ NOTE: The `root` route only routes `GET` requests to the action.
You can specify unicode character routes directly. For example
```ruby
-match 'こんにちは' => 'welcome#index'
+get 'こんにちは', to: 'welcome#index'
```
Customizing Resourceful Routes
@@ -719,7 +719,7 @@ While the default routes and helpers generated by `resources :posts` will usuall
The `:controller` option lets you explicitly specify a controller to use for the resource. For example:
```ruby
-resources :photos, controller: "images"
+resources :photos, controller: 'images'
```
will recognize incoming paths beginning with `/photos` but route to the `Images` controller:
@@ -764,7 +764,7 @@ TIP: By default the `:id` parameter doesn't accept dots - this is because the do
The `:as` option lets you override the normal naming for the named route helpers. For example:
```ruby
-resources :photos, as: "images"
+resources :photos, as: 'images'
```
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.
@@ -799,7 +799,7 @@ NOTE: The actual action names aren't changed by this option. The two paths shown
TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can use a scope.
```ruby
-scope path_names: { new: "make" } do
+scope path_names: { new: 'make' } do
# rest of your routes
end
```
@@ -809,8 +809,8 @@ end
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.
```ruby
-scope "admin" do
- resources :photos, as: "admin_photos"
+scope 'admin' do
+ resources :photos, as: 'admin_photos'
end
resources :photos
@@ -821,7 +821,7 @@ This will provide route helpers such as `admin_photos_path`, `new_admin_photo_pa
To prefix a group of route helpers, use `:as` with `scope`:
```ruby
-scope "admin", as: "admin" do
+scope 'admin', as: 'admin' do
resources :photos, :accounts
end
@@ -835,7 +835,7 @@ NOTE: The `namespace` scope will automatically add `:as` as well as `:module` an
You can prefix routes with a named parameter also:
```ruby
-scope ":username" do
+scope ':username' do
resources :posts
end
```
@@ -867,8 +867,8 @@ TIP: If your application has many RESTful routes, using `:only` and `:except` to
Using `scope`, we can alter path names generated by resources:
```ruby
-scope(path_names: { new: "neu", edit: "bearbeiten" }) do
- resources :categories, path: "kategorien"
+scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
+ resources :categories, path: 'kategorien'
end
```
@@ -952,8 +952,8 @@ Routes should be included in your testing strategy (just like the rest of your a
`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes.
```ruby
-assert_generates "/photos/1", { controller: "photos", action: "show", id: "1" }
-assert_generates "/about", controller: "pages", action: "about"
+assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
+assert_generates '/about', controller: 'pages', action: 'about'
```
#### The `assert_recognizes` Assertion
@@ -961,13 +961,13 @@ assert_generates "/about", controller: "pages", action: "about"
`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.
```ruby
-assert_recognizes({ controller: "photos", action: "show", id: "1" }, "/photos/1")
+assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
```
You can supply a `:method` argument to specify the HTTP verb:
```ruby
-assert_recognizes({ controller: "photos", action: "create" }, { path: "photos", method: :post })
+assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos', method: :post })
```
#### The `assert_routing` Assertion
@@ -975,5 +975,5 @@ assert_recognizes({ controller: "photos", action: "create" }, { path: "photos",
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`.
```ruby
-assert_routing({ path: "photos", method: :post }, { controller: "photos", action: "create" })
+assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
```