Making today worse so tomorrow seems better.

First Post

on

What do we have here?

It would seem to be yet another blog, and it is. This one, however, is built with merb and CouchDB so building it gave me a chance to experiment with some interesting projects that I don’t get to use in my daily life as a professional web developer.

The code for this site is available to the many-eyes beasts of the Interwebs here:

git://sprocket.slackworks.com/srv/git/blarg.git

It requires merb and friends, as well as an instance of CouchDB to be running somewhere. There are a few reasons I chose merb over Rails (which is what I generally use professionally) to do this:

  • It comes with no pre-packaged ORM. I wanted to use CouchDB, so none of the existing ORMs would really work for me. My previous experiences of trying to rip ActiveRecord out of Rails have been frustrating.
  • It has more flexible routing than Rails. I realize there are ways to accomplish the things I’m doing here in Rails, but the merb routes seem clearer to me, less hand-wavy. And perhaps most importantly:
  • It’s not Rails. I use Rails all day long, and I wanted to see what else is out there.

Moving along. I’m using CouchObject to communicate between Ruby and CouchDB, but I found CouchObject’s Persistable API a little unsatisfying, so I wrapped in a class I’m calling CouchBase. Classes that extend CouchBase can define couch_accessors that are populated from, and saved to, CouchDB.

class Post < CouchBase 
  couch_accessor :title, :summary, :body, :author, :tags, :created_at
  ...
end
couch_accessor is defined in CouchObject as such:
def self.couch_accessor(*fields)
  meta_def(:couchables) { fields }
end

This just takes note of which attributes should be saved in CouchDB because this can’t be inspected from a schema like with ActiveRecord. The method meta_def is part of metaid. When any of these attributes is read from or written to, it’s actually the class’s @document that is accessed.

def method_missing(meth, *attrs)
  field = meth.to_s.gsub('=', '')
  proxied_methods = self.class.couchables + [ :id, :new? ]
  if proxied_methods.include?(field.to_sym)
    @document.send(meth, *attrs) rescue nil
  else
    super
  end
end

Then, if the object is save-ed that @document is written to CouchDB. Objects pulled from the DB via CouchObject#find_by_id have their @document populated from the CouchDB record.

One caveat I noticed using CouchObject: CouchDB expects temp view POSTs to have the mime-type “text/javascript” but CouchObject sends them as “application/json” so you have to add application/json=/usr/local/bin/couchjs -f /usr/local/share/couchdb/server/main. js to the end of your /usr/local/etc/couchdb/couch.ini.

I’ll try to get comments working soon so people who want to blab may do so. In the mean time you can write to me at gnarg (at) slackworks.com and don’t forget to check out the code.