Uma pergunta um pouco antiga, mas eu mesma lutei contra isso hoje, e aqui está a resposta que eu encontrei: Eu acredito que isso é um pouco a culpa do jQuery, mas ele está apenas fazendo o que é natural. Eu, no entanto, tenho uma solução alternativa.
Dada a seguinte chamada jQuery ajax:
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
data : {"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}]}
});
Os valores que o jQuery postará se parecerão com isto (se você olhar para a Solicitação em seu Firebug-of-choice) fornecerá dados de formulário semelhantes a:
shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1
Se você CGI.unencode que você obterá
shared_items[0][entity_id]:1
shared_items[0][position]:1
Acredito que isso seja porque jQuery pensa que essas chaves em seu JSON são nomes de elementos de formulário e que deve tratá-las como se você tivesse um campo chamado "usuário [nome]".
Então, eles entram em seu aplicativo Rails, Rails vê os colchetes e constrói um hash para manter a chave mais interna do nome do campo (o "1" que o jQuery "utilmente" adicionou).
De qualquer forma, contornei esse comportamento construindo minha chamada ajax da seguinte maneira;
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
data : {"data": JSON.stringify({"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}])},
}
});
O que força o jQuery a pensar que esse JSON é um valor que você deseja passar, inteiramente, e não um objeto Javascript que ele deve pegar e transformar todas as chaves em nomes de campos de formulário.
No entanto, isso significa que as coisas são um pouco diferentes no lado do Rails, porque você precisa decodificar explicitamente o JSON em params [: data].
Mas tudo bem:
ActiveSupport::JSON.decode( params[:data] )
TL; DR: Então, a solução é: no parâmetro de dados para sua chamada jQuery.ajax (), faça {"data": JSON.stringify(my_object) }
explicitamente, em vez de alimentar o array JSON no jQuery (onde ele adivinha erroneamente o que você deseja fazer com ele.