The all this is about keeping the same interface for adding new fields, in fact it is just creating nice Value Object
After quick search on internet it looks it is not good idea to inherit from Hash directly.
Hopefully we can create objects with []= operator so it behaves like Hash.
For generating proper output we need to write format() method that will convert booleans into required format.
Here You can see proper Value Object and it's usage compared to old code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CustomFields | |
def initialize | |
@hash = {} | |
end | |
def []=(key, value) | |
@hash[key] = value | |
end | |
def to_hash | |
change_booleans | |
end | |
private | |
def change_booleans | |
new_hash = {} | |
@hash.each do |k, v| | |
if v.is_a?(TrueClass) || v.is_a?(FalseClass) | |
new_hash[k] = v ? 'Yes' : 'No' | |
else | |
new_hash[k] = v | |
end | |
end | |
return new_hash | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Before | |
custom_fields = {} | |
custom_fields['Postcode'] = s.postcode | |
custom_fields['TestAlreadyBooked'] = s.test_booked ? 'Yes' : 'No' | |
custom_fields['PaidSubscriber'] = s.latest_subscription ? 'Yes' : 'No' | |
api(custom_fields) | |
# After | |
custom_fields = CustomFields.new | |
custom_fields['Postcode'] = s.postcode | |
custom_fields['TestAlreadyBooked'] = s.test_booked? | |
custom_fields['PaidSubscriber'] = s.latest_subscription? | |
api(custom_fields.to_h) |
One bad thing about ruby: looks like you can't just tell in one operation that something is boolean, you need to check if it is TrueClass or FalseClass.