Coercion Support in Roar with Virtus

{{{
Have you ever heard of coercion? Me neither. Anyway, people kept asking for coercion support in “roar”:https://github.com/apotonick/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”:https://github.com/solnic/virtus by my good friend “Piotr Solnica”:http://solnic.eu/.

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.

h3. 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”:https://twitter.com/myabc who made me aware of the simplicity of combining those two gems!
}}}

Advertisement

7 thoughts on “Coercion Support in Roar with Virtus

  1. 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.

    Like

  2. @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!

    Like

  3. 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.)

    Like

  4. @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?

    Like

  5. @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.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s