Jedes Mal, wenn ich ein Array von JSON-Objekten mit jQuery to Rails POSTEN möchte, tritt dieses Problem auf. Wenn ich das Array stringiere, kann ich sehen, dass jQuery seine Arbeit korrekt macht:
"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"
Aber wenn ich das Array nur als Daten des AJAX-Aufrufs sende, erhalte ich:
"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}
Wenn ich nur ein einfaches Array sende, funktioniert es:
"shared_items"=>["entity_253"]
Warum ändert Rails das Array in diesen seltsamen Hash? Der einzige Grund, der mir in den Sinn kommt, ist, dass Rails den Inhalt nicht richtig verstehen kann, weil hier kein Typ vorhanden ist (gibt es eine Möglichkeit, ihn im jQuery-Aufruf festzulegen?):
Processing by SharedListsController#create as
Danke dir!
Update:
Ich sende die Daten als Array, nicht als Zeichenfolge, und das Array wird mithilfe der .push()
Funktion dynamisch erstellt . Versucht mit $.post
und $.ajax
, gleiches Ergebnis.
Content-Type
Anforderung nicht auf einapplication/json
, sondern sendete die Daten stattdessen wie ein HTML-Formular? Schwer so weit zurück zu denken. Rails funktionierteContent-Type
einwandfrei , nachdem der Wert auf den richtigen Wert eingestellt wurde und die gesendeten Daten gültiges JSON waren.contentType: 'application/json'
Eine etwas alte Frage, aber ich habe heute selbst damit gekämpft, und hier ist die Antwort, die ich gefunden habe: Ich glaube, das ist etwas jQuerys Schuld, aber es tut nur das, was für sie natürlich ist. Ich habe jedoch eine Problemumgehung.
Bei folgendem jQuery Ajax-Aufruf:
Die Werte, die jQuery veröffentlicht, sehen ungefähr so aus (wenn Sie sich die Anfrage in Ihrem Firebug Ihrer Wahl ansehen) und geben Ihnen Formulardaten, die wie folgt aussehen:
Wenn Sie CGI.unencode, den Sie erhalten
Ich glaube, das liegt daran, dass jQuery der Meinung ist, dass diese Schlüssel in Ihrem JSON Formularelementnamen sind und dass sie so behandelt werden sollten, als hätten Sie ein Feld mit dem Namen "user [name]".
Sie kommen also in Ihre Rails-App, Rails sieht die Klammern und erstellt einen Hash, der den innersten Schlüssel des Feldnamens enthält (die "1", die jQuery "hilfreich" hinzugefügt hat).
Wie auch immer, ich habe dieses Verhalten umgangen, indem ich meinen Ajax-Aufruf folgendermaßen konstruiert habe:
Dies zwingt jQuery zu der Annahme, dass dieser JSON ein Wert ist , den Sie vollständig übergeben möchten, und kein Javascript-Objekt, das alle Schlüssel in Formularfeldnamen umwandeln muss.
Dies bedeutet jedoch, dass die Dinge auf der Rails-Seite etwas anders sind, da Sie den JSON explizit in params [: data] dekodieren müssen.
Aber das ist in Ordnung:
TL; DR: Die Lösung lautet also: Führen Sie im Datenparameter Ihres jQuery.ajax () -Aufrufs
{"data": JSON.stringify(my_object) }
explizit aus, anstatt das JSON-Array in jQuery einzuspeisen (wo es falsch errät, was Sie damit tun möchten.quelle
Ich bin gerade auf dieses Problem mit Rails 4 gestoßen. Um Ihre Frage explizit zu beantworten ("Warum ändert Rails das Array in diesen seltsamen Hash?"), Siehe Abschnitt 4.1 des Rails-Handbuchs zu Action Controllern :
Das Problem ist, dass jQuery die Anforderung mit expliziten Array-Indizes formatiert und nicht mit leeren eckigen Klammern. Anstatt zu senden
shared_items[]=1&shared_items[]=2
, sendet es beispielsweiseshared_items[0]=1&shared_items[1]=2
. Rails sieht die Array-Indizes und interpretiert sie als Hash-Schlüssel und nicht als Array-Indizes. Dadurch wird die Anforderung zu einem seltsamen Ruby-Hash :{ shared_items: { '0' => '1', '1' => '2' } }
.Wenn Sie keine Kontrolle über den Client haben, können Sie dieses Problem auf der Serverseite beheben, indem Sie den Hash in ein Array konvertieren. So habe ich es gemacht:
quelle
Die folgende Methode kann hilfreich sein, wenn Sie starke Parameter verwenden
quelle
Hast du darüber nachgedacht
parsed_json = ActiveSupport::JSON.decode(your_json_string)
? Wenn Sie Inhalte in die andere Richtung senden, können Sie.to_json
die Daten serialisieren.quelle
Versuchen Sie nur, die JSON-Zeichenfolge in eine Rails-Controller-Aktion zu integrieren?
Ich bin nicht sicher, was Rails mit dem Hash macht, aber Sie könnten das Problem umgehen und mehr Glück haben, indem Sie ein Javascript / JSON-Objekt (im Gegensatz zu einer JSON-Zeichenfolge) erstellen und dieses als Datenparameter für Ihr Ajax senden Anruf.
Wenn Sie dies über Ajax senden möchten, würden Sie Folgendes tun:
Beachten Sie, dass jQuery mit dem obigen Ajax-Snippet den Datentyp intelligent errät, obwohl es normalerweise gut ist, ihn explizit anzugeben.
In beiden Fällen können Sie in Ihrer Controller-Aktion das JSON-Objekt abrufen, das Sie mit dem Parameter-Hash übergeben haben, d. H.
Zum Beispiel spuckt diese Aktion Ihr JSON-Objekt zurück auf Sie:
quelle
Verwenden Sie das Juwelack-jquery-params (Haftungsausschluss: Ich bin der Autor). Es behebt das Problem, dass Arrays mit Ganzzahlschlüsseln zu Hashes werden.
quelle