RESTFulとRails、map.resources

routes.rbに記載するmap.resourcesメソッドで提供される機能について、分かった範囲でメモ書きします。
この機能はREST支援機能なので、まずRESTから確認しました。

REST

RESTについての自分の認識。
(ここではRailsにとってのRESTを見ていくので、「アーキテクチャの原則と制約の集まり」の方のRESTについて)

  • システムコンポーネント間のやりとりに課される一連の制約
  • リソースの例
    • 現在日付
    • 商品
    • 在庫
    • セッション
  • コンポーネントの例
  • RESTの制約
  • システムコンポーネントは、ネットワークを介してリソースの「表現」をやりとりする。
    • 例えばXML、例えばjson。これらはリソースは同じでも表現が異なる。
    • 表現はリソース管理における通貨(クライアントもサーバも表現をやり取りして動作する)
  • 全てのリソースに適用できる操作セットがあり、この操作セットを介してリソースを扱う。
    • HTTPメソッドにおいてはGET/POST/PUT/DELETE
    • これらの操作はリソースに適用されるもので、リソースと直接関連付いてはいない。

RailsにおけるREST

名前付きルートと7つのコントローラアクションで表される。

  • map.resourcesに定義するということは、対象の名前付きルートに対応する7つのコントローラアクションを使うことに合意すること。
  • コントローラアクションとはindex/create/show/update/destroy/new/edit。
    • これらアクションはCRUDベースで命名されている
  • この定義を利用することでURIとHTTPメソッドの組み合わせで定型的なコントローラのメソッドへとルーティングされる。
URI・HTTPメソッドと呼び出されるメソッド

例えば

map.resources :messages

とした場合、組み合わせはこうなる。

  • ※URL(HTTPメソッド) -> 対応するメソッド #注釈
  • 複数形(messages)
    • XXX/messages(GET) -> MessagesController#index #複数形なので一覧表示
    • XXX/messages(POST) -> MessagesController#create #新規作成
  • 単数形(message)
    • XXX/message(GET) -> MessagesController#show #単数形なので一つを表示
    • XXX/message(PUT) -> MessagesController#update #更新
    • XXX/message(DELETE) -> MessagesController#update #削除
  • 補助アクション
    • XXX/message/new(GET) -> MessagesController#new
    • XXX/message/edit(GET) -> MessagesController#edit

補助アクションは、それぞれcreate/updateの前段階で、動き自体はshowと同じ。ただ、単数形のGETは既にshowで使われているので、これらには異なるURIが与えられている。

ヘルパーメソッド

map.resources指定を利用することで、ヘルパーメソッドが利用できるようになる。(mは一つのモデルクラスオブジェクト)

  <%= link_to "Edit", edit_message_url(m) %>
  <%= link_to "Destory", message_url(m), :confirm => "deestroy?", :method => :delete %>
  • message_url(m)
    • 単数形。引数のモデルのidをとって、「XXX/message/1」などのURLを生成。
    • :methodパラメタでHTMLメソッドを指定できる。(putやdelete)
  • messages_url
    • 複数形。「XXX/messages」というURLを生成。
  • new_message_url
  • edit_message_url(m)
    • 補助メソッド用。それぞれ「XXX/message/new」「XXX/message/1/edit」というURLを生成。
ネスト

リソースはネストすることができる。

  map.resources :posts do |post|
    post.resources :comments
  end

で、

    <td><%= link_to 'Show', post_comment_path(@post, comment) %></td>
    <td><%= link_to 'Edit', edit_post_comment_path(@post, comment) %></td>
    <td><%= link_to 'Destroy', post_comment_path(@post, comment), :confirm => 'Are you sure?', :method => :delete %></td>

という形で使用することができる。ネストリソースの識別のため、2つのパラメータを渡している。
前回作ったComment機能はこういった考え方に基づいていたことが分かる。
(CommentはPostに従属するリソースだから、ネストしたリソースとして定義され、コーディングされていた)

メモ

  • Commentサンプルを触っているときは、map.resourceという定義に対して起きる「お約束」が多すぎる気がしたけれど、理屈は通っているように感じる。
  • 逆に慣れてしまえば、URLとリソースおよびアクションをどう関連付けるかについて定型的な思考ができるようになりそう。
  • 単数形と複数形をよく間違ってしまうけど、これも慣れっぽい印象を持つ。