PageRenderTime 285ms CodeModel.GetById 151ms app.highlight 12ms RepoModel.GetById 119ms app.codeStats 0ms

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