{{{
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!
}}}
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.
LikeLike
@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!
LikeLike
Awesome Nick! I’m glad you’ve found Virtus useful for Roar 🙂
Regarding modules – we’ll figure something out!
LikeLike
Great stuff! Thanks, Nick!
LikeLike
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.)
LikeLike
@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:
Cool?
LikeLike
@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.
LikeLike