読者です 読者をやめる 読者になる 読者になる

おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

rails de REST

rails

railsでRESTを実現するための方法についてまとめ。

RESTとは

  • Representational State Transferの略
  • URI(名詞)とmethod(動詞)で振る舞いを決める

RESTにするメリット

  • 変わりにくいURI「Cool URI」が実現でき、ユーザビリティがあがる
  • インタフェース構築手法が統一されるため、作るのが楽になる

railsでRESTするには

ここからが本題。RAILS_ROOT/config/routes.rb内に下記のような文を追記する

map.resources :articles

そうすると、下記のようなRESTなルーティングが自動的に生成される。*1らくちん。

メソッド URLのパス アクション ヘルパー "index")と同じ。">*2
GET /articles index articles_url
POST /articles create articles_url
GET /articles/new new new_article_url
GET /articles/1 show article_url(:id => 1)
PUT /articles/1 update article_url(:id => 1)
GET /articles/1/edit edit edit_article_url(:id => 1)
DELETE /articles/1 destroy article_url(:id => 1)

単数系と複数

controller名の単数形複数形、map.resourceの単数形複数形で振る舞いがいろいろ変わってくる。なのでcontrollerを作るときは単数系と複数形をきちんと意識した方がいいみたい。少なくともRESTを使うcontrollerの名前は複数形したほうがいい。もしかしたらcontrollerの名前は全部複数形に統一したほうがいいのかもしれない。*3


以下どのように変わるかのメモ。

map.resources :article

controller名を単数形にすると、indexアクションのヘルパーが変化する。controller名が全部単数形になる。他は同じ

メソッド URLのパス アクション ヘルパー
GET /article index article_index_url
POST /article create article_index_url
GET /article/new new new_article_url
GET /article/1 show article_url(:id => 1)
PUT /article/1 update article_url(:id => 1)
GET /article/1/edit edit edit_article_url(:id => 1)
DELETE /article/1 destroy article_url(:id => 1)
map.resource :article

resourcesの方を単数形にすると、idを取り扱わないアクションとしてルーティングが作られる。

メソッド URLのパス アクション ヘルパー
POST /article create article_url
GET /article/new new new_article_url
GET /article/edit edit edit_article_url
GET /article show article_url
PUT /article update article_url
DELETE /article destroy article_url

この時、パスは単数形(article)でもルーティング先のcontrollerの名前は複数形(articles)になる*4

map.resoucesの拡張

map.resoucesでルーティング定義したcontrollerに、newとかupdateとかデフォルトで定義された以外のアクションのルーティングを定義する場合。

/article/1/recentのように、各IDごとに作用するアクションのルーティングを定義する場合

map.resources :articles, :member => { :release => :put }

/article/releaseみたいな場合

map.resources :articles, :collection => { :recent => :get }

/articles/new/shortformのように、既存のアクションnewアクションに上乗せしたルーティングを定義する場合

map.resources :articles, :new => { :shortform => :post }
修正
2008/06/12
memberとcollectionが逆なのを修正、newオプションの説明を修正

map.resouces以外でRESTしたい場合

map.resourcesを使わないでRESTを実現したい(editとかupdateとかのアクション名が嫌いとか)
人は以下のようにしてひとつづつルートを設定する必要がある。面倒。

map.connect 'articles/:id',
  :conditions => { :method => :put },
  :action => 'updatedayo'

参考資料

RailsによるアジャイルWebアプリケーション開発 第2版

RailsによるアジャイルWebアプリケーション開発 第2版

WEB+DB PRESS Vol.38

WEB+DB PRESS Vol.38

*1:あとformatの分もあるけどそれは省略

*2:名前付きルートのこと。articles_urlはurl_for(:controller => "articles", :action => "index")と同じ。

*3:でもcontrollerによっては複数形がそぐわない場合もあるので、そういう時だけ単数形がベストかな?

*4:だからやっぱりcontrollerの名前は複数形がいい