Question un peu ancienne, mais je me suis battu avec cela moi-même aujourd'hui, et voici la réponse que j'ai trouvée: je crois que c'est un peu la faute de jQuery, mais que ce n'est que ce qui lui est naturel. J'ai cependant une solution de contournement.
Compte tenu de l'appel jQuery ajax suivant:
$.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}]}
});
Les valeurs que jQuery publiera ressembleront à ceci (si vous regardez la requête dans votre Firebug-of-choice) vous donneront des données de formulaire qui ressemblent à:
shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1
Si vous CGI.unencode que vous obtiendrez
shared_items[0][entity_id]:1
shared_items[0][position]:1
Je crois que c'est parce que jQuery pense que ces clés dans votre JSON sont des noms d'élément de formulaire, et qu'il devrait les traiter comme si vous aviez un champ nommé "utilisateur [nom]".
Alors ils entrent dans votre application Rails, Rails voit les crochets et construit un hachage pour contenir la clé la plus interne du nom de champ (le "1" que jQuery a "utilement" ajouté).
Quoi qu'il en soit, j'ai contourné ce comportement en construisant mon appel ajax de la manière suivante;
$.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}])},
}
});
Ce qui oblige jQuery à penser que ce JSON est une valeur que vous souhaitez transmettre, entièrement, et non un objet Javascript qu'il doit prendre et transformer toutes les clés en noms de champs de formulaire.
Cependant, cela signifie que les choses sont un peu différentes du côté de Rails, car vous devez décoder explicitement le JSON dans les paramètres [: data].
Mais ça va:
ActiveSupport::JSON.decode( params[:data] )
TL; DR: Donc, la solution est: dans le paramètre data de votre appel jQuery.ajax (), faites-le {"data": JSON.stringify(my_object) }
explicitement, au lieu d'alimenter le tableau JSON dans jQuery (où il devine mal ce que vous voulez en faire.