Closed risen closed 1 year ago
Hey, currently there's no other way to do it - you have to use method for every attribute.
I wonder if something like this could solve most of this kind of use cases:
class PersonMapper < Shale::Mapper
model Person
attribute :id, Shale::Type::Integer
attribute :name, Shale::Type::String
json do
map ['street', 'city'], using: { from: :address_from_json }
end
# hash would be { 'street' => 'foo', 'city' => 'bar' }
def address_from_json(model, hash)
model.build_address(hash)
end
end
I'll have to think about all the use cases that can be solved by this. I don't want to add something that's coupled with a single, domain specific use case.
I just released a new version that allows you to map group of elements using methods e.g.
class Person < Shale::Mapper
attribute :name, Shale::Type::String
json do
group from: :name_from_json, to: :name_to_json do
map 'first_name'
map 'last_name'
end
end
def name_from_json(model, value)
model.name = "#{value['first_name']} #{value['last_name']}"
end
def name_to_json(model, doc)
doc['first_name'] = model.name.split(' ')[0]
doc['last_name'] = model.name.split(' ')[1]
end
end
person = Person.from_json(<<~DATA)
{
"first_name": "John",
"last_name": "Doe"
}
DATA
Release notes are here: https://www.shalerb.org/releases.html#v080
I'm closing the issue, if you have more questions feel free to create a new one. Thanks.
Hi,
I'm evaluating shale for a project, and was wondering if there's an easier way to get from flattened JSON to nested models.
Example:
… something like this. I could create a method for every single attribute that's "delegated" to address, but it gets verbose and tedious.
to:
with hash" api is just an example, there's probably a better waymodel.build_address
)