Quantcast
Channel: Ruby on Railsの記事一覧|TechRacho by BPS株式会社
Viewing all articles
Browse latest Browse all 1391

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

$
0
0

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

Rails routesを極めよう

2012/03
baba

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

とにかくrake 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(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" 
    
  • アルファベット順にソートする
  • config/routes.rbは記載順にマッチしますので、上にあるものが優先されます。しかし、膨れ上がったルーティングを人間が管理する際には、アルファベット順に並べておくのはひとつの方法です。

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


    Viewing all articles
    Browse latest Browse all 1391

    Trending Articles