Rails 3のroutesまとめ

Posted by irohiroki Sun, 29 Aug 2010 09:15:00 GMT

Rails 3ではroutesのDSLが完全に刷新されました。特に、あの見難かったハッシュの塊が解かれて、:member:getなど予約語の役割をしていたシンボルはディレクティブになりました。例えばRails 2の以下の記述は

map.resources :users, :member => {:foo => :get}, :collection => {:bar => :post}

Rails 3では下のように書けます:

resources :users do
  member do
    get :foo
  end

  collection do
    post :bar
  end
end

このように、Rails 2では"予約語"がキーになったり(:member:collection)値になったり(:get:post)していたものが、Rails 3ではディレクティブになり、ユーザの与える値がシンボルとして残りました。

また、ActionController::Routing::RouteSet::Mapperインスタンスであるmapが必要なくなっています。

このエントリでは、8月21日のRails勉強会@東京第54回@a_matsudaさんに教えていただいたことをベースに、Rails 3のroutesについてまとめます。

基本

URLのパターンに対し、コントローラとアクションを指定する方法は、Rails 2では

map.connect 'friends/:id', :controller => 'users', :action => 'show'

でしたが、Rails 3では

match 'friends/:id', :to => 'users#show'

になります。mapが不要になったことと、コントローラとアクションを1つの値で指定できることで簡潔になっていますね。

逆に、オプションのパラメータは()で囲む必要があります。例えば、デフォルトルートは下のように定義されます。

match '/:controller(/:action(/:id))'

名前付き(Named)

Rails 2では下の.friendのようにMapperインスタンスへ送るメッセージがルート名になったのですが

map.friend 'friends/:id', :controller => 'users', :action => 'show'

Rails 3では基本のmatchディレクティブに:asを付けます。

match 'friends/:id', :to => 'users#show', :as => 'friend'

root

root、つまり「/」に対するrouteは、Rails 2ではmap.rootというnamed routeが「/」に予約されていましたが、Rails 3ではrootというディレクティブを使います。例えば下のようになります:

root :to => 'home#show'

基本の省略形

基本のmatchディレクティブでは、実は:toを省略できます。つまり、下の2つは同じことです。

match 'friends/:id', :to => 'users#show'
match 'friends/:id' => 'users#show'

さらに、パスのノード名がコントローラ名とアクションに一致するなら、それも省略可能です。よって下の2つは同じです。

match 'users/summary' => 'users#summary'
match 'users/summary'

特定のコントローラに対するルートは、controllerディレクティブでまとめることができます:

controller :users do
  match 'summary', :to => :short
  match 'pretty', :to => :pp
end

resources

RESTfulなルートを定義するのに便利だったmap.resourcesですが、Rails 3でもresourcesとして使用可能です。例を挙げます:

resources :users

さらに、複数のリソースを渡せるようになりました:

resources :users, :products, :shops

resourcesはブロックを受け取り、その中で冒頭で紹介したmembergetといったディレクティブを使用できます。

resourcesをネストした場合は、Rail 2と同様、has_manyの関係を定義できます。

resources :users do
  resources :items
end

# user.rb
class User < ActiveRecord::Base
  has_many :items
end

:only:exceptといったオプションを与えて生成するルートを絞ることや、:constraintsオプションで受け付けるパラメータのパターンを制限するのもRails 2と同じです。

namespace

namespaceディレクティブを使うことで、パス(URL)とコントローラを任意の名前空間に入れることができます。例えば下のように書くことで、パスは/admin/users、コントローラはapp/controllers/admin/users_controller.rbに置かれたAdmin::UsersControllerになります。

namespace "admin" do
  resources :users
end

もしパスだけに名前空間をつけてコントローラはapp/controllersに入れたければ、scopeを使います:

scope "/admin" do
  resources :users
end

反対に、コントローラにだけ名前空間を付けたければ、scope :module => を使います:

scope :module => "admin" do
  resources :users
end

Rackアプリケーションへルート

Rails 3ではルーティングの機構自体がRackミドルウェアなので、別のRackアプリケーションを呼び出すようなルートも書けるようになりました。例えば:toの先にSinatra::Baseの子クラスを書くことができます。また、redirectというメソッドを使ってリダイレクトを指定することもできます:

match "/users/:id", :to => redirect("/accounts/%{id}")

参考

講師をしてくださった松田さんがRails 3の特集を書かれました。

WEB+DB PRESS Vol.58
WEB+DB PRESS Vol.58
  • 発売元: 技術評論社
  • 価格: ¥ 1,554
  • 発売日: 2010/08/24

Posted in  | Tags ,  | 2 comments | 1 trackback

Comments

  1. vicodin said over 1 year later:

    For newest information you have to pay a visit the web and on world-wide-web I found this website as a finest web site for most up-to-date updates.

  2. shinriyo said over 1 year later:

    ありがとうございます。 routesの書き方が一番詳しいエントリですね。

    routesがキモなのにいつも書き方を忘れてハマります

Trackbacks

Use the following link to trackback from your own site:
http://irohiroki.com/trackbacks?article_id=7

  1. From h-kageyuの日記
    Ruby on Rails 3 その3
    Rails3 の ActiveRecord で1件だけを返したいときは、Users.first や Users.last のようにすればよい。 SQL的には LIMIT 1 が付くだけ( last の場合は ORDER BY users.id DESC LIMIT 1)なのですが。 また複数...

(leave url/email »)

   Comment Markup Help Preview comment