= restfully_yours A Rails plugin for adding much needed REST features, especially for remote API development. == If Modified Allows client-side caching and conditional updates using the Last-Modified and ETag headers. A conditional GET uses the If-Modified-Since/If-None-Match headers to determine whether the entity was modified since the last response, returning a new response only if there are relevant modifications. The #if_modified method compares these headers against a list of arguments. If modified, it yields to the block to render a new response, and calls #modified to set new headers. If not modified, it sends back 304 (Not Modified) response. A conditional PUT uses the If-Unmodified-Since/If-Match headers to determine whether the entity remains unmodified since the last response, to prevent updates from stale data. The #if_unmodified method compares these headers against a list of arguments. If unmodified, it yields to the block to perform the update and render a new response, and calls #modified to set new headers. If not modified, it sends back 412 (Precondition Failed) response. For example: # Render only if modified since last GET/PUT. def show() @item = Item.find(params[:id]) if_modified @item do render :action=>"item" end end # Update only if not modified since last GET/PUT. def update() @item = Item.find(params[:id]) if_unmodified @item do @item.update_from params render :action=>"item" end end == Presenters A presenter is an object that renders another object, typically a model. It handles presentation logic that you want to keep outside the model, and has access to the controller methods you can use to create URLs, format content and so forth. Where helpers complement controllers, presenters complement models. For example: class ItemPresenter < ActionController::Presenter def to_xml() to_hash.to_xml(:root=>"item") end def to_json() to_hash.to_json end def to_hash() { :url=>item_url(object), :name=>h(name), :sku=>sku } end end And from within the controller: respond_to do |format| format.html { render :action=>"item" } format.xml { render :xml=>presenting(@item).to_xml } format.js { render :json=>presenting(@item).to_json } end Calling methods not defined in the presenter will pass the call to the model or controller. You can also access the controller and object directly from the presenter. Presenters go in the app/presenters directory, so this example would reside in app/presenters/item_presenter.rb. == License Copyright (c) 2007 Assaf Arkin, http://labnotes.org In the public domain.