When developing a new system, getting end-to-end functionality and being able to demonstrate it as soon as possible is important. While doing so, it’s also an added benefit if you do not spend a lot of time writing throwaway code.

I have a set of scripts that let me test and use the system that I am developing from the command line. Since the whole system is written in Ruby, writing a script to allow command line interaction is straightforward. The end result of what I am developing will be a service, so functionality equivalent to the scripts must be available in a browser. With Ruby, there are several ways to bring an application to a browser. The usual suspects are Rails, Merb and if they don’t work, one can always revert to using WEBrick and write servlets.

Rails and Merb did not seem right since I have an existing CouchDB backed model. I had read about Campingand wanted to test it out so I did. This was great. From the time I started investigating Camping until I could show data from my model in the browser took only 45 minutes. When I realized that I could use my own model directly rather than use the Camping model, I was just a few lines from the goal. I haven’t given much thought to whether this is a production ready framework, but that doesn’t really matter at the moment since I don’t have to write much unnecessary code. The benefit of reduced development time while retaining the full programmatic control of my model.

To show how easy it is to connect CouchDB and camping, here’s a simple example that while not particularly useful on it’s own should show a pattern that you can use in your own application.

require 'camping' require 'couchrest' Camping.goes :MyCamp

I use CouchRest to simplify CouchDB interaction. The magic is of course in the last line, Camping.goes :MyCamp . That line tells Camping to serve the module called MyCamp.

Time to implement the controller. Note that Camping expects to find the controller definitions in MyCamp::Controllers .

module MyCamp::Controllers class MyObject < R '/object/(\w+)'

This construct might confuse people, but R is defined by Camping and the parameter is a path with a regexp in the parentheses. This regexp yields the argument to get below. In this case, any HTTP GET request to server/object/number1 will call get('number1') . Perfectly RESTful.

def MyObject.set_storage(storage) @@storage = storage end

This is a way of letting the controller know the about our CouchRest model. I could have added a Model encapsulating that, but to me that is just adding another level of indirection that only serves to add confusion and complicate code maintenance since the model already exists.

def get(id) @my_object = @@storage.get(id) @my_id = id render :mymodel end end end

This is the method that is called by a HTTP GET request matching the pattern given /object/(\w+). render :mymodel result in the execution of the mymodel view.

module MyCamp::Views def mymodel body do h1 "#{@my_id}" ul do @my_object['items'].each do |field, value| li "#{field}: #{value}" end end end end end

Simple view that iterates over the ‘items’ hash and lists field: value. Note that Camping by default uses markaby to create HTML programmatically.

db_url = 'http://localhost:5984/' storage = CouchRest.database("#{@db_url}objects") MyCamp::Controllers::MyObject.set_storage(storage)

Sets up CouchRest to use the CouchDB backend at http://localhost:5984/objects

Run you application with

camping my_camp.rb

If the database contains a document with _id = 'number1' and 'items' = {"a": 1, "b": 2} , your browser will show this at http://localhost:3301/object/number1:

number1

a: 1

b: 2

There you go, a nice little Camping application backed by CouchDB.

For the official Camping site, go to http://camping.rubyforge.org/