Representable

Maps representation documents from and to Ruby objects.

Introduction

Representable maps fragments in documents to attributes in Ruby objects and back. It allows parsing representations and gives an object-oriented interface to the document. But that’s only half of it! Representable can also render documents from an object instance.

This is especially helpful when implementing REST services and clients and keeps your representation knowledge in one place.

Example

When writing a REST service you’d have to parse and extract data from an incoming representation document manually. Given the following XML document which represents an order.

<order>
  <id>1</id>
  <item>
    <name>Chocolate Cookie</name>
  </item>
  <item>
    <name>Vanilla Muffin</name>
  </item>
</order>

Now, parsing manually starts simple but gets complex soon. In the end, you have a nested hash data structure. Try this with Representable.

class Order
  include Representable::XML

  representable_property :id
  representable_collection :items, :tag => :item, :as => Item
end

class Item
  include Representable::XML

  representable_property :name
end

Consuming Representations

Representable gives you easy access for consuming incoming representation documents. It maps the appropriate content to objects’ attributes.

@order = Order.from_xml(xml)
@order.id               # => "1"
@order.items            # => [<item>, <item>]
@order.items.first.name # => "Chocolate Cookie"

Extendability

The cool thing with object-oriented representations is: you can treat them just like any other object in Ruby and extend them dynamically - which is impossible with plain hashes.

class Order
  # ...

  def sort_items
    items.sort! { |a, b| a.name <=> b.name }
  end

Generating Representations

Usually you have two places that share knowledge about a representation and its syntax and semantics: the parser and the renderer. With Representable, this is kept in one place.

@order.to_xml # => "<order><id>1</id>...</order>"

You can also render a representation from a newly created object.

Order.new(:id => 2, :items => [candy]).to_xml

Representable makes working with representations extremely easy and testable.

More

Representable was written with REST representations in mind. However, it is a generic module for working with documents. If you do consider using it for a REST project, check out the Roar framework, which comes with representers, built-in hypermedia support and more. It internally uses Representable and streamlines the process for building hypermedia-driven REST applications.

Representable comes with parser and renderer for XML and JSON and can easily be extended (Warning: internal API still changing).

Representable is a simplified fork of the ROXML gem. Big thanks to Ben Woosley for his work.

Copyright © 2011 Nick Sutterer <[email protected]> Copyright © 2004-2009 Ben Woosley, Zak Mandhro and Anders Engstrom.