[uf-rest] RESTified Rails Controller (take 2)

Dan Kubb dan.kubb at autopilotmarketing.com
Fri Feb 3 02:36:00 PST 2006


Hi all,

I've been working with my RESTful Rails controller on a real project
since I posted about it back in mid November:

   http://microformats.org/discuss/mail/microformats-rest/2005- 
November/000042.html

I got some really good feedback from Peter Williams and I decided to
integrate some of the ideas he came up with:

   http://pezra.barelyenough.org/blog/2006/01/rough-resting-on-rails/

Here's an example controller made with my latest (soon-to-be-released)
RestController:

   class BookController < RestController
     before_filter :load_books, :only => :collection
     before_filter :load_book,  :only => :entity

     resource_for :new do
       get(:cache_as => :public, :for => 1.hour) do
         @book = Book.new
         conditions << @book  # set the ETag and Last-Modified from  
the @book's lock_version and modified_at attributes
       end
     end

     resource_for :collection do
       get(:cache_as => :public, :for => 10.minutes)

       post do
         @book = @books.build(params[:book])
         if @book.save
           render_post_success :action => 'show', :id => @book
         else
           render :action => 'new', :status => HTTP_BAD_REQUEST
         end
       end
     end

     resource_for :entity do
       get(:cache_as => :public, :for => 10.minutes)

       put do
         @book.attributes = params[:book]
         begin
           Book.transaction do
             @book.save!
             conditions << @book
             test_conditions!
           end
           render_put_success
         rescue ActiveRecord::ActiveRecordError
           render :status => HTTP_BAD_REQUEST
         end
       end

       delete do
         if meets_conditions? and @book.destroy
           render_delete_success :id => nil
         else
           render :status => HTTP_BAD_REQUEST
         end
       end
     end

     private
       def load_books
         @book_pages, @books = paginate :book, :per_page => 20
         conditions << @books
       end

       def load_book
         @book = Book.find(params[:id])
         conditions << @book
       end
   end

The way the per-HTTP method handlers are defined has been changed
slightly, but it allows extra meta-data to be passed in when the
handler is being defined.  In the example above I'm using this to
define the Cache-Control/Expires headers that are set after the
GET request is handled -- you could also do this for PUT, POST and
other methods too. (although I haven't personally hit a situation
where I wanted to do that)

If you read through Peter's blog entry and comments you'll see
there are a few extra things I wanted to experiment with before I
release the next version of the RestController.  Even so I wanted
to provide this example and see if I could get some more constructive
feedback first.

-- 

Thanks,

Dan
__________________________________________________________________

Dan Kubb                  Email: dan.kubb at autopilotmarketing.com
Autopilot Marketing Inc.  Phone: 1 (604) 820-0212
                             Web: http://www.autopilotmarketing.com
__________________________________________________________________





More information about the microformats-rest mailing list