Search code examples
ruby-on-railsjsoncamelcasing

Parse JSON in Rails app that is camelCase


I am writing back-end to one app and my front-end developer forced me to use small-cap camelCase notation in JSON files that he is receiving (sic!). With sending him this is no problem because I use Jbuilder and there is an option to provide such possibility. But how can I parse his responses in simple way? Is there any option to make it automatically instead rewriting all keys using ActiveSupport String#underscore method?

Example:
I get request with JSON:

{
  'someValue': 324,
  'someOtherValue': 'trolololololo'
}

And in Rails land I want use it as follows:

@data = JSON.parse(request.body)
@some_value = @data['some_value'] # or @data[:some_value]

Solution

  • I found some code here so I post it again for you so it is easy to copy.

    def underscore_key(k)
      if defined? Rails
        k.to_s.underscore.to_sym
      else
        to_snake_case(k.to_s).to_sym
      end
    end
    
    def to_snake_case(string)
      string.gsub(/::/, '/').
      gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
      gsub(/([a-z\d])([A-Z])/,'\1_\2').
      tr("-", "_").
      downcase
    end
    
    def convert_hash_keys(value)
      case value
        when Array
          value.map { |v| convert_hash_keys(v) }
          # or `value.map(&method(:convert_hash_keys))`
        when Hash
          Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
        else
          value
      end
    end
    

    here are some small tests to prove the functionality:

    p convert_hash_keys({abc:"x"})          # => {:abc=>"x"}
    p convert_hash_keys({abcDef:"x"})       # => {:abc_def=>"x"}
    p convert_hash_keys({AbcDef:"x"})       # => {:abc_def=>"x"}
    p convert_hash_keys(["abc"])            # => ["abc"]
    p convert_hash_keys([abc:"x"])          # => [{:abc=>"x"}]
    p convert_hash_keys([abcDef:"x"])       # => [{:abc_def=>"x"}]
    

    I hope that meets your requirements.