Railsのルーティングを極める(前編)

Railsのルーティングを極める(後編)もご覧ください。


こんにちは、hachi8833です。今回も弊社CTOの馬場さんによる勉強会のスライドを元に記事を書きました。執筆当時はRails3だったので、Rails4情報も追加しました。

Railsのルーティング(routes)を極めよう

2012/03
baba

Railsのルーティングはきわめて自由度が高い分、気を付けないとすぐカオスになってしまいます。Railsのルーティングのコツについて勉強していきましょう。Railsのルーティングはconfig/routes.rbで設定します。

とにかくrake routes

追記: 現在はrakeコマンドがrailsコマンドに置き換えられつつあるので、rails routesを使うのがよいでしょう。

ルーティングを書く際にはrake routesを実行する癖をつけましょう。ルーティングを作成するだけでなく、Railsのデバッグ時にも有用で、迷ったらとにかくrake routesを実行してもいいくらいです。

rake routesは実行のたびにRails環境を読み込むので、そのままでは遅いので有名です。以下のような方法で高速化しましょう。

  • pryとpry-rails gemがインストールされているなら、rails consoleを起動しておいてshow-routesを実行
  • spring gemがインストールされているならspring rake routesとすれば2度目以降から高速になる
  • dev環境が起動中ならhttp://localhost:3000/rails/infoを参照する (Rails 4)

改めて、RESTとは

RESTとは、Railsに敷かれているレールの一つである概念で、REpresentational State Transferの頭字語です。その特徴は:

  • ステートレスであること
  • すべてを「リソース」で表す
  • リソースは名前を持つ
    RESTに従っていることをRESTfulと呼んだりします。

RESTfulなURLの例

  • http://example.com/prefectures
  • http://example.com/users/1

RESTの反対はRPC

RESTのちょうど反対の概念がRPC(Remote Procedure Call)です。これはクエリ形式などと呼ばれることもあることからわかるように、?の後ろに問い合わせを&でつないで表現します。

RPC URLの例

  • http://example.com/index.php?action=prefecture_list&id=1
  • http://example.com/PrefectureList.aspx?id=1 http://example.com/xmlrpc

Railsではresourcesでルーティングを記述することで自動的にRESTfulなルーティングが生成されます。
以下はusersコントローラとproductsコントローラへのルーティングです。

resources :users
resources :products

その場合、対応するコントローラにもRESTfulなアクションが揃っている必要があります。rails generate scaffoldで生成した場合は自動的にRESTfulになります。

Railsでは、REST形式もRPC形式も両方扱うことができますが、RailsはRESTを「レール」として定めていますので、統一のためにRESTfulなルーティングの作成を心がけるようにしましょう。

ただし、RESTはあくまでポリシーであり万能ではないので、時にはRPC形式を一部に導入する方が素直に作れることもあります。

RESTメソッド

RESTとHTTPメソッドにはそれぞれ以下のような関係があります。なお、Rails 4 からはPUTは非推奨となりPATCHが推奨されています。

RESTメソッド

メソッド 安全 冪等
GET
POST × ×
PATCH/PUT ×
DELETE ×
  • 安全が×になっているのは、危険という意味ではなく、実行すると元のデータが更新されるという意味です。
  • 同様に、安全が◯になっているのは、実行によって更新される心配がないという意味です。

  • 冪等(べきとう: idempotent)は近年よく使われる用語で、「1回実行しても2回以上実行しても結果が変わらない」ことを指します。1人殺しても3人殺しても死刑、は冪等です。1人殺せば犯罪者、1000人殺せば英雄、1億人殺せば神、だと冪等ではありません。

  • chefやvagrantなどのサーバーデプロイ用DSLではその目的のため冪等性が重視されます。

以下の表では、BPSという会社の所在地をGETメソッドとRESTfulなURLで表現した場合の例を示しています。

概念 RESTfulなメソッドとURL
都道府県 GET /prefectures
東京都 GET /prefectures/tokyo
東京都市区町村一覧 GET /prefectures/tokyo/cities
東京都新宿区 GET /prefectures/tokyo/cities/shinjuku
東京都新宿区会社一覧 GET /prefectures/tokyo/cities/shinjuku/companies
東京都新宿区にあるBPSという会社 GET /prefectures/tokyo/cities/shinjuku/companies/bps
BPSという会社 GET /companies/bps

以下の表は、記事・ユーザ・コメントを表現した場合の例です。特に、IDが複数ある場合の表現方法にご注目ください。

概念 RESTfulなメソッドとURL
記事一覧 GET /articles
記事(ID=1)、コメント一覧 GET /articles/1/comments
記事(ID=1)、コメント(ID=1) GET /articles/1/comments/1
ユーザ(ID=1) GET /users/1
ユーザ(ID=1)、パスワード GET /users/1/password

以下の表は、記事・ユーザ・コメントに対して操作を行なう場合の例です。Rails 4ではPUTは非推奨になり、PATCHが推奨されます。

概念 RESTfulなメソッドとURL
記事を投稿する POST /articles
記事(ID=1)にコメントを投稿する POST /articles/1/comments
記事(ID=1)を更新する PATCH /articles/1
記事(ID=1)のコメント(ID=1)を更新する PATCH /articles/1/comments/1
記事(ID=1)を削除する DELETE /articles/1
ユーザ(ID=1)のパスワードを更新する PATCH /users/1/password
(エラー) POST /users/1/password

ルーティングを綺麗に書くコツ

RESTに従う

原則として、RESTに従うようにしましょう。頑張ればresourceですべて書くことができます。が、原理主義的にがんばるとかえって見通しが悪くなることもありますのでほどほどにしましょう。

  resources :admin_menus, only:[ :index, :update ]
  resources :menus, only:[ :index ]
  resources :deadlines, except:[ :create, :destroy ]

以下の名前を理解する

リソース
HTTPメソッド(GET/POST/PATCH/PUT/DELETE)で操作する対象となるURLです。
名前付きルート
「パス_path」(ドメイン名より下のパスのみ)または「パス_url」(httpなどから始まるフルパス)という形式でURL形式を指定できます。たとえばContactページが/contactというパスにある場合、contact_pathまたはcontact_urlという名前付きルートで指定できます。名前付きルートは、パスヘルパーやURLヘルパーとも呼ばれます。これにより、コード上でURL構造を意識せずにパスを指定できます。
なお似ているけど違うのは「名前付きスコープ」と「名前付きパラメータ」です。
ネストしたリソース
ネストしたルーティングを記述することで、あるリソースを他のリソースの子にすることができます。

ファイル分割を検討する

Railsアプリケーションが成長してルーティングが膨大になったら、config/routes.rbの分割を検討しましょう。たとえば以下のようにconfig/application.rbに記載することで、config/routes.rbを分割してconfig/routes/以下のroutes_1.rbとroutes_2.rbに置くことができます。

config.paths["config/routes"] << "config/routes/routes_1.rb" 
config.paths["config/routes"] << "config/routes/routes_2.rb" 

アルファベット順にソートする

ネストしたリソースなどについては、後編に続きます。

関連記事

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。 高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(16区分17回 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、Ruby Programmer Gold、AWSソリューションアーキテクト(アソシエイト)、日商簿記2級、漢検準1級などを保有。

babaの書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ