RestClient只用最后一个哈希去除哈希参数数组?

Aut*_*act 11 rubygems ruby-on-rails rest-client ruby-on-rails-3

我有一个条件,我需要传递一个参数作为哈希数组,如下所示:

以下是API调用的Rack :: Test post方法.

post "#{url}.json",
:api_key => application.key,
:data => [{"Company"=>"Apple,Inc","Website"=>"Apple.com"},{"Company"=>"Google","Website"=>"google.com"}],
:run => { :title => "The First Run" }
Run Code Online (Sandbox Code Playgroud)

这是rails应用程序的日志.

Parameters: {"api_key"=>"6a9acb84d0ea625be75e70a1e04d26360606ca5b", "data"=>[{"Company"=>"Apple,Inc", "Website"=>"Apple.com"}, {"Company"=>"Google", "Website"=>"google.com"}], "run"=>{"title"=>"The First Run"}, "line_id"=>"4e018e2c55112729bd00000a"}
Run Code Online (Sandbox Code Playgroud)

现在,这是我用来调用API的RestClient post方法.

RestClient.post("/lines/#{@line.id}/runs.json", {:run => {:title => @title}, @param_for_input => @param_data})
Run Code Online (Sandbox Code Playgroud)

这是rails应用程序的日志.

Parameters: {"run"=>{"title"=>"run name"}, "data"=>{"Company"=>"Google", "Website"=>"google.com"}, "api_key"=>"f488a62d0307e79ec4f1e6131fa220be47e83d44", "line_id"=>"4e018a505511271f82000144"}
Run Code Online (Sandbox Code Playgroud)

不同之处在于data参数.

使用Rack :: Test方法发送时,数据将作为 "data"=>[{"Company"=>"Apple,Inc", "Website"=>"Apple.com"}, {"Company"=>"Google", "Website"=>"google.com"}]

但是通过RestClient方式,参数数据数组被剥离出来,只传递最后一个哈希值 "data"=>{"Company"=>"Google", "Website"=>"google.com"}

为什么RestClient将哈希数组剥离到数组的最后一个哈希?

Phi*_*een 19

我遇到了与rails应用程序相同的问题.我找到了以下解决方法来使用RestClient + Rails后端.

Rails期待数据[] [公司].使用'data []'代替'data'作为关键字.例如:

RestClient.post 'http://archive.greenviewdata.com/containers', { 
  :run => {:title => 'something'}, 
  'data[]' => [
    {"Company"=>"Apple,Inc","Website"=>"Apple.com"},
    {"Company"=>"Google","Website"=>"google.com"}
  ]
}
Run Code Online (Sandbox Code Playgroud)

在我们的例子中,我们在哈希中有一个嵌套两层深度的数组.由于RestClient格式化参数的方式,上述解决方法无法解决问题.因此,如果您的数组嵌套的深度超过传递给RestClient的散列的最高级别,则必须使用以下解决方法:

RestClient.post 'http://archive.greenviewdata.com/containers', {
  :run => {:title => 'something'}, 
  :nested => {
    'data' => {
      '' => [
        {"Company"=>"Apple,Inc","Website"=>"Apple.com"},
        {"Company"=>"Google","Website"=>"google.com"}
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Max*_*ams 14

我怀疑这与他们如何将哈希转换为参数的差异有关.Rack :: Test可能会使用Hash#to_param,它会产生以下结果:

> params = {:api_key => "12345", :data => [{"Company"=>"Apple,Inc","Website"=>"Apple.com"},{"Company"=>"Google","Website"=>"google.com"}], :run => { :title => "The First Run" }}

> paramstring = params.to_param
 => "api_key=12345&data%5B%5D%5BCompany%5D=Apple%2CInc&data%5B%5D%5BWebsite%5D=Apple.com&data%5B%5D%5BCompany%5D=Google&data%5B%5D%5BWebsite%5D=google.com&run%5Btitle%5D=The+First+Run" 

> URI.unescape(paramstring)
 => "api_key=12345&data[][Company]=Apple,Inc&data[][Website]=Apple.com&data[][Company]=Google&data[][Website]=google.com&run[title]=The+First+Run" 
Run Code Online (Sandbox Code Playgroud)

这是一个麻烦的部分:

数据[] [公司] =苹果公司与数据[] [公司网址] = Apple.com和数据[] [公司] =谷歌和数据[] [公司网址] = google.com

rails uri解析器必须读取它并将其转回哈希.在我看来,将一系列哈希值放入你的参数中是因为它创建了一个字符串,就像上面一样,从根本上难以解析.例如,提出这两个参数

data[][Company]=Apple,Inc
data[][Company]=Google
Run Code Online (Sandbox Code Playgroud)

解析器可以决定它们都在数组的第一个散列中描述公司变量,称为"data",因此用第二个覆盖第一个,这就是你正在发生的事情.

听起来你的问题是在生成阶段而不是解释阶段,但是,我仍然会尝试为你的参数创建一个更简洁的方案,其中数组只被用作参数名称的最后一部分(即使用一个哈希而不是一个数组来保存公司数据)而是插入一些唯一的键来区分公司的哈希值.像这样的东西:

{:api_key => "12345", 
 :data => {1 => {"Company"=>"Apple,Inc","Website"=>"Apple.com"}, 2 => {"Company"=>"Google","Website"=>"google.com"}}, 
 :run => { :title => "The First Run" }}
Run Code Online (Sandbox Code Playgroud)

1和2可能是某些公司记录的实际ID,或者它们可能只是您输入的一些数字来制作唯一的密钥,这些密钥在另一端被丢弃.这会产生这样的参数:

data[1][Company]=Apple,Inc
data[2][Company]=Google
Run Code Online (Sandbox Code Playgroud)

现在没有相互覆盖的危险.

在随后的控制器操作中,它只是改变了这样做:

params[:data].each do |company_hash|
  #do something with company hash
end
Run Code Online (Sandbox Code Playgroud)

params[:data].each do |k, company_hash|
  #do something with company hash and optionally k if you want, or ignore k
end
Run Code Online (Sandbox Code Playgroud)