使用HTTParty发送数组变量

时间:2014-02-18 14:12:19

标签: ruby arrays post httparty

我正在使用HTTParty发送POST请求。所需的变量之一是数组。这是我用来发送的代码:

response = HTTParty.post url, :body => 
    {"key"=>'XYZ123',
    "content"=>
        [{"placename"=>"placeholder",
        "placecontent"=>"sample content"}],
    etc. }

API需要看到:

"content": [
    {
        "placename": "placeholder",
        "placecontent": "sample content"
    }
],

但是,当我检查请求收到API的日志时,我看到我的代码正在生成:

"content": [
    {
        "placename": "placeholder"
    },
    {
        "placecontent": "sample content"
    }
],

如何阻止数组记录分成两部分?

感谢。

编辑: 所需的代码输出相当于:

...&content[0][placename]=placeholder&content[0][placecontent]=sample%20content...

1 个答案:

答案 0 :(得分:5)

默认情况下,HTTParty使用HashConversionsHash正文转换为参数:

  

<强>示例:

{ :name => "Bob",
  :address => {
    :street => '111 Ruby Ave.',
    :city => 'Ruby Central',
    :phones => ['111-111-1111', '222-222-2222']
  }
}.to_params
  #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111
     

Ruby Ave。“

您可以使用HTTParty.query_string_normalizer

覆盖自己的转换器
  

覆盖查询字符串规范化的方式。有助于覆盖   数组查询的默认rails规范化。

     

查询:

get '/', :query => {:selected_ids => [1,2,3]}
     

默认查询字符串规范化程序返回:

/?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3
     

让我们改变它:

/?selected_ids=1&selected_ids=2&selected_ids=3
     

将Proc传递给接受所产生的查询的查询规范化器。

     

@example修改数组查询字符串

class ServiceWrapper
  include HTTParty

  query_string_normalizer proc { |query|
    query.map do |key, value|
      value.map {|v| "#{key}=#{v}"}
    end.join('&')
  }
end
     

@param [Proc] normalizer自定义查询字符串规范化程序。 @yield [哈希,   字符串]查询字符串@yieldreturn [Array]稍后将成为的数组   加入'&amp;'

或者只是将其传递给您的选项:

response = HTTParty.post url, :body => 
    {"key"=>'XYZ123',
    "content"=>
        [{"placename"=>"placeholder",
        "placecontent"=>"sample content"}]},
    :query_string_normalizer => -> (h) { ... your own implementation here ...}

要获得a[1]=val1&a[2]=val2而不是a[]=val1&a[]=val2的序列化,您可以根据current one

创建自己的HashConversions
  class MyHashConversions

    def to_params(hash)
      params = hash.map { |k,v| normalize_param(k,v) }.join
      params.chop! # trailing &
      params
    end

    def normalize_param(key, value)
      param = ''
      stack = []

      if value.is_a?(Array)

        #### THE CHANGE IS HERE

        param << value.each_with_index.map { |element, i| normalize_param("#{key}[#{i}]", element) }.join

        ####
      elsif value.is_a?(Hash)
        stack << [key,value]
      else
        param << "#{key}=#{URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}&"
      end

      stack.each do |parent, hash|
        hash.each do |k, v|
          if v.is_a?(Hash)
            stack << ["#{parent}[#{k}]", v]
          else
            param << normalize_param("#{parent}[#{k}]", v)
          end
        end
      end

      param
    end
  end

上面的代码没有经过测试,但是如果它有效,而且足够通用,你可以考虑分支项目和github,在那里进行修复,所以它可以开箱即用:)