Have you ever heard of coercion? Me neither. Anyway, people kept asking for coercion support in roar so I found out that coercion means converting strings into ruby types. Tireless I added a new feature with a whopping 3 lines of code – the cool thing is that this module marries roar with a nifty coercion gem called virtus by my good friend Piotr Solnica.

All you have to do is using the latest roar release (0.10.1), use the appropriate feature and the :type option.

class ImmigrantSong
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Coercion
 
  property :composed_at, :type => DateTime, 
    :default => "May 12th, 2012"
end

This will automatically convert the composed_at property to a decent DateTime object when parsing a document. Note the working :default option, too!

document = "{\"composed_at\":\"November 18th, 1983\"}"
song = ImmigrantSong.new.from_json(document)
song.composed_at #=> 1983-11-18T00:00:00+00:00

The underlying virtus gem takes care of all the conversion work. Note that virtus also automatically adds accessors to the class.

First World Problems

A caveat is that this currently works with inline representers in classes, only. This is cause virtus doesn’t work within modules, yet. I guess we can expect a refactored virtus within days, right, solnic? As soon as this is working in virtus, you can savely use the conversion feature in modules, too. I keep you in the loop!

Oh, I forgot to thank Alex Coles who made me aware of the simplicity of combining those two gems!

Tags: ,

7 Responses to “Coercion Support in Roar with Virtus”


  1. trans

    It might be a while before Virtus can work with mixin modules –it’s a thorny problem. If module class methods mixed along with the instance methods it would be much easier, I believe. But unfortunately Ruby doesn’t support this.


  2. nick

    @trans: In roar, we had a similar problem but solved it very easily. We delay any class-specific operation until the module is included in an actual class. Maybe a similar approach could work with virtus? I will play around with it a bit and let you know!

  3. Awesome Nick! I’m glad you’ve found Virtus useful for Roar :)

    Regarding modules – we’ll figure something out!

  4. Great stuff! Thanks, Nick!


  5. Kevin Triplett

    Nick, I note you say this: “Note that virtus also automatically adds accessors to the class.”

    This is a win because I find myself having to specify accessors in my representers — unless I’m doing it wrong? (I specify unique attributes that make sense in my representer but because they do not exist on any of the models, I have to add accessors to my representers. It works but looks kinda klunky.)


  6. nick

    @Kevin: In earlier versions the representer added accessors but I decided to keep it as simple as possible. Remember, the representer is something like a parasite querying its host to represent it, not supposed to add too much functionality. You can easily override #property, thou:

    Representable::ClassMethods::Declarations.
    module_eval do
      def property(name, *args)
        attr_accessor name
        super
      end
    end

    Cool?


  7. Kevin Triplett

    @Nick — yeah, cool, thanks for that tip! I find myself dealing with combinations of models, like nested resources, and adding functionality for the view.

    For example, one of my objects has an array of images, of all different sizes, and I want to return an array of URLs to only the thumbnail-sized versions. So I create an array property of these URLs.

Leave a Reply