dwolla-v2-ruby icon indicating copy to clipboard operation
dwolla-v2-ruby copied to clipboard

Converting camel/kebab case to snake case and vice versa

Open javierjulio opened this issue 8 years ago • 0 comments

I've been working with the library since beginning of last week to learn how to implement our system at work with Dwolla to cover all our cases. Everything has gone great but one of the issues we have is the inconsistency in casing which would leads us to write code that utilizes the Dwolla library with mixed case, both camel (response properties) and kebab (for _links values). As is standard for Ruby projects we write code in snake case. Would the team be interested in accepting changes so requests can be provided in snake case and converted to camel case and responses the other way around? I've dealt with this before successfully with another service. Has this topic ever come up internally? Would their be any desire to have specific response objects?

I spent time on this today and came up with changes that would work with hashie, just something quick to see if it was even doable. I looked into using Dash and their property transformation extension but it requires that you define all available properties so that was a no go. The other issue is because of the mixed case and how method_missing works, I couldn't get around by just changing the SuperHash class but also had to update the Response class too. I wanted to see if I could get this to work so at least responses could use snake_case but still support the original casing too. This is what I came up with:

For the Response class:

def method_missing method, *args, &block
  if method != :_links && method != :_embedded
    method = method.to_s.gsub(/(?:_+)([a-z])/) { $1.upcase }.to_sym
  end
  # ...
end

For the SuperHash class:

def method_missing method
  dashed_method = method.to_s.gsub(/_/, "-").to_sym

  if key? dashed_method
    self[dashed_method]
  elsif key? method
    self[method]
  else
    super method
  end
end

With these changes I can for example do the following:

customer = app_token.get(customer_url)
customer.first_name
# => "Javier"
customer._links.self.resource_type
# => "customer"

Would you open to any enhancements to the library in some way to handle this? I'm happy to do the work. I'm wondering if you'd be willing to have a discussion around it and especially if its already come up amongst your team. Thanks.

javierjulio avatar Feb 06 '18 03:02 javierjulio