Closed lenart closed 9 years ago
I'm using Virtus in a similar scenario and opted to convert the attributes (using a hash extension - https://gist.github.com/nddeluca/44e07faac0b922c94a20) to underscore before passing the attributes to Virtus. This way, my virtus models stay clean and unaware of whether the external api uses camelcase or underscore attributes.
response = ... # Some GET request
product_attributes = JSON.parse(response.body) # returns a Hash
product = Product.new(product_attributes.to_underscore)
The reverse is also possible
product = Product.new(...)
product_attributes = product.as_json
JSON.generate(product_attributes.to_camel_case)
Thanks a lot @nddeluca. Seems like a good way to tackle such problem without having Virtus to worry about this.
For data mapping I'd recommend transproc that's used as a mapping backend for ROM. It's possible it'll be used in Virtus 2.0 too.
Virtus could be used as a mapper right now but IMO it's not feasible, attribute DSL is not the best way of expressing data mapping and complex transformations even though in simple cases like the one above it may seem to make perfect sense.
In example your attributes could be transformed via transproc like that:
require 'transproc/hash'
include Transproc::Helper # gives us `t` shortcut
transform = t(:map_key, :name, t(:to_string)) >> t(:map_hash, 'createdAt' => :created_at)
transform[name: :Jane, 'createdAt' => 'foo']
# => {:name=>"Jane", :created_at=>"foo"}
Sorry for opening an issue but I cannot find this anywhere.
I'm working with an API that uses camelcased attributes (objectId, createdAt, etc.). Is it possible to map this to underscored version of attribute in my model?
The problem is that now I have to use
attribute :objectId
inside my model and access the value throughproduct.objectId
which looks weird in my ruby code. I imagine something like: