使用HTTParty发送数组变量

kat*_*ley 2 ruby arrays post httparty

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

response = HTTParty.post url, :body => 
    {"key"=>'XYZ123',
    "content"=>
        [{"placename"=>"placeholder",
        "placecontent"=>"sample content"}],
    etc. }
Run Code Online (Sandbox Code Playgroud)

API需要看到:

"content": [
    {
        "placename": "placeholder",
        "placecontent": "sample content"
    }
],
Run Code Online (Sandbox Code Playgroud)

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

"content": [
    {
        "placename": "placeholder"
    },
    {
        "placecontent": "sample content"
    }
],
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

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

...&content[0][placename]=placeholder&content[0][placecontent]=sample%20content...
Run Code Online (Sandbox Code Playgroud)

Uri*_*ssi 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
Run Code Online (Sandbox Code Playgroud)

Ruby Ave."

您可以使用以下内容使用您自己的转换器覆盖它HTTParty.query_string_normalizer:

覆盖查询字符串规范化的方式.有助于覆盖Array查询的默认rails规范化.

对于查询:

get '/', :query => {:selected_ids => [1,2,3]}
Run Code Online (Sandbox Code Playgroud)

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

/?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3
Run Code Online (Sandbox Code Playgroud)

我们改成它:

/?selected_ids=1&selected_ids=2&selected_ids=3
Run Code Online (Sandbox Code Playgroud)

将Proc传递给接受生成的查询的查询规范化程序.

@example修改数组查询字符串

class ServiceWrapper
  include HTTParty

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

@param [Proc] normalizer自定义查询字符串规范化程序.@yield [Hash,String]查询字符串@yieldreturn [Array]一个稍后将与'&'连接的数组

或者只是将其传递给您:

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

要获得序列化a[1]=val1&a[2]=val2而不是a[]=val1&a[]=val2您可以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
Run Code Online (Sandbox Code Playgroud)

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