edge
詳細はrubyonrails.orgで: もっとRuby on Rails

外部からのRailsルーティング

このガイドでは、Railsのルーティングのユーザー向け機能について説明します。

このガイドを読み終えると、以下のことがわかります。

Chapters

  1. Railsルーターの目的
  2. リソースルーティング:Railsのデフォルト
  3. リソースフルでないルート
  4. リソースフルルートのカスタマイズ
  5. 非常に大きなルートファイルを複数の小さなファイルに分割する
  6. ルートの検査とテスト

1 Railsルーターの目的

Railsルーターは、URLを認識し、それらをコントローラーアクションまたはRackアプリケーションにディスパッチします。また、ビューで文字列をハードコードする必要がないため、パスとURLを生成することもできます。

1.1 URLとコードの接続

Railsアプリケーションが次のような受信リクエストを受け取った場合:

GET /patients/17

ルーターにコントローラーアクションと一致するように要求します。最初に一致するルートが次の場合:

get '/patients/:id', to: 'patients#show'

リクエストは、patientsコントローラーのshowアクションに{ id: '17' }paramsとしてディスパッチされます。

注意:ここではRailsはコントローラー名にsnake_caseを使用しています。MonsterTrucksControllerのような複数の単語のコントローラーがある場合は、例えばmonster_trucks#showを使用する必要があります。

1.2 コードからパスとURLを生成する

パスとURLも生成することができます。上記のルートが次のように変更された場合:

get '/patients/:id', to: 'patients#show', as: 'patient'

コントローラーに次のコードが含まれている場合:

@patient = Patient.find(params[:id])

および対応するビューに次のコードが含まれている場合:

<%= link_to 'Patient Record', patient_path(@patient) %>

ルーターはパス/patients/17を生成します。これにより、ビューの脆弱性が低くなり、コードが理解しやすくなります。idはルートヘルパーで指定する必要はありません。

1.3 Railsルーターの設定

アプリケーションまたはエンジンのルートは、config/routes.rbというファイルにあり、通常は次のようになります:

Rails.application.routes.draw do
  resources :brands, only: [:index, :show] do
    resources :products, only: [:index, :show]
  end

  resource :basket, only: [:show, :update, :destroy]

  resolve("Basket") { route_for(:basket) }
end

これは通常のRubyソースファイルなので、ルートを定義するためにすべての機能を使用できますが、ルーターのDSLメソッドと変数名が衝突する可能性があるため、注意が必要です。

注意:ルート定義を囲むRails.application.routes.draw do ... endブロックは、ルーターDSLのスコープを確立するために必要であり、削除してはいけません。

2 リソースルーティング:Railsのデフォルト

リソースルーティングを使用すると、特定のリソースフルコントローラーに対して一般的なルートをすばやく宣言できます。resourcesへの単一の呼び出しで、indexshowneweditcreateupdatedestroyアクションに必要なすべてのルートを宣言できます。

2.1 ウェブ上のリソース

ブラウザは、特定のHTTPメソッド(GETPOSTPATCHPUTDELETEなど)を使用して、URLをリクエストしてRailsからページを要求します。各メソッドは、リソース上で操作を実行するためのリクエストです。リソースルートは、複数の関連するリクエストを単一のコントローラーのアクションにマップします。

Railsアプリケーションが次のような受信リクエストを受け取った場合:

DELETE /photos/17

ルーターにコントローラーアクションにマップするように要求します。最初に一致するルートが次の場合:

resources :photos

Railsは、そのリクエストをphotosコントローラーのdestroyアクションに{ id: '17' }paramsとしてディスパッチします。

2.2 CRUD、動詞、およびアクション

Railsでは、リソースフルなルートは、HTTP動詞とURLをコントローラーアクションにマッピングします。慣例として、各アクションもデータベース内の特定のCRUD操作にマッピングされます。次のようなルーティングファイルのエントリ1つだけで、例えば:

resources :photos

アプリケーション内には、Photosコントローラーにマッピングされる7つの異なるルートが作成されます:

HTTP動詞 パス コントローラー#アクション 用途
GET /photos photos#index すべての写真のリストを表示
GET /photos/new photos#new 新しい写真を作成するためのHTMLフォームを返す
POST /photos photos#create 新しい写真を作成する
GET /photos/:id photos#show 特定の写真を表示
GET /photos/:id/edit photos#edit 写真を編集するためのHTMLフォームを返す
PATCH/PUT /photos/:id photos#update 特定の写真を更新する
DELETE /photos/:id photos#destroy 特定の写真を削除する

注意:ルーターはHTTPの動詞とURLを使用して受信リクエストとマッチングするため、4つのURLが7つの異なるアクションにマッピングされます。

注意:Railsのルートは指定された順序でマッチングされるため、resources :photosの上にget 'photos/poll'がある場合、resourcesの行のshowアクションのルートがgetの行よりも先にマッチングされます。これを修正するには、getの行をresourcesの行のに移動して、最初にマッチングされるようにします。

2.3 パスとURLヘルパー

リソースフルなルートを作成すると、アプリケーションのコントローラにいくつかのヘルパーが公開されます。resources :photosの場合:

  • photos_path/photosを返します
  • new_photo_path/photos/newを返します
  • edit_photo_path(:id)/photos/:id/editを返します(たとえば、edit_photo_path(10)/photos/10/editを返します)
  • photo_path(:id)/photos/:idを返します(たとえば、photo_path(10)/photos/10を返します)

これらのヘルパーのそれぞれには、現在のホスト、ポート、およびパスプレフィックスが前置された同じパスを返す_urlヘルパー(たとえば、photos_url)が対応しています。

ヒント:ルートのヘルパー名を見つけるには、以下の既存のルートのリストを参照してください。

2.4 同時に複数のリソースを定義する

複数のリソースに対してルートを作成する必要がある場合、resourcesへの単一の呼び出しでそれらをすべて定義することで、少しのタイピングを節約できます。

resources :photos, :books, :videos

これは次のように正確に動作します:

resources :photos
resources :books
resources :videos

2.5 単数形のリソース

クライアントが常にIDを参照せずに検索するリソースがある場合があります。たとえば、現在ログインしているユーザーのプロフィールを常に/profileで表示したい場合、単数形のリソースを使用してshowアクションに/profile/profile/:idではなく)をマップできます:

get 'profile', to: 'users#show'

to:Stringを渡すと、controller#actionの形式が期待されます。Symbolを使用する場合は、to:オプションをaction:で置き換える必要があります。#なしのStringを使用する場合は、to:オプションをcontroller:で置き換える必要があります:

get 'profile', action: :show, controller: 'users'

このリソースフルなルート:

resource :geocoder
resolve('Geocoder') { [:geocoder] }

は、アプリケーションに6つの異なるルートを作成し、すべてがGeocodersコントローラにマッピングされます:

HTTP動詞 パス コントローラ#アクション 用途
GET /geocoder/new geocoders#new ジオコーダを作成するためのHTMLフォームを返す
POST /geocoder geocoders#create 新しいジオコーダを作成する
GET /geocoder geocoders#show 唯一のジオコーダリソースを表示する
GET /geocoder/edit geocoders#edit ジオコーダを編集するためのHTMLフォームを返す
PATCH/PUT /geocoder geocoders#update 唯一のジオコーダリソースを更新する
DELETE /geocoder geocoders#destroy ジオコーダリソースを削除する

注意:単数形のルート(/account)と複数形のルート(/accounts/45)の両方に同じコントローラを使用したい場合、単数形のリソースは複数形のコントローラにマップされます。したがって、たとえば、resource :photoresources :photosは、同じコントローラ(PhotosController)にマップされる単数形と複数形のルートを作成します。

単数形のリソースフルなルートは、次のヘルパーを生成します:

  • new_geocoder_path/geocoder/newを返します
  • edit_geocoder_path/geocoder/editを返します
  • geocoder_path/geocoderを返します

注意:resolveへの呼び出しは、レコードの識別を介してGeocoderのインスタンスをルートに変換するために必要です。

複数形のリソースと同様に、ホスト、ポート、およびパスプレフィックスが含まれる_urlで終わる同じヘルパーもあります。

2.6 コントローラの名前空間とルーティング

コントローラのグループを名前空間の下に整理したい場合があります。最も一般的には、いくつかの管理コントローラをAdmin::名前空間の下にグループ化し、これらのコントローラをapp/controllers/adminディレクトリに配置します。namespaceブロックを使用して、そのようなグループにルーティングできます。

namespace :admin do
  resources :articles, :comments
end

これにより、articlescommentsコントローラのそれぞれにいくつかのルートが作成されます。Admin::ArticlesControllerの場合、Railsは次のように作成します:

HTTP動詞 パス コントローラ#アクション 名前付きルートヘルパー
GET /admin/articles admin/articles#index admin_articles_path
GET /admin/articles/new admin/articles#new new_admin_article_path
POST /admin/articles admin/articles#create admin_articles_path
GET /admin/articles/:id admin/articles#show admin_article_path(:id)
GET /admin/articles/:id/edit admin/articles#edit edit_admin_article_path(:id)
PATCH/PUT /admin/articles/:id admin/articles#update admin_article_path(:id)
DELETE /admin/articles/:id admin/articles#destroy admin_article_path(:id)

もしも/articles/adminの接頭辞なし)をAdmin::ArticlesControllerにルーティングしたい場合は、scopeブロックでモジュールを指定することができます。

scope module: 'admin' do
  resources :articles, :comments
end

単一のルートに対しても同様に行うことができます。

resources :articles, module: 'admin'

もしも/admin/articlesArticlesControllerAdmin::モジュール接頭辞なし)にルーティングしたい場合は、scopeブロックでパスを指定することができます。

scope '/admin' do
  resources :articles, :comments
end

単一のルートに対しても同様に行うことができます。

resources :articles, path: '/admin/articles'

これらの場合、名前付きルートヘルパーはscopeを使用しなかった場合と同じままです。最後の場合、以下のパスがArticlesControllerにマップされます。

HTTPメソッド パス コントローラー#アクション 名前付きルートヘルパー
GET /admin/articles articles#index articles_path
GET /admin/articles/new articles#new new_article_path
POST /admin/articles articles#create articles_path
GET /admin/articles/:id articles#show article_path(:id)
GET /admin/articles/:id/edit articles#edit edit_article_path(:id)
PATCH/PUT /admin/articles/:id articles#update article_path(:id)
DELETE /admin/articles/:id articles#destroy article_path(:id)

namespaceブロック内で異なるコントローラーネームスペースを使用する必要がある場合は、絶対コントローラーパスを指定することができます。例:get '/foo', to: '/foo#index'

2.7 ネストされたリソース

リソースが論理的に他のリソースの子であることは一般的です。例えば、アプリケーションに次のモデルが含まれるとします。

class Magazine < ApplicationRecord
  has_many :ads
end

class Ad < ApplicationRecord
  belongs_to :magazine
end

ネストされたルートを使用すると、この関係をルーティングで表現することができます。この場合、次のルート宣言を含めることができます。

resources :magazines do
  resources :ads
end

この宣言により、マガジンに関するルートだけでなく、広告もAdsControllerにルーティングされます。広告のURLにはマガジンが必要です。

HTTPメソッド パス コントローラー#アクション 用途
GET /magazines/:magazine_id/ads ads#index 特定のマガジンのすべての広告のリストを表示する
GET /magazines/:magazine_id/ads/new ads#new 特定のマガジンに所属する新しい広告を作成するためのHTMLフォームを返す
POST /magazines/:magazine_id/ads ads#create 特定のマガジンに所属する新しい広告を作成する
GET /magazines/:magazine_id/ads/:id ads#show 特定のマガジンに所属する特定の広告を表示する
GET /magazines/:magazine_id/ads/:id/edit ads#edit 特定のマガジンに所属する特定の広告を編集するためのHTMLフォームを返す
PATCH/PUT /magazines/:magazine_id/ads/:id ads#update 特定のマガジンに所属する特定の広告を更新する
DELETE /magazines/:magazine_id/ads/:id ads#destroy 特定のマガジンに所属する特定の広告を削除する

これにより、magazine_ads_urledit_magazine_ad_pathなどのルーティングヘルパーも作成されます。これらのヘルパーは、最初のパラメーターとしてMagazineのインスタンスを受け取ります(magazine_ads_url(@magazine))。

2.7.1 ネストの制限

必要に応じて、他のネストされたリソース内にリソースをネストすることもできます。例えば:

resources :publishers do
  resources :magazines do
    resources :photos
  end
end

深くネストされたリソースはすぐに扱いにくくなります。この場合、アプリケーションは次のようなパスを認識します。

/publishers/1/magazines/2/photos/3

対応するルートヘルパーはpublisher_magazine_photo_urlであり、3つのレベルすべてでオブジェクトを指定する必要があります。実際、この状況は混乱を招くため、Jamis Buck氏の人気記事では、良いRailsデザインのための原則を提案しています。

リソースは1レベル以上のネストにするべきではありません。

2.7.2 シャローなネスト

深いネストを避けるための方法の1つは、親の下にコレクションアクションをスコープ付きで生成し、階層を把握するための最小限の情報でリソースを一意に識別するためのルートのみをネストすることです。つまり、次のように記述します。

resources :articles do
  resources :comments, only: [:index, :new, :create]
end
resources :comments, only: [:show, :edit, :update, :destroy]

このアイデアは、記述的なルートと深いネストのバランスを取るものです。このために、:shallowオプションを使用して短縮構文を使用することもできます。

resources :articles do
  resources :comments, shallow: true
end

最初の例と同じルートが生成されます。親リソースで :shallow オプションを指定することもできます。その場合、すべてのネストされたリソースが浅くなります。

resources :articles, shallow: true do
  resources :comments
  resources :quotes
  resources :drafts
end

ここでの articles リソースには、次のルートが生成されます。

HTTP メソッド パス コントローラー#アクション 名前付きルートヘルパー
GET /articles/:article_id/comments(.:format) comments#index article_comments_path
POST /articles/:article_id/comments(.:format) comments#create article_comments_path
GET /articles/:article_id/comments/new(.:format) comments#new new_article_comment_path
GET /comments/:id/edit(.:format) comments#edit edit_comment_path
GET /comments/:id(.:format) comments#show comment_path
PATCH/PUT /comments/:id(.:format) comments#update comment_path
DELETE /comments/:id(.:format) comments#destroy comment_path
GET /articles/:article_id/quotes(.:format) quotes#index article_quotes_path
POST /articles/:article_id/quotes(.:format) quotes#create article_quotes_path
GET /articles/:article_id/quotes/new(.:format) quotes#new new_article_quote_path
GET /quotes/:id/edit(.:format) quotes#edit edit_quote_path
GET /quotes/:id(.:format) quotes#show quote_path
PATCH/PUT /quotes/:id(.:format) quotes#update quote_path
DELETE /quotes/:id(.:format) quotes#destroy quote_path
GET /articles/:article_id/drafts(.:format) drafts#index article_drafts_path
POST /articles/:article_id/drafts(.:format) drafts#create article_drafts_path
GET /articles/:article_id/drafts/new(.:format) drafts#new new_article_draft_path
GET /drafts/:id/edit(.:format) drafts#edit edit_draft_path
GET /drafts/:id(.:format) drafts#show draft_path
PATCH/PUT /drafts/:id(.:format) drafts#update draft_path
DELETE /drafts/:id(.:format) drafts#destroy draft_path
GET /articles(.:format) articles#index articles_path
POST /articles(.:format) articles#create articles_path
GET /articles/new(.:format) articles#new new_article_path
GET /articles/:id/edit(.:format) articles#edit edit_article_path
GET /articles/:id(.:format) articles#show article_path
PATCH/PUT /articles/:id(.:format) articles#update article_path
DELETE /articles/:id(.:format) articles#destroy article_path

DSL の shallow メソッドは、ネストごとにスコープを作成します。これにより、前の例と同じルートが生成されます。

shallow do
  resources :articles do
    resources :comments
    resources :quotes
    resources :drafts
  end
end

浅いルートをカスタマイズするための scope のオプションには、2つのオプションがあります。shallow_path オプションは、メンバーパスに指定したパラメーターを接頭辞として追加します。

scope shallow_path: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end

ここでの comments リソースには、次のルートが生成されます。

HTTP メソッド パス コントローラー#アクション 名前付きルートヘルパー
GET /articles/:article_id/comments(.:format) comments#index article_comments_path
POST /articles/:article_id/comments(.:format) comments#create article_comments_path
GET /articles/:article_id/comments/new(.:format) comments#new new_article_comment_path
GET /sekret/comments/:id/edit(.:format) comments#edit edit_comment_path
GET /sekret/comments/:id(.:format) comments#show comment_path
PATCH/PUT /sekret/comments/:id(.:format) comments#update comment_path
DELETE /sekret/comments/:id(.:format) comments#destroy comment_path

shallow_prefix オプションは、名前付きルートヘルパーに指定したパラメーターを追加します。

scope shallow_prefix: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end

ここでの comments リソースには、次のルートが生成されます。

HTTP メソッド パス コントローラー#アクション 名前付きルートヘルパー
GET /articles/:article_id/comments(.:format) comments#index article_comments_path
POST /articles/:article_id/comments(.:format) comments#create article_comments_path
GET /articles/:article_id/comments/new(.:format) comments#new new_article_comment_path
GET /comments/:id/edit(.:format) comments#edit edit_sekret_comment_path
GET /comments/:id(.:format) comments#show sekret_comment_path
PATCH/PUT /comments/:id(.:format) comments#update sekret_comment_path
DELETE /comments/:id(.:format) comments#destroy sekret_comment_path

2.8 ルーティングの関心事

ルーティングの関心事を使用すると、他のリソースやルート内で再利用できる共通のルートを宣言できます。関心事を定義するには、concern ブロックを使用します。

concern :commentable do
  resources :comments
end

concern :image_attachable do
  resources :images, only: :index
end

これらの関心事は、コードの重複を避け、ルート間での動作を共有するためにリソースで使用できます。

resources :messages, concerns: :commentable

resources :articles, concerns: [:commentable, :image_attachable]

上記は次と同じです。

resources :messages do
  resources :comments
end

resources :articles do
  resources :comments
  resources :images, only: :index
end

concernsを呼び出すことで、どこでも使用することができます。たとえば、scopeブロックやnamespaceブロック内で使用することができます。

namespace :articles do
  concerns :commentable
end

2.9 オブジェクトからパスとURLを作成する

ルーティングヘルパーを使用するだけでなく、Railsはパラメータの配列からパスとURLを作成することもできます。たとえば、次のルートがあるとします。

resources :magazines do
  resources :ads
end

magazine_ad_pathを使用する場合、数値のIDの代わりにMagazineAdのインスタンスを渡すことができます。

<%= link_to '広告の詳細', magazine_ad_path(@magazine, @ad) %>

また、url_forをオブジェクトのセットとともに使用することもできます。Railsは自動的にどのルートを使用するかを判断します。

<%= link_to '広告の詳細', url_for([@magazine, @ad]) %>

この場合、Railsは@magazineMagazineであり、@adAdであることを認識し、magazine_ad_pathヘルパーを使用します。link_toなどのヘルパーでは、url_forの代わりにオブジェクトだけを指定することもできます。

<%= link_to '広告の詳細', [@magazine, @ad] %>

単にマガジンにリンクする場合は、次のようにします。

<%= link_to 'マガジンの詳細', @magazine %>

その他のアクションの場合は、配列の最初の要素としてアクション名を挿入するだけです。

<%= link_to '広告の編集', [:edit, @magazine, @ad] %>

これにより、モデルのインスタンスをURLとして扱うことができ、リソースフルなスタイルを使用することの主な利点です。

2.10 追加のRESTfulアクションの追加

RESTfulルーティングがデフォルトで作成する7つのルートに制限されることはありません。必要に応じて、コレクションまたはコレクションの個々のメンバーに適用される追加のルートを追加することができます。

2.10.1 メンバールートの追加

メンバールートを追加するには、リソースブロックにmemberブロックを追加します。

resources :photos do
  member do
    get 'preview'
  end
end

これにより、GETで/photos/1/previewが認識され、PhotosControllerpreviewアクションにルーティングされます。リソースIDの値はparams[:id]に渡されます。また、preview_photo_urlpreview_photo_pathのヘルパーも作成されます。

メンバールートのブロック内では、各ルート名は認識されるHTTP動詞を指定します。ここではget, patch, put, post, deleteを使用できます。複数のmemberルートがない場合は、ブロックを省略してroute:onを渡すこともできます。

resources :photos do
  get 'preview', on: :member
end

:onオプションを省略することもできます。これにより、リソースIDの値がparams[:id]ではなくparams[:photo_id]で利用できる同じメンバールートが作成されます。ルートヘルパーもpreview_photo_urlpreview_photo_pathからphoto_preview_urlphoto_preview_pathに名前が変更されます。

2.10.2 コレクションルートの追加

collectionブロックを使用してコレクションにルートを追加します。

resources :photos do
  collection do
    get 'search'
  end
end

これにより、GETで/photos/searchなどのパスが認識され、PhotosControllersearchアクションにルーティングされます。また、search_photos_urlsearch_photos_pathのルートヘルパーも作成されます。

メンバールートと同様に、ルートに:onを渡すことができます。

resources :photos do
  get 'search', on: :collection
end

注意: 最初の位置引数としてシンボルを使用して追加のリソースルートを定義している場合、シンボルと文字列は同等ではないことに注意してください。シンボルはコントローラのアクションを推測し、文字列はパスを推測します。

2.10.3 その他の新しいアクションのためのルートの追加

on: :newのショートカットを使用して別の新しいアクションを追加するには、次のようにします。

resources :comments do
  get 'preview', on: :new
end

これにより、GETで/comments/new/previewなどのパスが認識され、CommentsControllerpreviewアクションにルーティングされます。また、preview_new_comment_urlpreview_new_comment_pathのルートヘルパーも作成されます。

リソースフルなルートに多くの追加アクションを追加している場合は、別のリソースの存在を隠している可能性があるため、停止して自分自身に尋ねる時が来たと考えてください。

3 リソースフルでないルート

リソースルーティングに加えて、Railsは任意のURLをアクションにルーティングするための強力なサポートを提供しています。ここでは、リソースフルなルーティングによって自動的に生成されるルートグループはありません。代わりに、アプリケーション内で各ルートを個別に設定します。

通常はリソースフルなルーティングを使用するべきですが、シンプルなルーティングの方が適している場合も多くあります。リソースフルなフレームワークにアプリケーションの最後の一部を無理にはめ込む必要はありません。 特に、シンプルなルーティングにより、既存のURLを新しいRailsアクションにマッピングすることが非常に簡単になります。

3.1 バウンドパラメータ

通常のルートを設定する際に、Railsは受信したHTTPリクエストの一部としてマップするシンボルのシリーズを指定します。例えば、次のルートを考えてみてください。

get 'photos(/:id)', to: 'photos#display'

このルートによって処理される受信したリクエストが /photos/1 の場合(ファイル内の他のルートと一致しなかったため)、結果は PhotosControllerdisplay アクションを呼び出し、最終パラメータ "1"params[:id] として利用できるようになります。このルートは、オプションのパラメータである :id を括弧で囲んでいるため、/photos という受信したリクエストも PhotosController#display にルーティングします。

3.2 ダイナミックセグメント

通常のルート内には、任意の数のダイナミックセグメントを設定できます。セグメントは、params の一部としてアクションで利用できます。次のようなルートを設定した場合、

get 'photos/:id/:user_id', to: 'photos#show'

/photos/1/2 というパスが PhotosControllershow アクションにディスパッチされます。params[:id]"1" となり、params[:user_id]"2" となります。

ダイナミックセグメントはデフォルトではドットを受け付けません。これは、ドットがフォーマットされたルートの区切り文字として使用されるためです。ダイナミックセグメント内でドットを使用する必要がある場合は、これを上書きする制約を追加してください。例えば、id: /[^\/]+/ はスラッシュ以外の任意の文字を許可します。

3.3 スタティックセグメント

セグメントの前にコロンを付けずにルートを作成することで、スタティックセグメントを指定できます。

get 'photos/:id/with_user/:user_id', to: 'photos#show'

このルートは /photos/1/with_user/2 のようなパスに応答します。この場合、params{ controller: 'photos', action: 'show', id: '1', user_id: '2' } となります。

3.4 クエリ文字列

params には、クエリ文字列からのパラメータも含まれます。例えば、次のルートを持つ場合、

get 'photos/:id', to: 'photos#show'

/photos/1?user_id=2 というパスが Photos コントローラーの show アクションにディスパッチされます。params{ controller: 'photos', action: 'show', id: '1', user_id: '2' } となります。

3.5 デフォルトの定義

ルートにデフォルトを定義するには、:defaults オプションにハッシュを指定します。これは、ダイナミックセグメントとして指定しないパラメータにも適用されます。例えば、

get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }

Railsは photos/12PhotosControllershow アクションにマッチさせ、params[:format]"jpg" に設定します。

また、defaults ブロックを使用して複数のアイテムのデフォルトを定義することもできます。

defaults format: :json do
  resources :photos
end

クエリパラメータを介してデフォルトを上書きすることはできません。これはセキュリティ上の理由からです。URLパス内のダイナミックセグメントを置換することでのみ、デフォルトを上書きできます。

3.6 ルートの名前付け

:as オプションを使用して、任意のルートに名前を指定できます。

get 'exit', to: 'sessions#destroy', as: :logout

これにより、アプリケーション内の名前付きルートヘルパーとして logout_pathlogout_url が作成されます。logout_path を呼び出すと /exit が返されます。

また、これを使用して、カスタムルートがリソースによって定義されたルーティングメソッドを上書きすることもできます。カスタムルートをリソースの定義の前に配置することで、次のようにします。

get ':username', to: 'users#show', as: :user
resources :users

これにより、コントローラー、ヘルパー、ビューで利用できる user_path メソッドが定義され、/bob のようなルートに移動します。UsersControllershow アクション内では、params[:username] にユーザーのユーザー名が含まれます。パラメータ名を :username 以外にしたい場合は、ルート定義内の :username を変更してください。

3.7 HTTP動詞の制約

一般的には、getpostputpatchdelete メソッドを使用して、ルートを特定の動詞に制約するべきです。match メソッドを :via オプションとともに使用して、複数の動詞に一致させることもできます。

match 'photos', to: 'photos#show', via: [:get, :post]

via: :all を使用して、すべての動詞を特定のルートに一致させることもできます。

match 'photos', to: 'photos#show', via: :all

GETPOST の両方のリクエストを単一のアクションにルーティングすることにはセキュリティ上の問題があります。一般的には、良い理由がない限り、すべての動詞をアクションにルーティングすることは避けるべきです。

Railsの GET はCSRFトークンをチェックしません。GET リクエストからデータベースに書き込むことは絶対に行わないでください。詳細については、CSRF対策のセキュリティガイドを参照してください。

3.8 セグメントの制約

動的セグメントのフォーマットを強制するために、:constraints オプションを使用することができます。

get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }

このルートは /photos/A12345 のようなパスにマッチしますが、/photos/893 のようなパスにはマッチしません。同じルートをより簡潔に表現することもできます。

get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/

:constraints は正規表現を受け取りますが、正規表現のアンカーは使用できません。例えば、次のルートは機能しません。

get '/:id', to: 'articles#show', constraints: { id: /^\d/ }

ただし、すべてのルートは開始と終了でアンカーが設定されているため、アンカーを使用する必要はありません。

例えば、次のルートは、常に数字で始まる 1-hello-world のような articlesto_param 値と、数字で始まらない david のような usersto_param 値が同じルート名前空間を共有できるようにします。

get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
get '/:username', to: 'users#show'

3.9 リクエストベースの制約

リクエストオブジェクトの任意のメソッドを基にルートを制約することもできます。

セグメントの制約と同じように、リクエストベースの制約を指定します。

get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }

また、constraints ブロックを使用して制約を指定することもできます。

namespace :admin do
  constraints subdomain: 'admin' do
    resources :photos
  end
end

注意: リクエストの制約は、ハッシュのキーと同じ名前のメソッドを Request オブジェクト 上で呼び出し、その戻り値とハッシュの値を比較することで動作します。したがって、制約の値は対応する Request オブジェクトのメソッドの戻り値の型と一致する必要があります。例えば: constraints: { subdomain: 'api' } は、予想どおりに api サブドメインにマッチします。ただし、シンボルを使用した constraints: { subdomain: :api } はマッチしません。なぜなら、request.subdomain は文字列 'api' を返すからです。

注意: format 制約には例外があります。これは Request オブジェクトのメソッドですが、すべてのパスに暗黙のオプションパラメータとして存在します。セグメントの制約が優先され、format 制約はハッシュを介して強制された場合にのみ適用されます。例えば、get 'foo', constraints: { format: 'json' }GET /foo にマッチします。なぜなら、デフォルトではフォーマットはオプションです。ただし、get 'foo', constraints: lambda { |req| req.format == :json } のように lambda を使用 すると、明示的な JSON リクエストのみがルートにマッチします。

3.10 高度な制約

より高度な制約がある場合は、Rails が使用する matches? メソッドに応答するオブジェクトを指定することができます。例えば、制限されたリストのすべてのユーザーを RestrictedListController にルーティングしたい場合、次のようにすることができます。

class RestrictedListConstraint
  def initialize
    @ips = RestrictedList.retrieve_ips
  end

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

Rails.application.routes.draw do
  get '*path', to: 'restricted_list#index',
    constraints: RestrictedListConstraint.new
end

また、lambda を使用して制約を指定することもできます。

Rails.application.routes.draw do
  get '*path', to: 'restricted_list#index',
    constraints: lambda { |request| RestrictedList.retrieve_ips.include?(request.remote_ip) }
end

matches? メソッドと lambda の両方が request オブジェクトを引数として受け取ります。

3.10.1 ブロック形式での制約の指定

ブロック形式で制約を指定することもできます。これは、複数のルートに同じルールを適用する必要がある場合に便利です。例えば:

class RestrictedListConstraint
  # ...上記の例と同じ
end

Rails.application.routes.draw do
  constraints(RestrictedListConstraint.new) do
    get '*path', to: 'restricted_list#index'
    get '*other-path', to: 'other_restricted_list#index'
  end
end

lambda を使用することもできます。

Rails.application.routes.draw do
  constraints(lambda { |request| RestrictedList.retrieve_ips.include?(request.remote_ip) }) do
    get '*path', to: 'restricted_list#index'
    get '*other-path', to: 'other_restricted_list#index'
  end
end

3.11 ルートのグロビングとワイルドカードセグメント

ルートのグロビングは、特定のパラメータがルートの残りの部分にマッチするように指定する方法です。例えば:

get 'photos/*other', to: 'photos#unknown'

このルートは photos/12/photos/long/path/to/12 にマッチし、params[:other] には "12""long/path/to/12" が設定されます。星印で始まるセグメントは「ワイルドカードセグメント」と呼ばれます。

ワイルドカードセグメントはルートのどこにでも現れることができます。例えば:

get 'books/*section/:title', to: 'books#show'

books/some/section/last-words-a-memoir にマッチし、params[:section]'some/section'params[:title]'last-words-a-memoir' になります。

技術的には、ルートには複数のワイルドカードセグメントがある場合もあります。マッチャーはセグメントをパラメータに直感的に割り当てます。例えば:

get '*a/foo/*b', to: 'test#index'

zoo/woo/foo/bar/baz にマッチし、params[:a]'zoo/woo'params[:b]'bar/baz' になります。 注意:'/foo/bar.json'をリクエストすると、params[:pages]はJSON形式のリクエストフォーマットで'foo/bar'となります。古い3.0.xの動作を復元するには、次のようにformat: falseを指定することができます。

get '*pages', to: 'pages#show', format: false

注意:フォーマットセグメントを省略できないようにするには、format: trueを指定することができます。

get '*pages', to: 'pages#show', format: true

3.12 リダイレクト

ルーターでredirectヘルパーを使用して、任意のパスを別のパスにリダイレクトすることができます。

get '/stories', to: redirect('/articles')

マッチしたパスの動的セグメントをパスに再利用してリダイレクトすることもできます。

get '/stories/:name', to: redirect('/articles/%{name}')

redirectにはブロックを指定することもできます。このブロックは、シンボル化されたパスパラメータとリクエストオブジェクトを受け取ります。

get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }

デフォルトのリダイレクトは301「Moved Permanently」リダイレクトです。一部のウェブブラウザやプロキシサーバーは、このタイプのリダイレクトをキャッシュし、古いページにアクセスできなくする場合があります。レスポンスステータスを変更するには、:statusオプションを使用できます。

get '/stories/:name', to: redirect('/articles/%{name}', status: 302)

これらの場合、先頭のホスト(http://www.example.com)を指定しない場合、Railsは現在のリクエストからこれらの詳細を取得します。

3.13 Rackアプリケーションへのルーティング

'articles#index'のような文字列は、ArticlesControllerindexアクションに対応しますが、マッチャーのエンドポイントとしてRackアプリケーションを指定することもできます。

match '/application.js', to: MyRackApp, via: :all

MyRackAppcallに応答し、[status, headers, body]を返す限り、ルーターはRackアプリケーションとアクションの違いを認識しません。これは、via: :allの適切な使用例です。Rackアプリケーションが適切と考えるすべての動詞を処理できるようにするためです。

注意:興味がある場合、'articles#index'は実際にはArticlesController.action(:index)に展開されます。これは有効なRackアプリケーションを返します。

注意:プロック/ラムダはcallに応答するオブジェクトであるため、非常にシンプルなルート(たとえば、ヘルスチェック用)をインラインで実装することができます:
get '/health', to: ->(env) { [204, {}, ['']] }

マッチャーのエンドポイントとしてRackアプリケーションを指定する場合、受信アプリケーションではルートが変更されないことに注意してください。次のルートでは、Rackアプリケーションはルートが/adminであることを想定する必要があります。

match '/admin', to: AdminApp, via: :all

Rackアプリケーションが代わりにルートパスでリクエストを受け取るようにしたい場合は、mountを使用します。

mount AdminApp, at: '/admin'

3.14 rootの使用

rootメソッドを使用して、Railsが'/'をどのアクションにルーティングするかを指定できます。

root to: 'pages#main'
root 'pages#main' # 上記のショートカット

rootルートはファイルの先頭に配置する必要があります。最も一般的なルートであり、最初にマッチする必要があるためです。

注意:rootルートはGETリクエストのみをアクションにルーティングします。

ネームスペースやスコープ内でもrootを使用することができます。例:

namespace :admin do
  root to: "admin#index"
end

root to: "home#index"

3.15 Unicode文字ルート

Unicode文字ルートを直接指定することができます。例:

get 'こんにちは', to: 'welcome#index'

3.16 直接ルート

directを呼び出すことで、直接カスタムURLヘルパーを作成することができます。例:

direct :homepage do
  "https://rubyonrails.org"
end

# >> homepage_url
# => "https://rubyonrails.org"

ブロックの戻り値は、url_forメソッドの有効な引数である必要があります。有効な文字列URL、ハッシュ、配列、Active Modelのインスタンス、またはActive Modelクラスを渡すことができます。

direct :commentable do |model|
  [ model, anchor: model.dom_id ]
end

direct :main do
  { controller: 'pages', action: 'index', subdomain: 'www' }
end

3.17 resolveの使用

resolveメソッドを使用すると、モデルのポリモーフィックなマッピングをカスタマイズすることができます。例:

resource :basket

resolve("Basket") { [:basket] }
<%= form_with model: @basket do |form| %>
  <!-- basket form -->
<% end %>

これにより、通常の/baskets/:idの代わりに単数形のURL /basketが生成されます。

4 リソースフルルートのカスタマイズ

resourcesによって生成されるデフォルトのルートとヘルパーは通常うまく機能しますが、何らかの方法でカスタマイズする必要がある場合があります。Railsでは、リソースフルヘルパーのほとんどの一般的な部分をカスタマイズすることができます。

4.1 コントローラの指定

:controllerオプションを使用すると、リソースに使用するコントローラを明示的に指定できます。例えば:

resources :photos, controller: 'images'

これにより、/photosで始まるパスは認識されますが、Imagesコントローラにルーティングされます:

HTTPメソッド パス コントローラ#アクション 名前付きルートヘルパー
GET /photos images#index photos_path
GET /photos/new images#new new_photo_path
POST /photos images#create photos_path
GET /photos/:id images#show photo_path(:id)
GET /photos/:id/edit images#edit edit_photo_path(:id)
PATCH/PUT /photos/:id images#update photo_path(:id)
DELETE /photos/:id images#destroy photo_path(:id)

注意:このリソースのパスを生成するためにphotos_pathnew_photo_pathなどを使用してください。

ネームスペース付きのコントローラの場合、ディレクトリ表記を使用できます。例えば:

resources :user_permissions, controller: 'admin/user_permissions'

これはAdmin::UserPermissionsコントローラにルーティングされます。

注意:ディレクトリ表記のみがサポートされています。Rubyの定数表記(例:controller: 'Admin::UserPermissions')でコントローラを指定すると、ルーティングの問題が発生し、警告が表示されます。

4.2 制約の指定

:constraintsオプションを使用して、暗黙のidに必要な形式を指定できます。例えば:

resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }

この宣言は、:idパラメータが指定された正規表現と一致するように制約します。したがって、この場合、ルーターは/photos/1をこのルートに一致させません。代わりに、/photos/RR27が一致します。

ブロック形式を使用して、複数のルートに単一の制約を適用することもできます。

constraints(id: /[A-Z][A-Z][0-9]+/) do
  resources :photos
  resources :accounts
end

注意:もちろん、このコンテキストで非リソースフルなルートで使用できるより高度な制約を使用することもできます。

TIP:デフォルトでは、:idパラメータはドットを受け付けません。これは、ドットがフォーマットされたルートのセパレータとして使用されるためです。:id内でドットを使用する必要がある場合は、これを上書きする制約を追加します。たとえば、id: /[^\/]+/はスラッシュ以外の任意の文字を許可します。

4.3 名前付きルートヘルパーの上書き

:asオプションを使用すると、名前付きルートヘルパーの通常の命名を上書きできます。例えば:

resources :photos, as: 'images'

これにより、/photosで始まるパスは認識され、リクエストはPhotosControllerにルーティングされますが、ヘルパーの名前に:asオプションの値が使用されます。

HTTPメソッド パス コントローラ#アクション 名前付きルートヘルパー
GET /photos photos#index images_path
GET /photos/new photos#new new_image_path
POST /photos photos#create images_path
GET /photos/:id photos#show image_path(:id)
GET /photos/:id/edit photos#edit edit_image_path(:id)
PATCH/PUT /photos/:id photos#update image_path(:id)
DELETE /photos/:id photos#destroy image_path(:id)

4.4 newおよびeditセグメントの上書き

:path_namesオプションを使用すると、自動生成されたパスのnewおよびeditセグメントを上書きできます。

resources :photos, path_names: { new: 'make', edit: 'change' }

これにより、以下のようなパスがルーティングで認識されます:

/photos/make
/photos/1/change

注意:このオプションによって実際のアクション名は変更されません。表示される2つのパスは、依然としてnewおよびeditアクションにルーティングされます。

TIP:このオプションをすべてのルートに一貫して適用したい場合は、以下のようにスコープを使用できます:

scope path_names: { new: 'make' } do
  # 他のルート
end

4.5 名前付きルートヘルパーのプレフィックス

:asオプションを使用して、Railsがルートに対して生成する名前付きルートヘルパーのプレフィックスを指定できます。このオプションを使用して、パススコープを使用するルート間の名前の衝突を防ぐことができます。例えば:

scope 'admin' do
  resources :photos, as: 'admin_photos'
end

resources :photos

これにより、/admin/photosのルートヘルパーはphotos_pathnew_photos_pathなどからadmin_photos_pathnew_admin_photo_pathなどに変更されます。スコープ付きのresources :photosas: 'admin_photos'を追加しない場合、スコープのないresources :photosにはルートヘルパーがありません。

ルートヘルパーのグループにプレフィックスを付けるには、scope:asを使用します:

scope 'admin', as: 'admin' do
  resources :photos, :accounts
end

resources :photos, :accounts

前述のように、/adminスコープのリソースヘルパーはadmin_photos_pathおよびadmin_accounts_pathに変更され、スコープのないリソースはphotos_pathおよびaccounts_pathを使用できます。 注意:namespaceスコープは、:asだけでなく、:module:pathの接頭辞も自動的に追加されます。

4.5.1 パラメータスコープ

名前付きパラメータでルートに接頭辞を付けることができます:

scope ':account_id', as: 'account', constraints: { account_id: /\d+/ } do
  resources :articles
end

これにより、/1/articles/9などのパスが提供され、コントローラ、ヘルパー、ビューでパスのaccount_id部分をparams[:account_id]として参照することができます。

また、account_で接頭辞が付いたパスとURLのヘルパーも生成されます。これには、通常どおりオブジェクトを渡すことができます:

account_article_path(@account, @article) # => /1/article/9
url_for([@account, @article])            # => /1/article/9
form_with(model: [@account, @article])   # => <form action="/1/article/9" ...>

制約を使用して、スコープをIDのような文字列にマッチするように制限しています。制約を必要に応じて変更するか、完全に省略することができます。:asオプションも厳密に必要ではありませんが、それがないと、url_for([@account, @article])form_withなどのurl_forに依存する他のヘルパーを評価するときにRailsがエラーを発生させます。

4.6 作成されるルートの制限

デフォルトでは、RailsはアプリケーションのすべてのRESTfulルートに対して7つのデフォルトアクション(indexshownewcreateeditupdatedestroy)のルートを作成します。:onlyオプションと:exceptオプションを使用してこの動作を細かく調整することができます。:onlyオプションは、指定したルートのみを作成するようにRailsに指示します:

resources :photos, only: [:index, :show]

これにより、/photosへのGETリクエストは成功しますが、/photosへのPOSTリクエスト(通常はcreateアクションにルーティングされる)は失敗します。

exceptオプションは、Railsが作成しないルートまたはルートのリストを指定します:

resources :photos, except: :destroy

この場合、Railsはdestroyのルート(/photos/:idへのDELETEリクエスト)を除くすべての通常のルートを作成します。

アプリケーションにRESTfulルートが多い場合、必要なルートのみを生成するためにonlyexceptを使用すると、メモリ使用量を削減し、ルーティングプロセスを高速化することができます。

4.7 翻訳されたパス

scopeを使用すると、resourcesによって生成されるパス名を変更することができます:

scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
  resources :categories, path: 'kategorien'
end

これにより、RailsはCategoriesControllerへのルートを作成します。

HTTPメソッド パス コントローラ#アクション 名前付きルートヘルパー
GET /kategorien categories#index categories_path
GET /kategorien/neu categories#new new_category_path
POST /kategorien categories#create categories_path
GET /kategorien/:id categories#show category_path(:id)
GET /kategorien/:id/bearbeiten categories#edit edit_category_path(:id)
PATCH/PUT /kategorien/:id categories#update category_path(:id)
DELETE /kategorien/:id categories#destroy category_path(:id)

4.8 単数形のオーバーライド

リソースの単数形をオーバーライドしたい場合は、inflectionsを介してインフレクタに追加のルールを追加する必要があります:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'tooth', 'teeth'
end

4.9 ネストされたリソースでの:asの使用

:asオプションは、ネストされたルートヘルパーで自動生成されるリソースの名前を上書きします。例:

resources :magazines do
  resources :ads, as: 'periodical_ads'
end

これにより、magazine_periodical_ads_urledit_magazine_periodical_ad_pathなどのルーティングヘルパーが作成されます。

4.10 名前付きルートパラメータのオーバーライド

:paramオプションは、デフォルトのリソース識別子:id(ルートを生成するために使用される動的セグメントの名前)を上書きします。コントローラからそのセグメントにアクセスするには、params[<:param>]を使用します。

resources :videos, param: :identifier
    videos GET  /videos(.:format)                  videos#index
           POST /videos(.:format)                  videos#create
 new_video GET  /videos/new(.:format)              videos#new
edit_video GET  /videos/:identifier/edit(.:format) videos#edit
Video.find_by(identifier: params[:identifier])

関連するモデルのActiveRecord::Base#to_paramをオーバーライドしてURLを構築することもできます:

class Video < ApplicationRecord
  def to_param
    identifier
  end
end
video = Video.find_by(identifier: "Roman-Holiday")
edit_video_path(video) # => "/videos/Roman-Holiday/edit"

5 非常に大きなルートファイルを複数の小さなファイルに分割する

数千のルートを持つ大規模なアプリケーションで作業する場合、単一のconfig/routes.rbファイルは扱いにくく、読みにくくなることがあります。

Railsには、drawマクロを使用して巨大な単一のroutes.rbファイルを複数の小さなファイルに分割する方法があります。

管理エリアのすべてのルートを含むadmin.rbルート、API関連のリソース用の別のapi.rbファイルなどを持つことができます。

# config/routes.rb

Rails.application.routes.draw do
  get 'foo', to: 'foo#bar'

  draw(:admin) # `config/routes/admin.rb`にある別のルートファイルを読み込みます
end
# config/routes/admin.rb

namespace :admin do
  resources :comments
end

Rails.application.routes.drawブロック内でdraw(:admin)を呼び出すと、引数として与えられた名前と同じ名前のルートファイルを読み込もうとします(この例ではadmin.rb)。ファイルはconfig/routesディレクトリまたはそのサブディレクトリ(つまり、config/routes/admin.rbまたはconfig/routes/external/admin.rb)に配置する必要があります。

admin.rbルーティングファイル内では通常のルーティングDSLを使用できますが、メインのconfig/routes.rbファイルと同様にRails.application.routes.drawブロックで囲む必要はありません。

5.1 本当に必要な場合以外はこの機能を使用しないでください

複数のルーティングファイルを持つことは、見つけやすさや理解しやすさを損ないます。ほとんどのアプリケーションでは、数百のルートを持つ場合でも、開発者が単一のルーティングファイルを持つ方が簡単です。RailsのルーティングDSLは、namespacescopeを使用してルートを整理する方法を既に提供しています。

6 ルートの検査とテスト

Railsには、ルートを検査およびテストするための機能が用意されています。

6.1 現在のルートの一覧表示

アプリケーションで利用可能なすべてのルートの完全な一覧を取得するには、サーバーがdevelopment環境で実行されている状態でブラウザでhttp://localhost:3000/rails/info/routesを開きます。または、ターミナルでbin/rails routesコマンドを実行して同じ出力を生成することもできます。

どちらの方法でも、config/routes.rbに記載されている順序と同じ順序ですべてのルートがリストされます。各ルートには以下の情報が表示されます。

  • ルート名(ある場合)
  • 使用されるHTTP動詞(ルートがすべての動詞に応答しない場合)
  • マッチするURLパターン
  • ルートのルーティングパラメータ

たとえば、RESTfulなルートのbin/rails routes出力の一部を以下に示します。

    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

また、--expandedオプションを使用して展開されたテーブル形式のモードをオンにすることもできます。

$ bin/rails routes --expanded

--[ ルート 1 ]----------------------------------------------------
Prefix            | users
Verb              | GET
URI               | /users(.:format)
Controller#Action | users#index
--[ ルート 2 ]----------------------------------------------------
Prefix            |
Verb              | POST
URI               | /users(.:format)
Controller#Action | users#create
--[ ルート 3 ]----------------------------------------------------
Prefix            | new_user
Verb              | GET
URI               | /users/new(.:format)
Controller#Action | users#new
--[ ルート 4 ]----------------------------------------------------
Prefix            | edit_user
Verb              | GET
URI               | /users/:id/edit(.:format)
Controller#Action | users#edit

grepオプションを使用してルートを検索することもできます。これにより、URLヘルパーメソッド名、HTTP動詞、またはURLパスと部分一致するルートが出力されます。

$ bin/rails routes -g new_comment
$ bin/rails routes -g POST
$ bin/rails routes -g admin

特定のコントローラにマップされるルートのみを表示したい場合は、-cオプションを使用します。

$ bin/rails routes -c users
$ bin/rails routes -c admin/users
$ bin/rails routes -c Comments
$ bin/rails routes -c Articles::CommentsController

bin/rails routesの出力は、出力行が折り返されないようにターミナルウィンドウの幅を広げると読みやすくなります。

6.2 ルートのテスト

ルートは、アプリケーションの他の部分と同様に、テスト戦略に含めるべきです。Railsには、ルートのテストをより簡単にするための3つの組み込みアサーションが用意されています。

6.2.1 assert_generatesアサーション

assert_generatesは、特定のオプションが特定のパスを生成することをアサートし、デフォルトのルートまたはカスタムルートと共に使用できます。例えば:

assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/about', controller: 'pages', action: 'about'

6.2.2 assert_recognizesアサーション

assert_recognizesは、assert_generatesの逆です。与えられたパスが認識され、アプリケーション内の特定の場所にルーティングされることをアサートします。例えば:

assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')

:method引数を指定してHTTP動詞を指定することもできます。

assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos', method: :post })

6.2.3 assert_routingアサーション

assert_routingアサーションは、パスがオプションを生成し、オプションがパスを生成することの両方をチェックします。つまり、assert_generatesassert_recognizesの機能を組み合わせています。

assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })

フィードバック

このガイドの品質向上にご協力ください。

タイポや事実の誤りを見つけた場合は、ぜひ貢献してください。 開始するには、ドキュメントへの貢献セクションを読んでください。

不完全なコンテンツや最新でない情報も見つかるかもしれません。 メインのドキュメントに不足しているドキュメントを追加してください。 修正済みかどうかは、まずEdge Guidesを確認してください。 スタイルと規約については、Ruby on Rails Guides Guidelinesを確認してください。

修正すべき点を見つけたが、自分で修正できない場合は、 問題を報告してください

そして最後に、Ruby on Railsのドキュメントに関するあらゆる議論は、公式のRuby on Railsフォーラムで大歓迎です。