Ruby on RailsにおけるRouting

こんにちは、south37です。今日も元気にrailsについて書いていこうと思います。前回のcontrollerのとこでもちょこっと触れてた、routingの話です。

routingとは?

まず最初に、Webサイトを訪問された際のrailsでの処理の流れを簡単に考えて見ましょう。
おおざっぱには、

1. urlを叩く
2. controllerの特定のメソッドが呼び出され、サーバーにおける処理が行われる。その際に、modelを通してDBにアクセスしたりする
3. 情報を整形して、viewとして出力

みたいな流れになるはずです。

routingというのは、この1.から2.にかけてに対応する処理です。すなわち、urlやGET or POSTなどに応じて呼ばれるべきcontrollerのメソッドを振り分けます。

railsにおいては、独自のDSLを使って、routing用のfileを記述します。ファイル名はroutes.rbというまんまなやつで、例えば

Nawabari::Application.routes.draw do
  get    'users/rank/:id',      to: 'users#rank'
  get    'users/update/:id/:name/:area' => 'users#update', area: /.*/
  get    'users',               to: 'users#index'
  get    'users/ranking/:num/', to: 'users#ranking'
  delete 'users/:id',           to: 'users#destroy', as: 'user'
  get    'users/new',           to: 'users#new'
  post   'users',               to: 'users#create'
end

みたいな感じで書いたりします。

ニュアンスはなんとなく分かると思うんですが簡単に説明すると、二行目のget 'users/rank/:id', to: 'users#rank'はhttp://~/users/rank/3を叩かれるとusers controllerのrankメソッドの処理が呼ばれるという意味です。:idって書いてる部分に渡された数字が、params[:id]としてcontrollerの中で受け取れるようになっています。

三行目もだいたい同じなんですが、:areaとして小数点も受け取れるようにする為に、areaの形式を正規表現で指定しています。/.*/って書いてて、.が任意の一文字で*が0個以上の繰り返しって意味なので、ようは:id/:name/の後に続く文字は何でもparams[:area]として受け取るって意味になっています。自分で書いておいてなんですが、何だかバカっぽいですね...

一応、:areaとしては小数も含めた数字が入るはずなんで、それを正規表現で表すと/\d+(\.\d+)?/みたいな感じになるでしょうか。ただ、この表現だと333.dみたいな値に対しても333をひっかけてしまいます。出来れば/\d+(\.\d+)?$/みたいに終末文字$を使いたいです。しかし、どうやらrailsにおいては正規表現のアンカー(訳注: 先頭 ^ 末尾 $ 単語の境界 \b 単語の境界以外 \B )は制約内で使えないらしいです。すごく気持ち悪くていやですね...

四行目移行は同じようなノリです。注目する点としては、as: ~ってやつでしょうか。これは、指定したurlに名前をつけるのに使います。railsでは、controllerやviewで別のページへのリンクを作る際にはlink_toと呼ばれるメソッドを用います。この引数としては、例えばhttp://~/users/indexを作りたければusers_index_pathという風に書きます。このとき、as: usersとしておくとlink_to users_pathでhttp://~/users/indexを生成出来る訳です。

ルーティングについてはこんな感じでしょうか。ちなみに、細かい指定が嫌であれば、routes.rbに

resources :pages

って書いておけば

#     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
#           PUT    /pages/:id(.:format)      pages#update
#           DELETE /pages/:id(.:format)      pages#destroy

のような7つのurl(とcontroller)へのroutingが一気に生成されます。こんな風に適切なデフォルトがあって、楽を出来るところではちゃんと楽を出来るのがrailsのいいとこですね。