Я подозреваю, что это связано с различиями в том, как они конвертируют хэш в params. 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"
Это неприятная часть:
данные [] [Компания] = яблоко, Inc и данные [] [Сайт] = Apple.com и данные [] [Компания] = Google и данные [] [Сайт] = google.com
Парсер rails uri должен прочитать это и превратить его обратно в хеш. По моему мнению, добавление массива хэшей в ваши параметры вызывает проблемы, так как создает строку, подобную приведенной выше, которую в принципе трудно разобрать. Например, представлены эти два параметра
data[][Company]=Apple,Inc
data[][Company]=Google
Парсер может решить, что они оба описывают переменную Company в первом хэше в массиве, называемом «data», и перезаписать первое вторым, что и происходит с вами.
Похоже, ваша проблема на стадии генерации, а не на стадии интерпретации, но все же я бы попытался создать более чистую схему для ваших параметров, в которой массивы будут когда-либо использоваться только в качестве заключительной части имени параметра (т. е. используйте хеш вместо массива для хранения данных компании), и вместо этого вы вставляете несколько уникальных ключей, чтобы отличить друг от друга хеши компании. Примерно так:
{:api_key => "12345",
:data => {1 => {"Company"=>"Apple,Inc","Website"=>"Apple.com"}, 2 => {"Company"=>"Google","Website"=>"google.com"}},
:run => { :title => "The First Run" }}
1 и 2 могут быть фактическими идентификаторами записей какой-либо компании или просто цифрами, которые вы вводите для создания уникальных ключей, которые выкидываются на другом конце. Это сгенерирует такие параметры:
data[1][Company]=Apple,Inc
data[2][Company]=Google
Которые теперь не могут перезаписывать друг друга.
В вашем последующем действии контроллера это всего лишь изменение по сравнению с этим:
params[:data].each do |company_hash|
#do something with company hash
end
до
params[:data].each do |k, company_hash|
#do something with company hash and optionally k if you want, or ignore k
end