Rails3のルーティングについて自分なりにまとめてみる #rails

最近Rails3で遊んでて、ようやくルーティングが分かってきたのでまとめます。僕の知ってる範囲しかまとめないので、すべての機能を網羅するわけではありませんが、これだけ知ってれば不自由しない気がするのでそれで良いです。ウフフ、オッケー。

基本的なこと

Railsの思想

Railsのルーティングを理解するのに、押さえておくべき思想は一つかなと思います。

「すべての操作はリソースに対するCRUD操作である」

これを念頭においておくと、ルーティングの理解がしやすくなると思います。

編集するファイル

ルーティングは以下のファイルに記述します。基本的にこれだけを見れば全部のルーティングがわかるようになっています。

config/routes.rb

ルーティングの確認方法

Railsアプリケーションのルートディレクトリで以下のコマンドを打てばいつでもルーティングを確認することができます。ルーティングをいじったらこまめに確認すると良いでしょう。

$ rake routes

resources

引数に与えた名前のリソースに対するCRUD操作を行う為のルートを定義します。

  resources :posts

これを rake routes で確認すると以下のようになります。

$ rake routes
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy
各アクションの役割

各アクションの役割は以下のとおりです。

アクション 役割 viewを持つか CRUD おもな遷移先
posts#index postの一覧を表示する o R show,new,destroy
posts#create postを新規作成する x C show
posts#new postを新規作成するための情報を入力する o R(C) create
posts#edit postを更新するための情報を入力する o R(U) update
posts#show postの詳細な情報を表示する o R edit
posts#update postを更新する x U show
posts#destroy postを削除する x D index
アクションを限定することができる

新規作成はできるけど更新はできないとか、削除させないとかを制御することができます。

:onlyを使うことで、指定したアクションだけのルートを定義することができます。

resources :posts, :only => [:new, :create]
$ rake routes
   posts POST /posts(.:format)     posts#create
new_post GET  /posts/new(.:format) posts#new

:exceptを使うことで、指定したアクション以外のルートを定義することができます。

resources :posts, :except => [:edit, :update, :destroy]
$ rake routes
   posts GET  /posts(.:format)     posts#index
         POST /posts(.:format)     posts#create
new_post GET  /posts/new(.:format) posts#new
    post GET  /posts/:id(.:format) posts#show

意図に合わせて適宜使い分けると良いでしょう。

resourcesのネスト

resourcesをネストさせることもできます。

resources :posts do
  resources :comments
end
$ rake routes
    post_comments GET    /posts/:post_id/comments(.:format)          comments#index
                  POST   /posts/:post_id/comments(.:format)          comments#create
 new_post_comment GET    /posts/:post_id/comments/new(.:format)      comments#new
edit_post_comment GET    /posts/:post_id/comments/:id/edit(.:format) comments#edit
     post_comment GET    /posts/:post_id/comments/:id(.:format)      comments#show
                  PUT    /posts/:post_id/comments/:id(.:format)      comments#update
                  DELETE /posts/:post_id/comments/:id(.:format)      comments#destroy
            posts GET    /posts(.:format)                            posts#index
                  POST   /posts(.:format)                            posts#create
         new_post GET    /posts/new(.:format)                        posts#new
        edit_post GET    /posts/:id/edit(.:format)                   posts#edit
             post GET    /posts/:id(.:format)                        posts#show
                  PUT    /posts/:id(.:format)                        posts#update
                  DELETE /posts/:id(.:format)                        posts#destroy

commentsに対するルーティングが定義されました。パスの先頭に /posts/:post_id がつきます。

namespace

管理画面を作りたいときなんかに便利なのがnamespaceです。例を見ましょう。

namespace :admin do
  resources :users
end
$ rake routes
    admin_users GET    /admin/users(.:format)          admin/users#index
                POST   /admin/users(.:format)          admin/users#create
 new_admin_user GET    /admin/users/new(.:format)      admin/users#new
edit_admin_user GET    /admin/users/:id/edit(.:format) admin/users#edit
     admin_user GET    /admin/users/:id(.:format)      admin/users#show
                PUT    /admin/users/:id(.:format)      admin/users#update
                DELETE /admin/users/:id(.:format)      admin/users#destroy

パスの先頭に /admin がつくようになります。注意事項が2点あります。

  1. model, view, controller の各ファイルを(基本的に)adminディレクトリ以下に配置する必要がある
  2. model, controller のクラスを(基本的に)Adminモジュールの内部に宣言する必要がある
MVC ファイル クラス
model app/models/admin/user.rb Admin::User
view app/views/admin/〜 なし
controller app/controllers/admin/users_controller.rb Admin::UsersController

root

ルート(/)へのルーティングを定義します。

root :to => 'posts#index'
$ rake routes
root  / posts#index

namespaceの下に定義することもできます。

root :to => 'posts#index'
namespace :admin do
  root :to => 'users#index'
end
$ rake routes
      root  /                posts#index
admin_root  /admin(.:format) admin/user#index

match

matchを使うと、比較的自由にルーティングを定義することができます。例えばomniauth等のプラグインを使って外部サービス経由でのログインをする場合、以下のように設定することになると思います。

match '/auth/:provider/callback' => 'sessions#create'
$ rake routes
  /auth/:provider/callback(.:format) sessions#create

まとめ

Rails3のルーティングについて僕が知ってることは以上です。間違ってたりしてたら指摘してもらえると嬉しいです。もっと高度な設定を教えてくれる人も大歓迎です。

「すべての操作はリソースに対するCRUD操作である」

とにかく、このことだけ忘れなければ色々すっきりすると思っています。