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
への単一の呼び出しで、index
、show
、new
、edit
、create
、update
、destroy
アクションに必要なすべてのルートを宣言できます。
2.1 ウェブ上のリソース
ブラウザは、特定のHTTPメソッド(GET
、POST
、PATCH
、PUT
、DELETE
など)を使用して、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 :photo
とresources :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
これにより、articles
とcomments
コントローラのそれぞれにいくつかのルートが作成されます。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/articles
をArticlesController
(Admin::
モジュール接頭辞なし)にルーティングしたい場合は、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_url
やedit_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の代わりにMagazine
とAd
のインスタンスを渡すことができます。
<%= link_to '広告の詳細', magazine_ad_path(@magazine, @ad) %>
また、url_for
をオブジェクトのセットとともに使用することもできます。Railsは自動的にどのルートを使用するかを判断します。
<%= link_to '広告の詳細', url_for([@magazine, @ad]) %>
この場合、Railsは@magazine
がMagazine
であり、@ad
がAd
であることを認識し、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
が認識され、PhotosController
のpreview
アクションにルーティングされます。リソースIDの値はparams[:id]
に渡されます。また、preview_photo_url
とpreview_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_url
とpreview_photo_path
からphoto_preview_url
とphoto_preview_path
に名前が変更されます。
2.10.2 コレクションルートの追加
collection
ブロックを使用してコレクションにルートを追加します。
resources :photos do
collection do
get 'search'
end
end
これにより、GETで/photos/search
などのパスが認識され、PhotosController
のsearch
アクションにルーティングされます。また、search_photos_url
とsearch_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
などのパスが認識され、CommentsController
のpreview
アクションにルーティングされます。また、preview_new_comment_url
とpreview_new_comment_path
のルートヘルパーも作成されます。
リソースフルなルートに多くの追加アクションを追加している場合は、別のリソースの存在を隠している可能性があるため、停止して自分自身に尋ねる時が来たと考えてください。
3 リソースフルでないルート
リソースルーティングに加えて、Railsは任意のURLをアクションにルーティングするための強力なサポートを提供しています。ここでは、リソースフルなルーティングによって自動的に生成されるルートグループはありません。代わりに、アプリケーション内で各ルートを個別に設定します。
通常はリソースフルなルーティングを使用するべきですが、シンプルなルーティングの方が適している場合も多くあります。リソースフルなフレームワークにアプリケーションの最後の一部を無理にはめ込む必要はありません。 特に、シンプルなルーティングにより、既存のURLを新しいRailsアクションにマッピングすることが非常に簡単になります。
3.1 バウンドパラメータ
通常のルートを設定する際に、Railsは受信したHTTPリクエストの一部としてマップするシンボルのシリーズを指定します。例えば、次のルートを考えてみてください。
get 'photos(/:id)', to: 'photos#display'
このルートによって処理される受信したリクエストが /photos/1
の場合(ファイル内の他のルートと一致しなかったため)、結果は PhotosController
の display
アクションを呼び出し、最終パラメータ "1"
を params[:id]
として利用できるようになります。このルートは、オプションのパラメータである :id
を括弧で囲んでいるため、/photos
という受信したリクエストも PhotosController#display
にルーティングします。
3.2 ダイナミックセグメント
通常のルート内には、任意の数のダイナミックセグメントを設定できます。セグメントは、params
の一部としてアクションで利用できます。次のようなルートを設定した場合、
get 'photos/:id/:user_id', to: 'photos#show'
/photos/1/2
というパスが PhotosController
の show
アクションにディスパッチされます。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/12
を PhotosController
の show
アクションにマッチさせ、params[:format]
を "jpg"
に設定します。
また、defaults
ブロックを使用して複数のアイテムのデフォルトを定義することもできます。
defaults format: :json do
resources :photos
end
クエリパラメータを介してデフォルトを上書きすることはできません。これはセキュリティ上の理由からです。URLパス内のダイナミックセグメントを置換することでのみ、デフォルトを上書きできます。
3.6 ルートの名前付け
:as
オプションを使用して、任意のルートに名前を指定できます。
get 'exit', to: 'sessions#destroy', as: :logout
これにより、アプリケーション内の名前付きルートヘルパーとして logout_path
と logout_url
が作成されます。logout_path
を呼び出すと /exit
が返されます。
また、これを使用して、カスタムルートがリソースによって定義されたルーティングメソッドを上書きすることもできます。カスタムルートをリソースの定義の前に配置することで、次のようにします。
get ':username', to: 'users#show', as: :user
resources :users
これにより、コントローラー、ヘルパー、ビューで利用できる user_path
メソッドが定義され、/bob
のようなルートに移動します。UsersController
の show
アクション内では、params[:username]
にユーザーのユーザー名が含まれます。パラメータ名を :username
以外にしたい場合は、ルート定義内の :username
を変更してください。
3.7 HTTP動詞の制約
一般的には、get
、post
、put
、patch
、delete
メソッドを使用して、ルートを特定の動詞に制約するべきです。match
メソッドを :via
オプションとともに使用して、複数の動詞に一致させることもできます。
match 'photos', to: 'photos#show', via: [:get, :post]
via: :all
を使用して、すべての動詞を特定のルートに一致させることもできます。
match 'photos', to: 'photos#show', via: :all
GET
と POST
の両方のリクエストを単一のアクションにルーティングすることにはセキュリティ上の問題があります。一般的には、良い理由がない限り、すべての動詞をアクションにルーティングすることは避けるべきです。
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
のような articles
の to_param
値と、数字で始まらない david
のような users
の to_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'
のような文字列は、ArticlesController
のindex
アクションに対応しますが、マッチャーのエンドポイントとしてRackアプリケーションを指定することもできます。
match '/application.js', to: MyRackApp, via: :all
MyRackApp
がcall
に応答し、[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_path
、new_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_path
、new_photos_path
などからadmin_photos_path
、new_admin_photo_path
などに変更されます。スコープ付きのresources :photos
にas: '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つのデフォルトアクション(index
、show
、new
、create
、edit
、update
、destroy
)のルートを作成します。: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ルートが多い場合、必要なルートのみを生成するためにonly
とexcept
を使用すると、メモリ使用量を削減し、ルーティングプロセスを高速化することができます。
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_url
やedit_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は、namespace
やscope
を使用してルートを整理する方法を既に提供しています。
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_generates
とassert_recognizes
の機能を組み合わせています。
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
フィードバック
このガイドの品質向上にご協力ください。
タイポや事実の誤りを見つけた場合は、ぜひ貢献してください。 開始するには、ドキュメントへの貢献セクションを読んでください。
不完全なコンテンツや最新でない情報も見つかるかもしれません。 メインのドキュメントに不足しているドキュメントを追加してください。 修正済みかどうかは、まずEdge Guidesを確認してください。 スタイルと規約については、Ruby on Rails Guides Guidelinesを確認してください。
修正すべき点を見つけたが、自分で修正できない場合は、 問題を報告してください。
そして最後に、Ruby on Railsのドキュメントに関するあらゆる議論は、公式のRuby on Railsフォーラムで大歓迎です。