SuperModel – to sexy up your Ruby models

A few months ago, my friend Chu Yeow and I released a Ruby gem called ActiveCouch which was designed to be a very elegant Ruby wrapper for the exciting new phenomenon – CouchDB. ActiveCouch was my first shot at a Ruby library and I had a lot of fun creating elegant DSL’s (a lot of which were inspired from ActiveRecord and ActiveResource). In essence, ActiveCouch lets you define models like so:

class Pet < ActiveCouch::Base

  has :name, :which_is => :text, :with_default_value => 'Tom'


class Person < ActiveCouch::Base

  has :name, :which_is => :text, :with_default_value => 'McLovin'

  has :age, :which_is => :number, :with_default_value => 0

  has_many :dogs, :class => Pet

  has_many :cats, :class => Pet

  has_many :pets # Automagically assumes that 'pets' corresponds to the class Pet


While this is great, I found myself using these semantics more often in other Ruby libraries that I started to work on. Thus was born – SuperModel.

SuperModel’s aim is to wrap semantics such as has, has_one, has_many (which are familiar to many Ruby/Rails developers) in a re-usable library which can form the basis for other such libraries. For instance, I am currently in the process of re-writing ActiveCouch so that ActiveCouch::Base inherits from SuperModel::Base. By doing so, all the ‘modeling’ semantics will be taken care of by SuperModel and ActiveCouch can deal with interfacing with CouchDB.

SuperModel also gives you serialization for free (currently only JSON, but future releases will also include XML, YAML, etc.) So, methods such as to_json, to_xml and to_yaml will let you serialize/de-serialize SuperModel objects in/from any format that you want.

class Person < SuperModel::Base
  # If you don't specify a 'type', it defaults to string
  # while converting to JSON
  has :name

# Create a SuperModel object
p = => 'McLovin')

# Another way you can create a SuperModel object
p1 = do |person| = 'Seth'

# JSON serialization
p.to_json # => {"name":"McLovin"}

SuperModel is hosted at and the gem is available from GitHub as well. [Note: There are some problems currently with installing gems from GitHub, please refer to the GitHub RubyGems page for pointers]


About this entry