basyura's blog

あしたになったらほんきだす。

REST をキメるときもちイイ

url と method (GET , POST , PUT , DELETE) で action (index , create , new ,edit , show , update , destroy) がキマる。
非常に綺麗で気持ちがいい。

config/routes

Project モデルを定義済みだとして、呼び出し可能なルートを定義する。

resources :projects

これでどのようなルートが定義されたかは rake で確認する。

$ rake routes
    projects GET    /projects(.:format)          {:action=>"index", :controller=>"projects"}
             POST   /projects(.:format)          {:action=>"create", :controller=>"projects"}
 new_project GET    /projects/new(.:format)      {:action=>"new", :controller=>"projects"}
edit_project GET    /projects/:id/edit(.:format) {:action=>"edit", :controller=>"projects"}
     project GET    /projects/:id(.:format)      {:action=>"show", :controller=>"projects"}
             PUT    /projects/:id(.:format)      {:action=>"update", :controller=>"projects"}
             DELETE /projects/:id(.:format)      {:action=>"destroy", :controller=>"projects"}

method と url の組み合わせが、どのコントローラの action とリンクしているかが分かる。

new_project_path

新しいレコードを作る view へのリンクを貼る。

new_モデル名_path

でパスを生成してくれる。

<%= link_to "new project" , new_project_path %>

controller

rake routes の結果を見ても分かる通り、new_project を GET で開くと ProjectsController#new が呼ばれる。

new_project GET /projects/new(.:format) {:action=>"new", :controller=>"projects"}

新規にレコードを作るので保存用の model インスタンスを生成しておく。

def new
  @project = Project.new
end

ProjectsController#new が呼ばれた後は new.html.erb がレンダリングされる。

new.html.erb

<%= form_for @project do |f| %>
  <%= f.text_field :name %>
  <%= submit_tag 'create project' %>
<% end %>


form_for メソッドに @project を渡すと新規作成用の form を自動生成してくれる。生成された html を見てみる。

<form accept-charset="UTF-8" action="/projects" 
  class="new_project" id="new_project" method="post">

  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" type="hidden" 
      value="MZe68aF8KVayrEZGyjsZ14iaYhZDA3sfbOK998Iluh4=" />
  </div>
  <input id="project_name" name="project[name]" 
                                      size="30" type="text" />
  <input name="commit" type="submit" value="create project" /> 
</form>

submit ボタンが押されると、form の action と method に従ってリクエストが送信される。再び rake routes の結果を参照する。

POST /projects(.:format) {:action=>"create", :controller=>"projects"}

method="post" で action="/projects" なので、 ProjectsController#create が呼ばれる事が分かる。

ProjectsController#create

def create
  @project = Project.new(params[:project])
  @project.save
  redirect_to projects_path , :notice => 'create new project.'
end

params[:projects] で form から送信されたパラメータを拾って Project model のインスタンスを生成することができるので保存(save)する。



ルールに従った url と method (GET , POST , PUT , DELETE) を起点に考えるといろいろとスッキリする。自分で任意の url を作ってコントローラのメソッドを呼びだそうとか、hidden にパラメータを埋めこんで処理を切り替えようとかしなくていい。
ルールに沿って REST をキメるときもちイイと感じる。