Chaque fois que je veux POSTER un tableau d'objets JSON avec jQuery to Rails, j'ai ce problème. Si je stringify le tableau, je peux voir que jQuery fait son travail correctement:
"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"
Mais si j'envoie simplement le tableau en tant que données de l'appel AJAX, je reçois:
"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}
Alors que si j'envoie juste un tableau simple, cela fonctionne:
"shared_items"=>["entity_253"]
Pourquoi Rails change-t-il le tableau en ce hachage étrange? La seule raison qui me vient à l'esprit est que Rails ne peut pas comprendre correctement le contenu car il n'y a pas de type ici (existe-t-il un moyen de le définir dans l'appel jQuery?):
Processing by SharedListsController#create as
Je vous remercie!
Mise à jour:
j'envoie les données sous forme de tableau, pas de chaîne et le tableau est créé dynamiquement à l'aide de la .push()
fonction. Essayé avec $.post
et $.ajax
, même résultat.
Content-Type
la requête surapplication/json
, mais envoyait plutôt les données comme le ferait un formulaire html? Difficile de repenser aussi loin. Rails fonctionnait très bien, après avoirContent-Type
défini la valeur correcte, et les données envoyées étaient du JSON valide.contentType: 'application/json'
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:
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 à:
Si vous CGI.unencode que vous obtiendrez
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;
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:
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.la source
Je viens de rencontrer ce problème avec Rails 4. Pour répondre explicitement à votre question ("Pourquoi Rails change-t-il le tableau en ce hachage étrange?"), Voir la section 4.1 du guide Rails sur les contrôleurs d'action :
Le problème est que jQuery formate la requête avec des index de tableau explicites, plutôt qu'avec des crochets vides. Ainsi, par exemple, au lieu d'envoyer
shared_items[]=1&shared_items[]=2
, il envoieshared_items[0]=1&shared_items[1]=2
. Rails voit les indices de tableau et les interprète comme clés de hachage plutôt que les indices de tableau, transformant la demande dans un étrange hachage Ruby:{ shared_items: { '0' => '1', '1' => '2' } }
.Si vous n'avez pas le contrôle du client, vous pouvez résoudre ce problème côté serveur en convertissant le hachage en tableau. Voici comment je l'ai fait:
la source
La méthode suivante peut être utile si vous utilisez des paramètres forts
la source
Avez-vous envisagé de le faire
parsed_json = ActiveSupport::JSON.decode(your_json_string)
? Si vous envoyez des éléments dans l'autre sens, vous pouvez les utiliser.to_json
pour sérialiser les données.la source
Essayez-vous simplement d'obtenir la chaîne JSON dans une action de contrôleur Rails?
Je ne suis pas sûr de ce que fait Rails avec le hachage, mais vous pourriez contourner le problème et avoir plus de chance en créant un objet Javascript / JSON (par opposition à une chaîne JSON) et en l'envoyant comme paramètre de données pour votre Ajax appel.
Si vous vouliez envoyer ceci via ajax, vous feriez quelque chose comme ceci:
Notez qu'avec l'extrait ajax ci-dessus, jQuery fera une estimation intelligente du type de données, bien qu'il soit généralement bon de le spécifier explicitement.
Quoi qu'il en soit, dans votre action de contrôleur, vous pouvez obtenir l'objet JSON que vous avez passé avec le hachage de paramètres, c'est-à-dire
Par exemple, cette action vous crachera votre objet json:
la source
Utilisez le gem rack-jquery-params (avertissement: je suis l'auteur). Il résout le problème des tableaux qui deviennent des hachages avec des clés entières.
la source