We wrote HashMapper for a particular project but the use case is common enough that someone else might find it useful.
HashMapper is a "hash to hash" converter. It's a module that gives you a little DSL to map which keys in an input hash should map to which keys in the output, also a hash.
A web service of ours was getting JSON requests from a third party site in a rather messed-up structure. We wanted to avoid spoiling our controllers with parameter sanitizing code. Let's see a quick example from the Readme:
class ManyLevels
extend HashMapper
map from('/name'), to('/tag_attributes/name')
map from('/properties/type'), to('/tag_attributes/type')
map from('/tagid'), to('/tag_id')
map from('/properties/egg'), to('/chicken')
end
input = {
:name => 'ismael',
:tagid => 1,
:properties => {
:type => 'BLAH',
:egg => 33
}
}
ManyLevels.normalize(input)
# outputs:
{
:tag_id => 1,
:chicken => 33,
:tag_attributes => {
:name => 'ismael',
:type => 'BLAH'
}
}
You would then use it in your controllers to "translate" incoming parameters before feeding them to the rest of your app:
@article = Article.create( ArticleParams.normalize(params[:weird_article_data]) )
Of course that example can use a helper:
def pretty_parameters
ArticleParams.normalize(params[:weird_article_data])
end
Being a simple module, we ended up using this not only at the controller layer but also simplify parameter conversion in some pretty complex models we had in our codebase, by wrapping HashMapper's functionality in our domain objects. Overall, it helped to abstract out details of implementation and standardize the way in which we dealt with hash data.
More examples and advanced usage on the Github page. You can also take a look at the spec for even more details and edge cases.
