Closed glaucocustodio closed 2 months ago
hey, you can achieve that using just plain Ruby, no need for special constructs:
class User < Shale::Mapper
attribute :gender, Shale::Type::String
def gender
if super == 'f'
'female'
else
'male'
end
end
end
although this behavior is confusing, the JSON doc you generate will be different then the one you're consuming (unless that's what you specifically need):
puts User.from_json('{"gender":"m"}').to_json
# => {"gender":"male"}
The proper way to solve this imo is to use custom type:
class Gender < Shale::Type::Value
def self.of_json(value, **)
value == 'm' ? 'male' : 'female'
end
def self.as_json(value, **)
value == 'male' ? 'm' : 'f'
end
end
class User < Shale::Mapper
attribute :gender, Gender
end
This works as you would expect:
user = User.from_json('{"gender":"m"}')
puts user.gender
# => male
puts user.to_json
# => {"gender":"m"}
Since I'm only parsing a json and not to converting to it back, I am gonna override the method like you showed:
class User < Shale::Mapper
attribute :gender, Shale::Type::String
def gender
if super == 'f'
'female'
else
'male'
end
end
end
Would you accept a PR describing this behaviour with its caveat on README?
having that in README would be a great addition, PR is welcome
Hey, thank you for the awesome work on Shale, it's really great.
Since
discussions
is not enabled on this repo, I am opening a issue to hear from you.Problem
Imagine we have a very long mapper:
And we would like to change the output of a single attribute (across all formats JSON, YAML, TOML, CSV and XML) so gender returns
male
instead ofm
andfemale
instead off
If I got it right, one would need to define
map
for all fields across all formats right? Eg:we could also create a custom type, eg:
Using custom type seems less worse, but it still feels way too verbose..
Proposed solution #1
Would you be happy if we could override a single method instead of defining mappings for all attributes? Eg:
Proposed solution #2
In case you are not happy with #1, what about defining a method to be called when reading a single attribute? Eg:
Please let me know if there is an easier way to accomplish the thing or if you would accept a PR implementing either of the proposed solutions.