/lib/httparty/hash_conversions.rb

http://github.com/jnunemaker/httparty · Ruby · 69 lines · 45 code · 7 blank · 17 comment · 3 complexity · ecbc5800249d18aa51629a5b59583570 MD5 · raw file

  1. require 'erb'
  2. module HTTParty
  3. module HashConversions
  4. # @return <String> This hash as a query string
  5. #
  6. # @example
  7. # { name: "Bob",
  8. # address: {
  9. # street: '111 Ruby Ave.',
  10. # city: 'Ruby Central',
  11. # phones: ['111-111-1111', '222-222-2222']
  12. # }
  13. # }.to_params
  14. # #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
  15. def self.to_params(hash)
  16. hash.to_hash.map { |k, v| normalize_param(k, v) }.join.chop
  17. end
  18. # @param key<Object> The key for the param.
  19. # @param value<Object> The value for the param.
  20. #
  21. # @return <String> This key value pair as a param
  22. #
  23. # @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
  24. def self.normalize_param(key, value)
  25. normalized_keys = normalize_keys(key, value)
  26. normalized_keys.flatten.each_slice(2).inject('') do |string, (k, v)|
  27. string + "#{ERB::Util.url_encode(k)}=#{ERB::Util.url_encode(v.to_s)}&"
  28. end
  29. end
  30. def self.normalize_keys(key, value)
  31. stack = []
  32. normalized_keys = []
  33. if value.respond_to?(:to_ary)
  34. if value.empty?
  35. normalized_keys << ["#{key}[]", '']
  36. else
  37. normalized_keys = value.to_ary.flat_map do |element|
  38. normalize_keys("#{key}[]", element)
  39. end
  40. end
  41. elsif value.respond_to?(:to_hash)
  42. stack << [key, value.to_hash]
  43. else
  44. normalized_keys << [key.to_s, value]
  45. end
  46. stack.each do |parent, hash|
  47. hash.each do |child_key, child_value|
  48. if child_value.respond_to?(:to_hash)
  49. stack << ["#{parent}[#{child_key}]", child_value.to_hash]
  50. elsif child_value.respond_to?(:to_ary)
  51. child_value.to_ary.each do |v|
  52. normalized_keys << normalize_keys("#{parent}[#{child_key}][]", v).flatten
  53. end
  54. else
  55. normalized_keys << normalize_keys("#{parent}[#{child_key}]", child_value).flatten
  56. end
  57. end
  58. end
  59. normalized_keys
  60. end
  61. end
  62. end