RESTfull design je přístup k programování webů který popisuje jakým způsobem se k jednotlivým objektům přistupuje. V podstatě logicky mapuje práci s jednotlivými objekty na url.
Pro přechod k REST budeme tedy měnit nejen řadič, ale také routy jenž k tomuto řadiči povedou.
Tabulka 47.5. RESTFull
| standardní metody | sloveso | url | akce |
|---|---|---|---|
plural_path | GET | /notes | index |
singular_path(id) | GET | /notes/1 | show |
new_singular_path | GET | /notes/new | new |
singular_path | POST | /notes | create |
edit_singular_path(id) | GET | /notes/1;edit | edit |
singular_path(id) | PUT | /notes/1 | update |
singular_path(id) | DELETE | /notes/1 | destroy |
# GET /notes
# GET /notes.xml
# ...
def index
@notes = Note.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @notes.to_xml }
format.rss { render :xml => @notes.to_rss }
end
endPříklad 47.24. Controller Template
class MyController < ApplicationController
# GET /notes
# GET /notes.xml
def index
@notes = Note.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @notes.to_xml }
end
end
# GET /notes/1
# GET /notes/1.xml
def show
@note = Note.find(params[:id])
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @notes.to_xml }
end
end
# GET /notes/new
def new
@mode = 'new'
@note = Note.new
end
def create
@note = Note.create(params_hash)
respond_to do |wants|
wants.html {redirect_to :action=>:index}
wants.js {render}
end
end
def edit
@note = Note.find(params[:id])
end
def update
object = @note, …
if Note.update_attributes(params_hash)
respond_to do |wants|
wants.html {redirect_to :action=>:index}
wants.js {render}
end
else
render
end
end
def destroy
…
end
endRoutes
ActionController::Routing::Routes.draw do |map|
map.resources :notes, :sessions
endV pohledu index.html.erb
<h1>Přehled poznámek</h1>
<table>
<tr></tr>
<% for note in @notes %>
<tr>
<td></td>
<td><%= link_to 'Show', note_path(note) %></td>
<td><%= link_to 'Edit', edit_note_path(note) %></td>
<td><%= link_to 'Destroy', note_path(note),
:confirm => 'Are you sure?',
:method => :delete %></td>
</tr>
<% end %>
</table>
<br/>
<%= link_to 'Nová poznámka'm new_note_path %>Místo odkazů link_to můžeme používat tlačítka button_to. Je třeba vědět, že tlačítka tako vytvářená sebou "nesou" celý formulář. Pokud chceme použít AJAX, budou uvedené řádky vypadat
<td><%= link_to_remote 'Destroy',
:url => note_path(note),
:confirm => 'Are you sure?',
:method => :delete %></td>
Řadič k mazání záznamů (metoda destroy)
# DELETE /notes/1
# DELETE /notes/1.xml
def destroy
@note = Note.find(params[:id])
@note.destroy
respond_to do |format|
format.html { redirect_to notes_url } # go to index
format.js # run the destroy.rjs template
format.xml { render :nothing = > true }
end
endSmazání poznámky z konzole
$ curl -X DELETE -H "Accept: text/xml" http://localhost:3000/notes/2$ curl -X DELETE -H "Accept: application/javascript" http://localhost:3000/notes/2Ošetření chyb. Tedy pokoušíme se smazat něco co již neexistuje
# DELETE /notes/1
# DELETE /notes/1.xml
def destroy
@note = Note.find(params[:id])
@note.destroy
respond_to do |format|
format.html { redirect_to notes_url } # go to index
format.js # run the destroy.rjs template
format.xml { render :nothing = > true }
end
rescue Exception => e
respond_to do |format|
format.html { render :text => "Record not found", status => 404 }
format.js { render(:update) {|page| page.alert("There was an error")}}
format.xml { render :nothing = > true, :status => 404 }
end
endK editaci potřebujeme pohled edit.html.erb
<h1>Editace poznámky</h1>
<% form_for(:note,
:url => note_path(@note),
:html => { :method => :put }) do |f| %>
<label for="">Title
<%= f.text_field :title, :class => 'text_field' %>
</label>
<label for="">Content
<%= f.text_area :content %>
</label>
# nebo výš uvedená pole formuláře umístníme do samsotatného souboru _form.hmtl.erb
# a zde jen uvedeme partial
<%= render :partial => 'form', :locals => {:f => f} %>
<p><%= submit_tag "Update" %></p>
<% end %>
<% link_to 'Show', note_path(@note) %> |
<% link_to 'Back', notes_path %>Pohled pro vytváření novoho záznamu:
<h1>Nová poznámka</h1>
<% form_for(:note, :url => notes_path) do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<p><%= submit_tag "Create" %></p>
<% end %>
<% link_to 'Back', notes_path %>$ script/plugin install http://dev.rubyonrails.org/svn/rails/plugins/simply_helpful/
Formáty použité v respond_to do |format| můžeme rozšířit o vlastní formát. V souboru environment.rb zaragistrujeme mime typ.
Mime::Type.register 'application/vnd.blinksale+xml', :api Mime::Type.register 'application/vnd.visa+xml, :visa
Máme-li model s relací one_to_many, potřebujeme naprogramovat aplikaci tak, aby v rámci RESTFull principu "rozuměla" url jako:
/notes/1/keywords/6
Příklad 47.25. routes.rb pro vnořenou tabulku /notes/:note_id/keywords/:id
ActionController::Routing::Routes.draw do |map|
…
# /notes/:note_id/keywords/:id
map.resources :notes do |notes|
notes.resources :keywords, :name_prefix => 'note_'
end
map.resources :keywords 