Top / ruby / rails / RailsGuidesをゆっくり和訳してみたよ / Rails Routing from the Outside In

ruby/rails/RailsGuidesをゆっくり和訳してみたよ/Rails Routing from the Outside In

このエントリーをはてなブックマークに追加 Delicious Check
更新: 2011-05-25 (水) 02:06:21 (362d)

原文

http://guides.rubyonrails.org/routing.html

裏の裏までルーティング(Rails Routing from the Outside In)

このガイドではユーザー向けのRails のルーティング機能を学ぶことができます。
このガイドを読んだ後、以下のことができるようになります:

  • routes.rb 内のコードの理解
  • お馴染みのリソースフルなスタイルか match メソッドを使った、自身のルーティングの構築
  • 何のパラメーターを、アクションが受け取ることを期待するかの識別
  • ルーティングヘルパを使った、自動的なパスや URL の作成
  • 制約や Rack 終点のような、高度なテクニックの使用

1 ルーターの目的(The Purpose of the Rails Router)

ルーターは URL を認識し、コントローラーのアクションにディスパッチ(送出)します。
それはまた、パスと URL を生成し、ビュー内に文字列をハードコードする必要を回避します。

1.1 コードに URL を繋ぐ(Connecting URLs to Code)

Rails アプリケーションが、入ってくるリクエストを受け取った時、

GET /patients/17

それがコントローラーのアクションにマッチするか、ルーターに問い合わせます。
もし最初のマッチするルーティングが、

match "/patients/:id" => "patients#show"

なら、リクエストは、 patients コントローラーの show アクションに、 params 内の { :id => "17" } とともにディスパッチされます。

1.2 コードからパスと URL の生成(Generating Paths and URLs from Code)

パスと URL の生成も出来ます。
アプリケーションがこのコードを格納しているなら:

@patient = Patient.find(17)
<%= link_to "Patient Record", patients_path(@patient.id) %>

ルーターは、 /patients/17 を生成するでしょう。
これhビューの脆弱性を軽減し、コードを簡単に理解出来るようにするでしょう。

2 リソースルーティング: Rails のデフォルト(Resource Routing: the Rails Default)

リソースルーティングは、与えられたリソースフルなコントローラーのための共通ルーティングの全ての宣言を迅速に、出来るようにします。
index 、 show 、 new 、 edit 、 create 、 update 、 destroy アクションのための分割されたルーティングの宣言の代わりに、
リソースフルなルーティングが、単一行のコード内で宣言します。

2.1 ウェブ上のリソース(Resources on the Web)

ブラウザは、GET 、 POST 、 PUT 、 DELETE のような特定のHTTP メソッドを使って
URL からリクエストを作ることにより、 Rails からページをリクエストします。
全てのメソッドは、リソース上の操作を実行するためのリクエストです。
リソースルーティングは、いくつかの関連するリクエストを単一のコントローラー内のアクションにマッピングします。

Rails アプリケーションが、入ってくるリクエストを受け取った時、

DELETE /photos/17

それがコントローラーのアクションにマッチするか、ルーターに問い合わせます。
もし最初のマッチするルーティングが、

resources :photos

なら、 Rails は、リクエストを、 photos コントローラーの destroy メソッドに、 params 内の { :id => "17" } とともにディスパッチするでしょう。

2.2 CRUD 、Verbs 、 Actions (CRUD, Verbs, and Actions)

Rails では、リソースフルルーティングは HTTP verbs と URL と コントローラーアクションの間のマッピングを提供します。
規約により、全てのアクションはまた、データベース内の 特定の CRUD 操作にマッピングされます。
ルーティングファイル内の、このような単一の登録は、

resources :photos 

アプリケーション内に7つの異なったルーティングを作成します、 Photos コントローラーの全てのマッピングは:

VerbPathaction目的
GET/photosindex全ての photo のリストを表示する
GET/photos/newnew新しい photo を作るための HTML フォームを返す
POST/photoscreate新しい photo の作成する
GET/photos/:idshow特定の photo の表示
GET/photos/:id/editeditphoto の編集のための HTML フォームを返す
PUT/photos/:idupdate特定の photo の更新
DELETE/photos/:iddestroy特定の photo の削除

2.3 パスと URL (Paths and URLs)

リソースフルルーティングの作成は、またアプリケーション内のコントローラーで、いくつかのヘルパを使えるようにするでしょう。
resources :photos の場合:

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

これらのヘルパ全ては、 対応する _url ヘルパ( photos_url のような)を持っていて、
それは現在のホスト、ポート、パスの接頭辞、の接頭辞を、同じパスにつけて返します。

ルーターは、内向きのリクエストにマッチするために HTTP verb や URL を使うので、4つの URL は7つの異なるアクションにマッピングします。

2.4 同時に複数のリソースの定義(Defining Multiple Resources at the Same Time)

一つ以上のリソースのためのルーティングを作成する必要があるなら、
単一の resources 呼び出しで全てを定義することによって、タイピングを少し減らすことが出来ます:

resources :photos, :books, :videos

これは、以下と全く同じように動きます。

resources :photos
resources :books
resources :videos

2.5 単一のリソース(Singular Resources)

時々、クライアントがいつも ID を参照すること無しに訪ねるリソースがあります。
一般的な例を挙げると、 /profile は現在ログインしているユーザーのプロフィールをいつも表示します。
この場合、 /profile ( /profile/:id では無く)に show アクションをマップするために単一のリソースを使います。

match "profile" => "users#show"

このリソースルーティングは

resource :geocoder

6つの異なるルーティングをアプリケーション内に作成します、全て Geocoders コントローラーへのマッピングです:

VerbPathaction目的
GET/geocoder/newnew新しい geocoder を作るための HTML フォームの返却
POST/geocodercreate新しい geocoder の作成
GET/geocodershow唯一の geocoder リソースのの表示
GET/geocoder/editeditgeocoder の編集のための HTML フォームの返却
PUT/geocoderupdate唯一の geocoder リソースの更新
DELETE/geocoderdestroygeocoder リソースの削除

単一のルーティング( /account )と複数系のルーティング( /accounts/45 )のために、
同じコントローラーを使いたいかもしれないので、単一のリソースは複数のコントローラーにマッピングします。

単一のリソースフルルーティングは、これらのヘルパを生成します:

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

複数形のリソースと同様に、 _url で終わる同じヘルパはまたホスト、ポート、パスの接頭辞を含むでしょう。

2.6 コントローラーのネームスペースとルーティング(Controller Namespaces and Routing)

ネームスペース下で、コントローラのグループを整理したいかもしれません。
最も一般的には、 Admin:: ネームスペース下で管理者コントローラーのいくつかをグループ化したいでしょう。
これらのコントローラーを app/controllers/admin ディレクトリ下に配置し、ルーター内でそれらを一緒にグループ化します:

namespace "admin" do
  resources :posts, :comments
end

これは posts コントローラーと、 comments コントローラーの全てに対するいくつかのルーティングを作るでしょう。
Admin::PostsController に対して、 Rails は、以下を作るでしょう:

VerbPathactionヘルパ
GET/admin/photosindexadmin_photos_path
GET/admin/photos/newnewnew_admin_photos_path
POST/admin/photoscreateadmin_photos_path
GET/admin/photos/:idshowadmin_photo_path(id)
GET/admin/photos/:id/editeditedit_admin_photo_path(id)
PUT/admin/photos/:idupdateadmin_photo_path(id)
DELETE/admin/photos/:iddestroyadmin_photo_path(id)

/photos (頭に /admin 無し)を Admin::PostsController にルーティングしたい場合、以下を使えます。

scope :module => "admin" do
  resources :posts, :comments
end

もしくは、単一の場合は、

resources :posts, :module => "admin"

/admin/photos を PostsController (頭に Admin:: module 無し)にルーティングしたい場合、以下を使えます。

scope "/admin" do
  resources :posts, :comments
end

もしくは、単一の場合は、

resources :posts, :path => "/admin"

これらのケース全てで、名前付きルーティングは scope を使用していない場合と同じく残っています。
最後のケースでは、次のパスが PostsController にマッピングされます:

VerbPathactionヘルパ
GET/admin/photosindexphotos_path
GET/admin/photos/newnewnew_photos_path
POST/admin/photoscreatephotos_path
GET/admin/photos/1showphoto_path(id)
GET/admin/photos/1/editeditedit_photo_path(id)
PUT/admin/photos/1updatephoto_path(id)
DELETE/admin/photos/1destroyphoto_path(id)

2.7 ネストしたリソース(Nested Resources)

他のリソースの論理的な子は、リソースを持っているのが一般的です。
例えば、アプリケーションがこれらのモデルを含んでいるとします:

class Magazine < ActiveRecord::Base
  has_many :ads
end

class Ad < ActiveRecord::Base
  belongs_to :magazine
end

ネストしたルーティングは、ルーティング内のこの関連を捉えられます。
この場合、このルーティングの宣言を含むことが出来ます:

resources :magazines do
  resources :ads
end

magazines のためのルーティングに加えて、この宣言は AdsController に ads をルーティングするでしょう。
ad URL は magazine を必要とします:

VerbPathactionヘルパ
GET/magazines/1/adsindex特定の magazine のための全ての ad のリストを表示
GET/magazines/1/ads/newnew特定の magazine に属している新しい ad を作るための HTML フォームの返却
POST/magazines/1/adscreate特定の magazine に属している新しい ad の作成
GET/magazines/1/ads/1show特定の magazine に属している特定の ad の表示
GET/magazines/1/ads/1/editedit特定の magazine に属している ad の編集のための HTML フォームを返却
PUT/magazines/1/ads/1update特定の magazine に属している特定の ad の更新
DELETE/magazines/1/ads/1destroy特定の magazine に属している特定の ad の削除

これは 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.8 オブジェクトからのパスと URL の作成(Creating Paths and URLs From Objects)

ルーティングヘルパの使用に加えて、 Rails はまたパラメーターの配列から、パスと URL を作成できます。
例えば、このルーティングのセットがあるとしましょう:

resources :magazines do
  resources :ads
end

magazine_ad_path を使う時、数値の ID の代わりに、 Magazine と Ad のインスタンスを渡せます。

<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>

また、オブジェクトのセットと url_for を使え、 Rails は自動的にあなたが必要なルーティングを決定するでしょう:

<%= link_to "Ad details", url_for(@magazine, @ad) %>

この場合では、 Rails は @magazine は Magazine で、 @ad は Ad だと思い、従って、 magazine_ad_path helper を使うでしょう。
link_to のようなヘルパ内で、完全な url_for 呼び出しの代わりに、オブジェクトだけを指定することができます:

<%= link_to "Ad details", [@magazine, @ad] %>

ただ magazine へだけリンクしたい場合、 Array も省くことが出来ます:

<%= link_to "Magazine details", @magazine %>

これは、 URL としてモデルのインスタンスを扱うことが出来、リソースフルなスタイルを使う主な利点です。

2.9 もっと RESTful なアクションの追加(Adding More RESTful Actions)

デフォルトで作られる RESTful なルーティング7つに制限されません。
お望みなら、コレクションや、コレクションの個々のメンバに適用したルーティングを追加するでしょう。

2.9.1 メンバルーティングの追加

メンバルーティングを追加するために、リソースブロック内にメンバーブロックを追加してください:

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

これは /photos/1/preview と GET だと認識し、 PhotosController の preview アクションにルーティングするでしょう。
それはまた、 preview_photo_url と preview_photo_path を作るでしょう。

メンバルーティングのブロック内で、全てのルーティング名は HTTP verb を指定すると、認識するでしょう。
get 、 put 、 post 、 delete を使えます。
もし、複数のメンバルーティングがないなら、 :on をルーティングに渡し、ブロックを排除できます:

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

2.9.2 コレクションルーティングの追加

コレクションにルーティングを追加するために:

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

これは Rails が、 /photos/search と GET のようなパスを理解出来るようにし、 PhotosController の search アクションにルーティングします。
それはまた search_photos_url と search_photos_path ルーティングヘルパを作成するでしょう。

メンバルーティングと同様に、 :on をルーティングに渡せます:

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

2.9.3 注意書き

もしリソースフルルーティングに多くの余分なアクションを追加していると気づいたなら、
それは辞め時で、別のリソースの存在を偽装していないかどうか、自分自身に尋ねて下さい。

3 リソースフルでないルーティング(Non-Resourceful Routes)

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

通常、リソースフルなルーティングを使うべきですが、シンプルなルーティングがより適切な多くの場合があります。
もし適していなければ、リソースフルフレームワーク内にアプリケーションの全てを押しこむ必要はありません。

特に、シンプルなルーティングは、古い URL を新しい Rails のアクションにマッピングするのを簡単にします。

3.1 バインドされたパラメーター(Bound Parameters)

いつものルーティングを設定する場合、 Rails が内向きの HTTP リクエストの一部にマッピングする一連のシンボルを指定します。
これらのシンボルの二つは、特別です。 :controller はアプリケーション内のコントローラーの名前にマッピングし、
:action はコントローラー内のアクションの名前にマッピングします。
例えば、デフォルトの Rails のルーティングの1つを考えて下さい:

match ':controller(/:action(/:id))'

/photos/show/1 の内向きのリクエストが、このルーティングによって処理されたら、
(ファイル内のそれ以前のルーティングにマッチしなかったことにより)
結果は PhotosController の show アクションを呼び出し、最後のパラメーターを
params[:id] として 最後のパラメーター "1" を利用可能にするでしょう。
このルーティングはまた、 /photos の内向きのリクエストを、 PhotosController にルーティングし、
:action と :id はオプションのパラメーターなので、カッコで表されています。

3.2 動的セグメント(Dynamic Segments)

いつものルーティング内に、お望みの数だけ動的セグメントを設定できます。
:controller や :action の他は、 params の一部としてアクションで利用可能でしょう。
もしこのルーティングを設定したなら:

match ':controller/:action/:id/:user_id'

/photos/show/1/2 の内向きのパスは、 PhotosController の show アクションにディスパッチされるでしょう。
params[:id] は "1" で、 params[:user_id] は "2" でしょう。

namespace や :module と、 :controller パスセグメントを使えません。~
もしそうしたければ、 :controller 上で、要求するネームスペースとマッチする制約を使います。例えば:

match ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/

3.3 静的セグメント(Static Segments)

ルーティングを作成する時に、静的セグメントを指定できます:

match ':controller/:action/:id/with_user/:user_id'

このルーティングは、 /photos/show/1/with_user/2 のようなパスに対応するでしょう。
この場合、 params は { :controller => "photos", :action => "show", :id => "1", :user_id => "2" } になるでしょう。

3.4 クエリ文字列(The Query String)

params はクエリ文字列から任意のパラメーターを含むでしょう。
例えば、このルーティング:

match ':controller/:action/:id'

/photos/show/1?user_id=2 の内向きのパスは、 PhotosController の show アクションにディスパッチされるでしょう。
params は { :controller => "photos", :action => "show", :id => "1", :user_id => "2" } になるでしょう。

3.5 デフォルトの定義(Defining Defaults)

ルーティングの内側で、 :controller と :action シンボルを明示的に使う必要はありません。
デフォルトとして指定できます:

match 'photos/:id' => 'photos#show'

このルーティングで、 Rails は、 /photos/12 の内向きのパスを PhotosController の show アクションにマッチするでしょう。

:defaults オプションのためのハッシュを供給することによって、ルーティング内の他のデフォルトを定義することも出来ます。
これは、動的セグメントとして指定しないパラメーターにさえ適用されます。
例えば:

match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }

Rails は photos/12 の内向きのパスを PhotosController の show アクションにマッチし、
params[:format] に "jpg" を設定するでしょう。

3.6 名前付きルーティング(Naming Routes)

:as オプションを使って、ルーティングのための名前を指定します。

match 'exit' => 'sessions#destroy', :as => :logout

これは名前付きヘルパとして logout_path と logout_url をアプリケーション内に作成するでしょう。
logout_path の呼び出しは、 /logout を返すでしょう。

3.7 セグメントの制約(Segment Constraints)

動的セグメントのためのフォーマットを適用するために :constraints オプションを使うことが出来ます。

match 'photos/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ }

このルーティングは /photos/A12345 のようなパスにマッチするでしょう。
より簡潔に、同じルートをこのように表現することができます:

match 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ 

:constraints は正規表現を受け取ります。
しかしながら、正規表現のアンカー(訳注: 先頭 ^ 末尾 $ 単語の境界 \b 単語の境界以外 \B )は制約内で使えないことに注意してください。
例えば、次のルーティングは動かないでしょう:

match '/:id' => 'posts#show', :constraints => {:id => /^\d/}

しかしながら、全てのルーティングは先頭に固定されているので、アンカーを使う必要はありません。

例えば、次のルーティングは、 to_param の値が 1-hello-world のような常に数字で始まる posts と
to_param の値が david のような常に数字で始まらない users で、root ネームスペースを共有できるようにします。

match '/:id' => 'posts#show', :constraints => { :id => /\d.+/ }
match '/:username' => 'users#show'

3.8 リクエストベースの制約(Request-Based Constraints)

String を返す Request 上の任意のメソッドに基づいて、ルーティングを制限することが出来ます。

セグメントの制約を指定するのと同じ方法で、リクエストベースの制約を指定します。

match "photos", :constraints => {:subdomain => "admin"}

ブロック形式の中で、制約を指定することも出来ます。

namespace "admin" do
  constraints :subdomain => "admin" do
    resources :photos
  end
end

3.9 高度な制約(Advanced Constraints)

もっと高度な制約がある場合、 Rails が使うべき matches? に対応するオブジェクトを渡せます。
例えば、BlacklistController にブラックリスト上の全てのユーザーをルーティングしたい場合。
こうできます:

class BlacklistConstraint
  def initialize
    @ips = Blacklist.retrieve_ips
  end

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

TwitterClone::Application.routes.draw do
  match "*path" => "blacklist#index",
    :constraints => BlacklistConstraint.new
end

3.10 glob ルーティング(Route Globbing)

glob ルーティングは、特定のパラメーターがルーティングの残りの全ての部分にマッチすべきだと指定する方法です。
(訳注: glob は UNIX コマンド名)

match 'photos/*other' => 'photos#unknown'

このルーティングは photos/12 か /photos/long/path/to/12 にマッチし、
params[:other] に "12" か "long/path/to/12" を設定するでしょう。

ワイルドカードセグメントは、あるルーティングの最後にある必要はありません。
例えば、

match 'books/*section/:title' => 'books#show'

これは books/some/section/last-words-a-memoir にマッチし、
params[:section] は "some/section" 、 params[:title] は "last-words-a-memoir" に等しくなります。

技術的に、確かにルーティングは一つ以上のワイルドカードセグメントを持つことができ、
マッチャーは、直観的な方法でパラメーターにセグメントを割り当てます。
例えば、

match '*a/foo/*b' => 'test#index'

は、 zoo/woo/foo/bar/baz にマッチし、
params[:a] は "zoo/woo" 、 params[:b] は "bar/baz" に等しくなります。

3.11 リダイレクト(Redirection)

ルーティング内の redirect ヘルパを使って、任意のパスを他のパスにリダイレクトできます:

match "/stories" => redirect("/posts")

また、パス内でマッチした動的セグメントを、リダイレクト先のパス内で再利用できます。

match "/stories/:name" => redirect("/posts/%{name}")

redirect にブロックを与えることもできます、それは params と(オプションで) request オブジェクトを受け取ります:

match "/stories/:name" => redirect {|params| "/posts/#{params[:name].pluralize}" }
match "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }

これらの全ての場合、リダイレクト先ホスト(http://www.example.com)を指定しないなら、
Rails は現在のリクエストから詳細を取ってくるでしょう。

3.12 Rack アプリケーションへのルーティング(Routing to Rack Applications)

"posts#index" のような PostsController 内の index アクションに対応する String の代わりに、
マッチャーの終点として Rack application を指定することが出来ます。

match "/application.js" => Sprockets

Sprockets が call に応答し、 [status, headers, body] を返す限り、
ルーティングは、Rack アプリケーションとアクションの間の違いを知らないままでしょう。

好奇心のため、"posts#index" は実際、 PostsController.action(:index) に展開され、それは有効な Rack アプリケーションを返します。

3.13 root の使用(Using root)

Rails が "/" に何をルーティングするか、 root メソッドで指定できます:

root :to => 'pages#main'

root ルーティングをファイルの最後に置くべきです。

4 リソースルルーティングのカスタマイズ(Customizing Resourceful Routes)

resources :posts によって、生成されたデフォルトのルーティングとヘルパは通常役に立ちますが、
何らかの時にそれらをカスタマイズしたい時があるかもしれません。
Rails は リソースフルヘルパのどの部分も事実上カスタマイズすることを許しています。

4.1 利用するコントローラーの指定(Specifying a Controller to Use)

:controller オプションは、リソースのために使うコントローラーを明示的に指定することが出来ます。
例えば:

resources :photos, :controller => "images"

これは /photo から始まる内向きのパスを認識します、が、 Images コントローラーにルーティングするでしょう:

VerbPathaction
GET/photosindex
GET/photos/newnew
POST/photoscreate
GET/photos/1show
GET/photos/1/editedit
PUT/photos/1update
DELETE/photos/1destroy

このリソースのパスを生成するために、 photos_path や new_photos_path 等を使って下さい。

4.2 制約の指定(Specifying Constraints)

暗黙な id 上の 必要なフォーマットを指定するのに、 :constraints を使えます。
例えば:

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

もちろん、このコンテキスト内でリソースフルでないルーティング内で利用可能なもっと高度な制約を使えます。

4.3 名前付きヘルパのオーバーライド(Overriding the Named Helpers)

:as オプションは、名前付きルーティングヘルパのための通常の命名を上書きできます。
例えば:

resources :photos, :as => "images"

は、 /photos で始まる内向きのパスを認識し、リクエストを PhotosController にルーティングするでしょう:

VerbPathaction
GET/photosindeximages_path
GET/photos/newnewnew_image_path
POST/photoscreateimages_path
GET/photos/1showimage_path
GET/photos/1/editeditedit_image_path
PUT/photos/1updateimage_path
DELETE/photos/1destroyimage_path

4.4 new と edit セグメントをオーバーライド(Overriding the new and edit Segments)

:path_names オプションは、パス内に自動的に生成された "new" と "edit" セグメントをオーバーライドできます。

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

これは以下のようなパスをルーティングに認識させます。

/photos/make
/photos/1/change

実際のアクション名はこのオプションによって変更されません。
示されたされた二つのパスは、 new と edit アクションにルーティングされます。

全てのルーティングのためのこのオプションを均一に変更したいなら、スコープを使えます:

scope :path_names => { :new => "make" } do
  # rest of your routes
end

4.5 名前付きルーティングヘルパの接頭辞(Prefixing the Named Route Helpers)

Rails がルーティングのために生成する名前付きルーティングヘルパの接頭辞を指定するのに :as オプションを使えます。
パススコープを使っているルーティング間の名前の衝突を防ぐために、このオプションを使って下さい。

scope "admin" do
  resources :photos, :as => "admin_photos"
end

resources :photos

これは、 admin_photos_path や new_admin_photo_path のようなルーティングヘルパを提供するでしょう。

ルーティングのグループの接頭辞を付けるには、 :as を scope と共に使います。

scope "admin", :as => "admin" do
  resources :photos, :accounts
end

resources :photos, :accounts

ネームスペーススコープは、 :module と :path 接頭辞だけでなく、自動的に :as を追加するでしょう。

4.6 作成されたルーティングの制限(Restricting the Routes Created)

デフォルトでは Rails は、アプリケーション内の全ての RESTful ルーティングのためのデフォルトのアクションの7つ全て
( index 、 show 、 new 、 create 、 edit 、 update 、 destroy )のためのルーティングを作成します。
この動作を微調整するために :only と :except オプションを使えます。

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 翻訳されたパス(Translated Paths)

scope を使って、リソースによって生成されたパスの名前を変更できます:

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

Rails は CategoriesController へのルーティングを作成します。

VerbPathaction
GET/kategorienindex
GET/kategorien/neunew
POST/kategoriencreate
GET/kategorien/1show
GET/kategorien/:id/bearbeitenedit
PUT/kategorien/1update
DELETE/kategorien/1destroy

4.8 単一形式のオーバーライド(Overriding the Singular Form)

リソースの単一形式を定義したいなら、 Inflector に追加ルールを追加すべきでしょう。

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

4.9 ネストしたリソース内での :as の使用(Using :as in Nested Resources)

:as オプションは、ネストしたルーティングヘルパ内でリソースのために自動的に生成された名前をオーバーライドします。
例えば、

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

これは、 magazine_periodical_ads_url や edit_magazine_periodical_ad_path のようなルーティングヘルパを作るでしょう。

5 ルーティングの検査とテスト(Inspecting and Testing Routes)

Rails はルーティングの検査とテストのための仕組みを提案します。

5.1 rake と共に既存のルーティングを見る(Seeing Existing Routes with rake)

アプリケーション内で利用可能なルーティングの全ての完全なリストが欲しいなら、 rake routes コマンドを実行してください。
これは全てのルーティングを、 routes.rb 内で現れるのと同じ順番で表示するでしょう。
全てのルーティングで、以下のことがわかるでしょう:

  • ルーティング名(あれば)
  • 使われている HTTP verb (もしルーティングが全ての verb に対応していなければ)
  • マッチする URL パターン
  • ルーティングのためのパラメータ

例えば、ここに RESTful なルーティングのための rake routes の出力の一部があります:

          users GET  /users          {:controller=>"users", :action=>"index"}
formatted_users GET  /users.:format  {:controller=>"users", :action=>"index"}
                POST /users          {:controller=>"users", :action=>"create"}
                POST /users.:format  {:controller=>"users", :action=>"create"}

CONTROLLER 環境変数を設定することにより、特定のコントローラーをマッピングするルーティングに、リストを制限するかもしれません。

$ CONTROLLER=users rake routes

rake routes からの出力は、行が折り返さないまで端末のウィンドウを広げれば、もっと読みやすくなることがわかるでしょう。

5.2 ルーティングのテスト(Testing Routes)

ルーティングは(アプリケーションの他の部分のように)テスト戦略に含まれるべきです。
Rails は3つの built-in assertions を提案します:

  • assert_generates
  • assert_recognizes
  • assert_routing

5.2.1 assert_generates アサーション

特定のパスを生成するオプションの特定のセットをアサートするために、 assert_generates を使って下さい。
これをデフォルトのルーティングにもカスタムルーティングにも使えます。

assert_generates "/photos/1", { :controller => "photos", :action => "show", :id => "1" }
assert_generates "/about", :controller => "pages", :action => "about"

5.2.2 assert_recognizes アサーション

assert_recognizes アサーションは、 assert_generates の逆です。
Rails は与えられたパスを認識し、アプリケーション内の特定の部分にルーティングするようアサートします。

assert_recognizes({ :controller => "photos", :action => "show", :id => "1" }, "/photos/1")

HTTP verb を指定するために :method 引数を渡せます。

assert_recognizes({ :controller => "photos", :action => "create" }, { :path => "photos", :method => :post })

RESTful なルーティングの解釈をテストするのにも、リソースフルなヘルパを使えるでしょう。

assert_recognizes new_photo_url, { :path => "photos", :method => :post }

5.2.3 assert_routing アサーション

assert_routing アサーションは、ルーティングを両方の方法でチェックします:
パスが生成するオプションと、オプションが生成するパスをテストします。
従って、 assert_generates と assert_recognizes の機能を統合しています。

assert_routing({ :path => "photos", :method => :post }, { :controller => "photos", :action => "create" }) 

6 Changelog(Changelog)

Lighthouse ticket

  • April 10, 2010: Updated guide to remove outdated and superfluous information, and to provide information about new features, by Yehuda Katz
  • April 2, 2010: Updated guide to match new Routing DSL in Rails 3, by Rizwan Reza
  • Febuary 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
  • October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by Mike Gunderloy
  • September 23, 2008: Added section on namespaced controllers and routing, by Mike Gunderloy
  • September 10, 2008: initial version by Mike Gunderloy

コメント欄(誤訳・誤字があれば教えて頂ければ幸いです。)



Top / ruby / rails / RailsGuidesをゆっくり和訳してみたよ / Rails Routing from the Outside In