railsのルーティング周りについて、自分自身がルーティング設定をする時に迷わないようにするため、また内部でどのような処理がされているのかをイメージしながら設定を書けるようになるため、調べた内容をまとめてみる。
最初は、ネストしたルーティングの設定の仕方がよくわからなかったが、スコープを意識することで定義したいリソースを生成したい場合にどのようにルーティングを設定すればよいのかが段々とわかるようになってきた。
- rails-4.2.5で動作確認した内容です。
- 間違いがあれば、コメント等でお知らせいただけますと幸いです。
- サンプルコードは、特に実用性を深く考慮したものではないです。
ルーターの役割
ルーターは,PATH_INFOの情報をもとに、HTTPリクエストを適切なコントローラーのアクションへディスパッチする(正確には、通常Dispatcherオブジェクトがdispatchする)。例えば,以下のような設定を考えてみる。
| 1 | get '/books/:id', to: 'books#show', as: 'book' | 
上記設定で生成されるルーティングは以下のようになり,
| 1 | book GET /books/:id(.:format) books#show | 
GET /books/1のようなHTTPリクエストを送ると、books_controllerのshowメソッドにディスパッチされる。
| 1 2 3 | GET /books/1 => books_controller#show    params[:id] => 1 | 
ルーティング設定
getやpostなどのHTTPメソッド宣言やmatchのような宣言でURLパターンを記述したり、resourcesやresourceのリソーススコープとcollectionやmemberなどのスコープレベルを組み合わせたりすることでルーティングを設定していく。
resources
リソースフルな一連のルーティングを生成する。デフォルトで以下のアクションが用意されている。@api_onlyは,rails5からAPI機能に特化した開発を行なうために追加されたオプションであり,apiモードの時に生成されるアクションでは:newや:editが含まれない形になっている。
| 1 2 3 4 5 6 7 | def default_actions   if @api_only     [:index, :create, :show, :update, :destroy]   else     [:index, :create, :new, :show, :update, :destroy, :edit]   end end | 
resourcesを使って以下のような設定をすると、上記のデフォルトアクションに対応するルーティングが生成される。
| 1 | resources :books | 
この設定により以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 |      books GET    /books(.:format)          books#index            POST   /books(.:format)          books#create   new_book GET    /books/new(.:format)      books#new  edit_book GET    /books/:id/edit(.:format) books#edit       book GET    /books/:id(.:format)      books#show            PATCH  /books/:id(.:format)      books#update            PUT    /books/:id(.:format)      books#update            DELETE /books/:id(.:format)      books#destroy | 
param
セグメント:idは、paramオプションで変えることもできる。,
| 1 | resources :books, param: :no | 
上記設定により以下のようなルーティングが生成される。
| 1 2 3 4 5 6 7 8 |     books GET    /books(.:format)          books#index           POST   /books(.:format)          books#create  new_book GET    /books/new(.:format)      books#new edit_book GET    /books/:no/edit(.:format) books#edit      book GET    /books/:no(.:format)      books#show           PATCH  /books/:no(.:format)      books#update           PUT    /books/:no(.:format)      books#update           DELETE /books/:no(.:format)      books#destroy | 
only、except
onlyやexceptオプションを使うと、ルーティングを特定のアクションに限定したり、ルーティングから特定のアクションを除外したりすることができる。以下はonlyオプションを使って:showアクションのみに限定した場合の例。
| 1 | resources :books, only: [:show] | 
以下のルーティングが生成される。
| 1 | book GET /books/:id(.:format) books#show | 
collection、 member、new
resourcesは、newおよび後述するcollectionとmemberを使っても同じように設定を記述することができる。実際、resourcesは呼び出しの中でこれらのスコープを使っている。以下のような設定を書いてみたところ、resources :booksと同様のルーティングが生成されるのを確認できる(実際にはこのような書き方はしないだろう。。)。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | resources :books, only:[] do   collection do     get :index , to: 'books#index'     post :create, to: 'books#create'   end   new do     get :new, to: 'books#new'   end   member do     get :edit , to: 'books#edit'     get :show , to: 'books#show'     patch :update , to: 'books#update'     put :update , to: 'books#update'     delete :destroy, to: 'books#destroy'   end end | 
nested
nestedスコープは、resourcesスコープで:#{singular}_#{param}の動的パスセグメントを生成する。例えば、以下ではパス/reviewsに対して、:book_idという動的パスセグメントを生成している。
| 1 2 3 4 | resources :books do   # この宣言は、nestedスコープで呼ばれるので、:book_idセグメントが使われる   get 'reviews', to: 'reviews#index' end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 | book_reviews GET    /books/:book_id/reviews(.:format) reviews#index        books GET    /books(.:format)                  books#index              POST   /books(.:format)                  books#create     new_book GET    /books/new(.:format)              books#new    edit_book GET    /books/:id/edit(.:format)         books#edit         book GET    /books/:id(.:format)              books#show              PATCH  /books/:id(.:format)              books#update              PUT    /books/:id(.:format)              books#update              DELETE /books/:id(.:format)              books#destroy | 
:book_idでなく:idを使いたい場合は、memberスコープにすればよい。
| 1 2 3 | resources :books do   get 'reviews', to: 'reviews#index', on: :member end | 
resource
単数形リソース(id参照を必要としないリソース)を使用する時に使う。デフォルトで以下のアクションが用意されている。
| 1 2 3 | def default_actions   [:show, :create, :update, :destroy, :new, :edit] end | 
例えば、ログインしているユーザーに対するリソースフルな一連のルーティングを生成したい場合、以下のように設定できる。
| 1 | resource :user | 
上記設定により生成されるルーティングは以下のようになる。
| 1 2 3 4 5 6 7 |      user POST   /user(.:format)      users#create  new_user GET    /user/new(.:format)  users#new edit_user GET    /user/edit(.:format) users#edit           GET    /user(.:format)      users#show           PATCH  /user(.:format)      users#update           PUT    /user(.:format)      users#update           DELETE /user(.:format)      users#destroy | 
indexアクションのルーティングが含まれない点が、resourcesと異なる。
スコープで生成されるリソース
ActionDispatch::RoutingモジュールのMapper::Resources::Resource(resourcesで呼ばれる)やMapper::Resources::SingletonResourceクラス(resourceで呼ばれる)を見ると、各スコープでどのようなパスセグメントが生成されるのか把握することができる。
ActionDispatch::Routing::Mapper::Resources
from www.omniref.com
以下表にまとめてみる。
| Scope Level | Resources, Resource | Resource (SingularResource) | 
| collection | path | path | 
| member | “#{path}/:#{param}” | path (default scope) | 
| new | “#{path}/new” | “#{path}/new” | 
| nested | “#{path}/:#{singular}_#{param}” (default scope) | path | 
| Called Inside | collection ・get :index ・post :create new ・get :new member ・get :edit ・get :show ・patch :update ・put :update ・delete :destroy | collection ・post :create new ・get :new member ・get :edit ・get :show ・patch :update ・put :update ・delete :destroy | 
例えば以下の設定例では、下表のようになる。
| 1 2 3 4 5 6 7 8 | resources :books do   get 'reviews', to: 'reviews#index' end resource :user do   get 'profile', to: 'users#profile'   # 以下もok   # get 'profile' end | 
| Scope Level | Resources, Resource | Resource (SingularResource) | 
| collection | /books | /user | 
| member | /books/:id | /user /user/profile | 
| new | /books/new | /user/new | 
| nested | /books/:book_id/reviews | 

collection
id参照のないリソースを使用したい時に使う。resourcesまたはresourceのスコープ外で宣言するとArgumentErrorになる。
| 1 2 3 4 5 6 7 8 9 10 11 | resources :books do   collection do     get 'categories'   end end # 上記は以下のようにも書ける。 resources :books do   get 'categories', on: :collection end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 | categories_books GET    /books/categories(.:format) books#categories            books GET    /books(.:format)            books#index                  POST   /books(.:format)            books#create         new_book GET    /books/new(.:format)        books#new        edit_book GET    /books/:id/edit(.:format)   books#edit             book GET    /books/:id(.:format)        books#show                  PATCH  /books/:id(.:format)        books#update                  PUT    /books/:id(.:format)        books#update                  DELETE /books/:id(.:format)        books#destroy | 
member
id参照のあるリソースを使用したい時に使う。resourcesまたはresourceのスコープ外で使うとArgumentErrorになる。
| 1 2 3 4 5 6 7 8 9 10 11 | resources :books do   member do     get 'details'   end end # 上記は以下のようにも書ける。 resources :books do   get 'details', on: :member end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 | details_book GET    /books/:id/details(.:format) books#details        books GET    /books(.:format)             books#index              POST   /books(.:format)             books#create     new_book GET    /books/new(.:format)         books#new    edit_book GET    /books/:id/edit(.:format)    books#edit         book GET    /books/:id(.:format)         books#show              PATCH  /books/:id(.:format)         books#update              PUT    /books/:id(.:format)         books#update              DELETE /books/:id(.:format)         books#destroy | 
ちなみに、memberを使わないと以下のルーティングとなる。
| 1 2 3 4 5 6 7 8 9 | book_details GET    /books/:book_id/details(.:format) books#details        books GET    /books(.:format)                  books#index              POST   /books(.:format)                  books#create     new_book GET    /books/new(.:format)              books#new    edit_book GET    /books/:id/edit(.:format)         books#edit         book GET    /books/:id(.:format)              books#show              PATCH  /books/:id(.:format)              books#update              PUT    /books/:id(.:format)              books#update              DELETE /books/:id(.:format)              books#destroy | 
pathヘルパーメソッドのprefixおよび動的パスセグメント名が異なっているので注意。
root
アプリケーションルートのルーティングを生成する。以下の3つの定義は同じとなるが、1)の書き方が最もシンプル。
| 1 2 3 | 1) root 'welcome#index' 2) root to: 'welcome#index' 3) match '/', as: :root, via: :get, to: 'welcome#index' | 
namespaceやscope内でも宣言することができる。例えば、以下はscopeのブロック内で、3)の設定をしたことと同じである。
| 1 2 3 | scope 'admin', as: 'admin' do   root to: 'admin#index' end | 
以下のルーティングが生成される。
| 1 | admin_root GET /admin(.:format) admin#index | 
HttpHelpers
HttpHelpersモジュールには、代表的なHTTPメソッドのヘルパーメソッドが定義されている。これらのメソッドを使ってresourcesで生成されるルーティングの設定を記述すると以下のようになる。
| 1 2 3 4 5 6 7 8 | get    '/books'    , to: 'books#index', as: 'books' post   '/books'    , to: 'books#create' get    '/books/new', to: 'books#index', as: 'new_book' get    '/books/:id/edit', to: 'books#edit', as: 'edit_book' get    '/books/:id', to: 'books#show' patch  '/books/:id', to: 'books#update' put    '/books/:id', to: 'books#update' delete '/books/:id', to: 'books#destroy' | 
match
HttpHelpersモジュールのメソッドは内部でこのメソッドを呼んでいる。getやpostでは、呼び出しに対応するHTTPメソッドが1つに決定されるが、matchではviaオプションを使って複数のHTTPメソッドに対応するルーティングを生成することができる。
| 1 | match '/books/:id', to: 'books#update', as: 'book', via: [:put, :patch] | 
以下のルーティングが生成される。
| 1 | book PUT|PATCH /books/:id(.:format) books#update | 
anchor
anchorオプションをfals`に設定すると、pathで始まるリソースに一致するリクエスト全てで有効となる。
| 1 2 3 | # /books # /books/any/path/ok match 'books', to: 'books#index', anchor: false, via: :get | 
scope
様々なスコープを作り、ルーティング設定を記述することができる。ここでのオプションは、matchやresourcesでも同様に使うことができる。例えば、以下はpath: '/books'オプションを保持したスコープを作り、そのスコープ内でさらにgetメソッドを使ってルーティングを設定している。
| 1 2 3 | scope '/books' do   get ':id', to: 'books#show', as: 'book' end | 
以下のルーティングが生成される。
| 1 | book GET /books/:id(.:format) books#show | 
path
| 1 2 3 4 5 6 7 8 9 | scope <path> do   # do something end # または scope path: <path> do   # do something end | 
as
スコープ内でasオプションで指定される値をpathヘルパーメソッドのprefixに追加する。
| 1 2 3 | scope as: <path_helper_name> do   # do something end | 
以下では、pathオプションを保持するスコープでasオプションを使ってpathヘルパーメソッドのprefixをそれぞれbooksとbookに設定している。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | scope '/books' do   scope as: 'books' do     get    '/'    , to: 'books#index'     post   '/'    , to: 'books#create'   end   get    '/new', to: 'books#new', as: 'new_book'   get    '/:id/edit', to: 'books#edit', as: 'edit_book'   scope as: 'book' do     get    ':id', to: 'books#show'     patch  ':id', to: 'books#update'     put    ':id', to: 'books#update'     delete ':id', to: 'books#destroy'   end end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 |     books GET    /books(.:format)          books#index           POST   /books(.:format)          books#create  new_book GET    /books/new(.:format)      books#new edit_book GET    /books/:id/edit(.:format) books#edit      book GET    /books/:id(.:format)      books#show           PATCH  /books/:id(.:format)      books#update           PUT    /books/:id(.:format)      books#update           DELETE /books/:id(.:format)      books#destroy | 
controller
スコープ内でcontrollerオプションで指定されるcontrollerを使う。
| 1 2 3 4 5 6 7 8 9 | scope controller: <controller> do   # do something end # 以下も同じ controller <controller> do   # do something end | 
以下では、path、controller、asの3つのオプションを保持したスコープを作り、その中でいくつかのルーティングを設定している。
| 1 2 3 4 | scope '/books', controller: :books, as: :books do   get '/', to: :index   post '/', to: :create end | 
以下のルーティングが生成される。
| 1 2 | books GET /books(.:format) books#index      POST /books(.:format) books#create | 
action
スコープ内でactionオプションで指定されるactionを使う。
| 1 2 3 | scope action: <action> do   # do something end | 
以下では、path、controller、action、asの4つのオプションを保持したスコープを作り、ルーティングを設定している。
| 1 2 3 | scope '/books/:id', controller: :books, action: :update, as: :book do   match '/', via: [:put, :patch] end | 
以下のルーティングが生成される。
| 1 | book PUT|PATCH /books/:id(.:format) books#update | 
module
スコープ内でmoduleオプションで指定されるmoduleを使う。
| 1 2 3 | scope module: <module> do   # do something end | 
以下では、path、module、asの3つのオプションを保持したスコープを作り、adminモジュールのadminコントローラーのindexアクションに対するルーティングを設定している。
| 1 2 3 | scope '/admin', module: :admin, as: :admin do   get '/', to: 'admin#index' end | 
以下のルーティングが生成される。
| 1 | admin GET /admin(.:format) admin/admin#index | 
shallow_path
スコープ内でshallow_pathオプションで指定される値を、shallowオプションが指定されているリソースのメンバーリソース(id参照のある)の先頭に追加する。
| 1 2 3 | scope shallow_path: <shallow_path> do   # do something end | 
以下では、reviewsの一連のid参照をするリソースにunpublishedというパスセグメントを追加している。
| 1 2 3 4 5 | scope shallow_path: 'unpublished' do   resources :books do     resources :reviews, shallow: true   end end | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |    book_reviews GET    /books/:book_id/reviews(.:format)       reviews#index                 POST   /books/:book_id/reviews(.:format)       reviews#create new_book_review GET    /books/:book_id/reviews/new(.:format)   reviews#new     edit_review GET    /unpublished/reviews/:id/edit(.:format) reviews#edit          review GET    /unpublished/reviews/:id(.:format)      reviews#show                 PATCH  /unpublished/reviews/:id(.:format)      reviews#update                 PUT    /unpublished/reviews/:id(.:format)      reviews#update                 DELETE /unpublished/reviews/:id(.:format)      reviews#destroy           books GET    /books(.:format)                        books#index                 POST   /books(.:format)                        books#create        new_book GET    /books/new(.:format)                    books#new       edit_book GET    /books/:id/edit(.:format)               books#edit            book GET    /books/:id(.:format)                    books#show                 PATCH  /books/:id(.:format)                    books#update                 PUT    /books/:id(.:format)                    books#update                 DELETE /books/:id(.:format)                    books#destroy | 
shallow_prefix
スコープ内でshallow_prefixオプションで指定される値を、shallowオプションが指定されているリソースのメンバーリソース(id参照のある)に対応するpathヘルパーメソッドのprefixに追加する。
| 1 2 3 | scope shallow_prefix: <shallow_prefix> do   # do something end | 
以下の例では、unpublishedをpathヘルパーメソッドのprefixに追加している。
| 1 2 3 4 5 | scope shallow_prefix: 'unpublished' do   resources :books do     resources :reviews, shallow: true   end end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |            book_reviews GET    /books/:book_id/reviews(.:format)     reviews#index                         POST   /books/:book_id/reviews(.:format)     reviews#create         new_book_review GET    /books/:book_id/reviews/new(.:format) reviews#new edit_unpublished_review GET    /reviews/:id/edit(.:format)           reviews#edit      unpublished_review GET    /reviews/:id(.:format)                reviews#show                         PATCH  /reviews/:id(.:format)                reviews#update                         PUT    /reviews/:id(.:format)                reviews#update                         DELETE /reviews/:id(.:format)                reviews#destroy                   books GET    /books(.:format)                      books#index                         POST   /books(.:format)                      books#create                new_book GET    /books/new(.:format)                  books#new               edit_book GET    /books/:id/edit(.:format)             books#edit                    book GET    /books/:id(.:format)                  books#show                         PATCH  /books/:id(.:format)                  books#update                         PUT    /books/:id(.:format)                  books#update                         DELETE /books/:id(.:format)                  books#destroy | 
path_names
path_namesオプションで指定される値で、newやeditなどの自動生成されるパスセグメントをオーバーライドする。
| 1 2 3 | scope path_names: {key: value, ...} do   # do something end | 
| 1 2 3 | scope path_names: {new: 'init'} do   resources :books end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 |     books GET    /books(.:format)          books#index           POST   /books(.:format)          books#create  new_book GET    /books/init(.:format)     books#new edit_book GET    /books/:id/edit(.:format) books#edit      book GET    /books/:id(.:format)      books#show           PATCH  /books/:id(.:format)      books#update           PUT    /books/:id(.:format)      books#update           DELETE /books/:id(.:format)      books#destroy | 
shallow
浅いネストを設定する。
| 1 2 3 4 5 6 7 8 9 | scope shallow: true do   # do something end # 以下も同じ shallow do   # do something end | 
| 1 2 3 4 5 6 7 | scope shallow: true do   resources :books do     resources :reviews do       resources :votes     end   end end | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |    review_votes GET    /reviews/:review_id/votes(.:format)     votes#index                 POST   /reviews/:review_id/votes(.:format)     votes#create new_review_vote GET    /reviews/:review_id/votes/new(.:format) votes#new       edit_vote GET    /votes/:id/edit(.:format)               votes#edit            vote GET    /votes/:id(.:format)                    votes#show                 PATCH  /votes/:id(.:format)                    votes#update                 PUT    /votes/:id(.:format)                    votes#update                 DELETE /votes/:id(.:format)                    votes#destroy    book_reviews GET    /books/:book_id/reviews(.:format)       reviews#index                 POST   /books/:book_id/reviews(.:format)       reviews#create new_book_review GET    /books/:book_id/reviews/new(.:format)   reviews#new     edit_review GET    /reviews/:id/edit(.:format)             reviews#edit          review GET    /reviews/:id(.:format)                  reviews#show                 PATCH  /reviews/:id(.:format)                  reviews#update                 PUT    /reviews/:id(.:format)                  reviews#update                 DELETE /reviews/:id(.:format)                  reviews#destroy           books GET    /books(.:format)                        books#index                 POST   /books(.:format)                        books#create        new_book GET    /books/new(.:format)                    books#new       edit_book GET    /books/:id/edit(.:format)               books#edit            book GET    /books/:id(.:format)                    books#show                 PATCH  /books/:id(.:format)                    books#update                 PUT    /books/:id(.:format)                    books#update                 DELETE /books/:id(.:format)                    books#destroy | 
constraints
通常Dispatcherがルーティングエンドポイントとなっているところに、一層処理を挟む形となる。
これを利用すると、動的パスセグメントのURL形式に特定の制約を課すことができる。constraintsオプションのHashキーには、Requestクラスのメソッド名を指定することもでき、その場合、valueはメソッドの返り値の型と一致させる必要がある。
| 1 2 3 4 5 6 7 8 9 | scope constraints: <constraints> do   # do something end # 以下も同じ constraints <constraints> do   # do something end | 
idパラメータが数値のみを許可する例。
| 1 2 3 4 | scope constraints: {id: /\d+/ } do   get '/books/:id', to: 'books#show'   delete '/books/:id', to: 'books#destroy' end | 
以下のルーティングが生成される。
| 1 2 | GET    /books/:id(.:format) books#show {:id=>/\d+/} DELETE /books/:id(.:format) books#destroy {:id=>/\d+/} | 
ローカルからのリクエストの時のみ許可する例。
Requestクラスのlocal?メソッドを使う。
| 1 2 3 | scope constraints: {'local?': true} do   get '/debug', to: 'debug#info' end | 
ActionDispatch::Journey::Route
from www.omniref.com
constraintsに任意のオブジェクトを指定する
matches?メソッドに応答するオブジェクトを指定することができる。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class SmartPhoneConstraint   def initialize     @agent_tags = SmartPhone.agent_tags   end   def matches?(request)     user_agent = request.headers["HTTP_USER_AGENT"]     @agent_tags.any? {|tag| user_agent.include?(tag) }   end end scope constraints: SmartPhoneConstraint.new do   get '/smartphones', to: 'smartphones#index' end | 
Procやlambdaなどのcallに応答するオブジェクトを指定することもできる。
| 1 2 3 | scope constraints: Proc.new {|req| req.local? } do   get '/local', to: 'local#index' end | 
以下のルーティングが生成される。
| 1 | local GET /local(.:format) books#index | 
defaults
パラメータのデフォルト値を設定する。
| 1 2 3 4 5 6 7 8 9 | scope defaults: <default> do   # do something end # 以下も同じ defaults <default> do   # do something end | 
| 1 2 3 | scope defaults: {format: :json} do   get '/books/:id', to: 'books#show', as: 'book' end | 
以下のルーティングが生成される。
| 1 | book GET /books/:id(.:format) books#show {:format=>:json} | 
namespace
| 1 2 3 | namespace :admin, as: 'admin' do   # do something end | 
scopeで以下のように書いたのと同じになる。
| 1 2 3 | scope path: 'admin', as: 'admin', module: 'admin', shallow_path: 'admin', shallow_prefix: 'admin' do   # do something end | 
concern
ルーティング設定を再利用することができる。resourcesやresourceのオプションで指定できる。
| 1 2 3 4 5 6 | concern :attachable do   post '/file_upload', to: 'files#upload' end resources :pages, concerns: :attachable resource :user, concerns: :attachable | 
以下のルーティングが生成される。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | page_file_upload POST   /pages/:page_id/file_upload(.:format) files#upload            pages GET    /pages(.:format)                      pages#index                  POST   /pages(.:format)                      pages#create         new_page GET    /pages/new(.:format)                  pages#new        edit_page GET    /pages/:id/edit(.:format)             pages#edit             page GET    /pages/:id(.:format)                  pages#show                  PATCH  /pages/:id(.:format)                  pages#update                  PUT    /pages/:id(.:format)                  pages#update                  DELETE /pages/:id(.:format)                  pages#destroy file_upload_user POST   /user/file_upload(.:format)           files#upload             user POST   /user(.:format)                       users#create         new_user GET    /user/new(.:format)                   users#new        edit_user GET    /user/edit(.:format)                  users#edit                  GET    /user(.:format)                       users#show                  PATCH  /user(.:format)                       users#update                  PUT    /user(.:format)                       users#update                  DELETE /user(.:format)                       users#destroy | 
Rackアプリケーションの指定
toオプションにrackアプリケーションを指定することができる。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class MyApp   def call(env)     serve ActionDispatch::Request.new(env)   end   def matches?(req)     req.local?   end   def serve(env)     [200, {'Content-Type' => 'text/plain'}, ['hello myapp']]   end end match '/myapp', to: MyApp.new, via: :all | 
以下のようなルーティングが生成される。
| 1 | myapp /myapp(.:format) #<MyApp:0x007fa4d0c7def0> | 
コントローラーのアクションもrackのエンドポイント
toには、アクションを直接指定することもできる。
| 1 | get '/books', to: BooksController.action(:index) | 
redirect
toオプションにredirectを使うと、動的セグメントを利用してリダイレクトさせることができる。
| 1 2 | get '/readers/:name', to: redirect('/reviewers/%{name}'), as: 'reader' get '/authors/:name', to: redirect(path: '/writers/%{name}', subdomain: 'book'), as: 'author' | 
以下のルーティングが生成される。
| 1 2 | reader GET /readers/:name(.:format) redirect(301, /reviewers/%{name}) author GET /authors/:name(.:format) redirect(301, path: /writers/%{name}, subdomain: book) | 
mount
アプリケーションにRackアプリケーションやEngineをマウントすることができる。内部では、matchが呼び出されている。
| 1 2 3 4 5 | Ex1) mount MyRackApp, at: 'myapp' Ex2) mount MyRackApp => 'myapp' Ex3) mount MyRackApp => 'myapp', as: 'my' => match 'myapp', to: MyRackApp, via: :all, format: false, anchor: false, as: 'my' Ex4) mount MyApp::Engine => '/myapp' | 
Ex3の例では、以下のルーティングが生成され、/myappでアプリケーションにアクセスすることができる。
| 1 | my /myapp #<MyApp:0x007fa4cba5a790> | 
ルーティング適用の順番
ルーティングは、先に設定しているものが優先される。
| 1 2 3 4 | # こっちが先に定義されているので呼ばれる get '/first', to: 'welcome#index' # こっちは呼ばれない get '/first', to: 'books#index' | 
参考リンク
- http://railsguides.jp/routing.html
- http://railsguides.jp/engines.html
技術評論社
売り上げランキング: 23,409
 
  


コメント