在前面的博文中,介紹了簡單的CRUD風格的實現。html
接下來咱們在此基礎上來實現一下RESTful版本的CRUD。瀏覽器
爲何要採用RESTful風格:designing controller and action is chaosapp
HTTP methods (RFC 2616)post
POST -> Create this
GET -> Read url
PUT -> Update spa
DELETE -> Delete.net
Remove actions from URL, and we have simple named route.code
/events/create -> POST /eventsorm
/events/show/1 -> GET /events/1
/events/update/1 -> PUT /events/1
/events/destroy/1 -> DELETE /events/1
CRUD-based action names get things simpler
create -> POST
show -> GET
PUT -> update
delete -> DELETE
儘可能每個controller值負責一組CRUD
下面開始實施
自動創建一組named routes對應到actions
編輯 /config/routes.rb,加入
map.resources :events
編輯/app/views/events/index.html.erb
<ul> <%= will_paginate @events %> <% @events.each do |event| %> <li> <%= link_to event.name, event_path(event) %> <%= link_to 'edit', edit_event_path(event) %> <%= link_to 'delete', event_path(event), :method => :delete %> </li> <% end -%> <%= will_paginate @events %> </ul> <%= link_to 'new event', :controller => 'events', :action => 'new' %>
event_path的默認請求方法是 GET
對比一下原有的souce
<ul> <%= will_paginate @events %> <% @events.each do |event| %> <li> <%= link_to event.name, :controller => 'events', :action => 'show', :id => event %> <%= link_to 'edit', :controller => 'events', :action => 'edit', :id => event %> <%= link_to 'delete', :controller => 'events', :action => 'destroy', :id => event %> </li> <% end -%> <%= will_paginate @events %> </ul> <%= link_to 'new event', :controller => 'events', :action => 'new' %>
編輯/app/views/events/show.html.erb
<%=h @event.name %> <%=h @event.description %> <p> <%= link_to 'back to index', events_path %> </p>
編輯/app/views/events/new.html.erb
<%= error_messages_for :event %> <% form_for @event, :url => events_path do |f| %> <%= render :partial => 'form', :locals => { :f => f } %> <%= f.submit "Create" %> <% end %>
在Form中events_path的默認請求方法是POST
編輯/app/views/events/edit.html.erb
<%= error_messages_for :event %> <% form_for @event, :url => event_path(@event), :html => { :method => :put } do |f| %> <%= render :partial => 'form', :locals => { :f => f } %> <%= f.submit "Update" %> <% end %>
運行一下看看吧~
總結一下HTTP請求跟action的4-7關係表:
其實HTML規格只支持GET/POST,不支持PUT和DELETE方法的,rails在生成HTML的時候偷偷的作了一些處理。
咱們寫的代碼是這樣的:
<%##event_path默認是GET,刪除須要指定:method##%> <%= link_to 'delete', event_path(event), :method => :delete %>
生成的HTML是這樣的:
<a onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'TwKvS1qYjCaO2RQ3QlCdo3K57NfH0yTqKShmMk8jjI0='); f.appendChild(s);f.submit();return false;" href="/events/1">delete</a>
當點擊的時候,實際上在頁面上生成了下面內容:
<form id="edit_events_1" method="post" action="/events/1"> <input type="hidden" value="put" name="_method"/> .... </form>
其實各類瀏覽器之間還有一些關於DELETE和PUT一些支持或者不支持的不統一現象,這些問題Rails處理掉了,咱們不須要關注了。
另外,XmlHttpRequest(Ajax request)定義了GET/POST/PUT/DELETE/HEAD/OPTIONS
不過不是全部瀏覽器都支持。